21#include <casadi/casadi.hpp>
34 for (
double val : init) {
155 return "Stormer-Verlet";
159 throw InvalidArgument(
"solve_second_order_ivp: unsupported second-order method");
165 return "Rosenbrock-Euler";
169 throw InvalidArgument(
"solve_ivp_mass_matrix: unsupported mass-matrix method");
179 const std::string &context) {
186 const std::string &context) {
197 throw IntegrationError(context +
": finite_difference_epsilon must be positive");
200 throw IntegrationError(context +
": max_newton_iterations must be positive");
208 if (q0.size() == 0) {
211 if (q0.size() != v0.size()) {
212 throw IntegrationError(
"solve_second_order_ivp: q0 and v0 must have the same size");
219 if (expr.is_zero()) {
224 casadi::Function probe(
"integrate_zero_probe", std::vector<casadi::MX>{},
225 std::vector<casadi::MX>{expr});
226 std::vector<casadi::DM> res = probe(std::vector<casadi::DM>{});
227 return std::abs(
static_cast<double>(res.at(0))) <= 1e-14;
233template <
typename VectorFunc>
240 for (Eigen::Index j = 0; j < x.size(); ++j) {
241 const double xj = x(j);
242 const double step = epsilon * std::max(1.0, std::abs(xj));
243 x_perturbed(j) = xj + step;
245 x_perturbed(j) = xj - step;
248 J.col(j) = ((f_plus - f_minus) / (2.0 * step)).
eval();
254template <
typename MassFunc>
256 const std::string &context) {
258 if (M.rows() != y.size() || M.cols() != y.size()) {
259 throw IntegrationError(context +
": mass matrix must be square with size matching y");
264template <
typename RhsFunc,
typename MassFunc>
268 if (f.size() != y.size()) {
269 throw IntegrationError(
"solve_ivp_mass_matrix: rhs dimension must match y");
273 auto rhs_at_t = [&](
const NumericVector &state) {
return rhs(t, state); };
277 return (y + dt * k).eval();
280template <
typename RhsFunc,
typename MassFunc>
283 const double t_next = t + dt;
287 if (f.size() != y.size()) {
288 throw IntegrationError(
"solve_ivp_mass_matrix: rhs dimension must match y");
291 return (M * ((trial - y) / dt) - f).eval();
318 throw IntegrationError(
"solve_ivp_mass_matrix: BDF1 Newton solve failed to converge; residual "
353template <
typename Func,
typename T>
356 if constexpr (std::is_floating_point_v<T>) {
360 T center = (a + b) / 2.0;
361 T halfwidth = (b - a) / 2.0;
366 for (
int i = 0; i < 15; ++i) {
367 T x = center + halfwidth * embedded.nodes[
static_cast<std::size_t
>(i)];
369 kronrod_sum += embedded.primary_weights[
static_cast<std::size_t
>(i)] * fx;
370 gauss_sum += embedded.embedded_weights[
static_cast<std::size_t
>(i)] * fx;
373 kronrod_sum *= halfwidth;
374 gauss_sum *= halfwidth;
377 result.
value = kronrod_sum;
378 result.
error = std::abs(kronrod_sum - gauss_sum);
383 throw IntegrationError(
"quad with callable is not supported for symbolic types. "
384 "Use quad(expr, variable, a, b) instead.");
400 double a,
double b,
double abstol = 1e-8,
401 double reltol = 1e-6) {
403 std::vector<casadi::MX> all_vars = casadi::MX::symvar(expr);
406 std::vector<casadi::MX> parameters;
407 for (
const auto &var : all_vars) {
408 if (!casadi::MX::is_equal(var, variable)) {
409 parameters.push_back(var);
421 casadi::MXDict dae = {{
"x", dummy_x}, {
"t", variable}, {
"p", p}, {
"ode", expr}};
423 casadi::Dict opts = {{
"abstol", abstol}, {
"reltol", reltol}};
425 casadi::Function integrator = casadi::integrator(
"quad_integrator",
"cvodes", dae, a, b, opts);
428 casadi::DMDict arg = {{
"x0", casadi::DM(0.0)}, {
"p", casadi::DM::zeros(p.size1(), p.size2())}};
431 casadi::MXDict sym_arg = {{
"x0", casadi::MX(0.0)}, {
"p", p}};
433 casadi::MXDict res = integrator(sym_arg);
436 result.
value = res.at(
"xf");
437 result.
error = abstol;
480template <
typename Func>
482 int n_eval = 100,
double abstol = 1e-8,
double reltol = 1e-6) {
483 double t0 = t_span.first;
484 double tf = t_span.second;
488 result.
y.resize(y0.size(), n_eval);
489 result.
y.col(0) = y0;
492 int n_state = y0.size();
493 double dt_base = (tf - t0) / (n_eval - 1);
496 int substeps = std::max(1,
static_cast<int>(std::ceil(1.0 / std::sqrt(reltol))));
500 for (
int i = 1; i < n_eval; ++i) {
501 double t = result.
t(i - 1);
502 double dt = dt_base / substeps;
504 for (
int s = 0; s < substeps; ++s) {
514 result.
message =
"Integration successful (RK4)";
531template <
typename Func>
533 std::initializer_list<double> y0_init,
int n_eval = 100,
534 double abstol = 1e-8,
double reltol = 1e-6) {
556template <
typename AccelFunc>
557SecondOrderOdeResult<double>
565 const double t0 = t_span.first;
566 const double tf = t_span.second;
568 SecondOrderOdeResult<double> result;
569 result.t =
linspace(t0, tf, n_eval);
570 result.q.resize(q0.size(), n_eval);
571 result.v.resize(v0.size(), n_eval);
572 result.q.col(0) = q0;
573 result.v.col(0) = v0;
577 const double dt_base = (tf - t0) /
static_cast<double>(n_eval - 1);
579 for (
int i = 1; i < n_eval; ++i) {
580 double t = result.t(i - 1);
581 const double dt = dt_base /
static_cast<double>(opts.substeps);
583 for (
int s = 0; s < opts.substeps; ++s) {
584 SecondOrderStepResult<double> step;
588 step =
rkn4_step(acceleration, q, v, t, dt);
599 result.success =
true;
609template <
typename AccelFunc>
612 std::initializer_list<double> q0_init, std::initializer_list<double> v0_init,
637template <
typename RhsFunc,
typename MassFunc>
644 const double t0 = t_span.first;
645 const double tf = t_span.second;
647 throw IntegrationError(
"solve_ivp_mass_matrix: t_span endpoints must differ");
649 if (y0.size() == 0) {
655 result.y.resize(y0.size(), n_eval);
656 result.y.col(0) = y0;
659 const double dt_base = (tf - t0) /
static_cast<double>(n_eval - 1);
661 for (
int i = 1; i < n_eval; ++i) {
662 double t = result.t(i - 1);
663 const double dt = dt_base /
static_cast<double>(opts.substeps);
665 for (
int s = 0; s < opts.substeps; ++s) {
677 result.success =
true;
687template <
typename RhsFunc,
typename MassFunc>
689 std::pair<double, double> t_span,
690 std::initializer_list<double> y0_init,
int n_eval = 100,
725 const double t0 = t_span.first;
726 const double tf = t_span.second;
728 throw IntegrationError(
"solve_ivp_mass_matrix_expr: t_span endpoints must differ");
730 const int n_state =
static_cast<int>(y0.size());
737 SymbolicScalar::substitute(rhs_expr, t_var, t0 + (tf - t0) * t_normalized);
739 SymbolicScalar::substitute(mass_expr, t_var, t0 + (tf - t0) * t_normalized);
741 if (mass_sub.size1() != n_state || mass_sub.size2() != n_state) {
743 "solve_ivp_mass_matrix_expr: mass matrix must be square with size matching y0");
745 if (rhs_sub.size1() != n_state || rhs_sub.size2() != 1) {
746 throw IntegrationError(
"solve_ivp_mass_matrix_expr: rhs must be a column vector matching "
750 casadi::DM y0_dm_full(n_state, 1);
751 for (
int i = 0; i < n_state; ++i) {
752 y0_dm_full(i) = y0(i);
755 std::vector<double> t_eval_normalized(n_eval);
756 for (
int i = 0; i < n_eval; ++i) {
757 t_eval_normalized[i] =
static_cast<double>(i) /
static_cast<double>(n_eval - 1);
760 std::vector<bool> row_has_structural_nnz(
static_cast<std::size_t
>(n_state),
false);
761 for (
int row = 0; row < n_state; ++row) {
762 for (
int col = 0; col < n_state; ++col) {
764 row_has_structural_nnz[
static_cast<std::size_t
>(row)] =
true;
770 std::vector<int> differential_indices;
771 std::vector<int> algebraic_indices;
772 for (
int i = 0; i < n_state; ++i) {
773 if (row_has_structural_nnz[
static_cast<std::size_t
>(i)]) {
774 differential_indices.push_back(i);
776 algebraic_indices.push_back(i);
780 auto is_component_of = [](
const casadi::MX &var,
const casadi::MX &vector_expr) {
781 for (
int i = 0; i < vector_expr.nnz(); ++i) {
782 if (casadi::MX::is_equal(var, vector_expr(i))) {
789 casadi::Dict integrator_opts = {
790 {
"abstol", opts.abstol}, {
"reltol", opts.reltol}, {
"calc_ic",
true}};
791 for (
const auto &kv : opts.symbolic_integrator_options) {
792 integrator_opts[kv.first] = kv.second;
796 result.
t.resize(n_eval);
797 for (
int i = 0; i < n_eval; ++i) {
798 result.t(i) = t0 + (tf - t0) * t_eval_normalized[i];
800 result.y.resize(n_state, n_eval);
802 if (algebraic_indices.empty()) {
803 SymbolicScalar z_var = SymbolicScalar::sym(
"y_dot_norm", n_state, 1);
804 SymbolicScalar alg = casadi::MX::mtimes(mass_sub, z_var) - (tf - t0) * rhs_sub;
806 std::vector<casadi::MX> all_vars = casadi::MX::symvar(casadi::MX::vertcat({rhs_sub, alg}));
807 std::vector<casadi::MX> parameters;
808 for (
const auto &var : all_vars) {
809 if (casadi::MX::is_equal(var, t_normalized) || casadi::MX::is_equal(var, y_var) ||
810 casadi::MX::is_equal(var, z_var) || is_component_of(var, y_var) ||
811 is_component_of(var, z_var)) {
814 parameters.push_back(var);
817 casadi::MX p = casadi::MX::vertcat(parameters);
818 casadi::MXDict dae = {{
"x", y_var}, {
"z", z_var}, {
"t", t_normalized},
819 {
"p", p}, {
"ode", z_var}, {
"alg", alg}};
821 casadi::Function integrator = casadi::integrator(
"mass_matrix_ivp_integrator",
"idas", dae,
822 0.0, t_eval_normalized, integrator_opts);
824 casadi::DMDict integrator_args;
825 integrator_args[
"x0"] = y0_dm_full;
826 integrator_args[
"z0"] = casadi::DM::zeros(n_state, 1);
827 integrator_args[
"p"] = casadi::DM::zeros(p.size1(), p.size2());
828 casadi::DMDict res_dm = integrator(integrator_args);
830 casadi::DM xf = res_dm.at(
"xf");
831 for (
int i = 0; i < n_state; ++i) {
832 for (
int j = 0; j < n_eval; ++j) {
833 result.y(i, j) =
static_cast<double>(xf(i, j));
837 if (differential_indices.empty()) {
838 throw IntegrationError(
"solve_ivp_mass_matrix_expr: fully algebraic systems are not "
842 const int n_diff =
static_cast<int>(differential_indices.size());
843 const int n_alg =
static_cast<int>(algebraic_indices.size());
851 for (
int i = 0; i < n_state; ++i) {
852 if (row_has_structural_nnz[
static_cast<std::size_t
>(i)]) {
853 partitioned_y(i) = x_var(diff_cursor++);
855 partitioned_y(i) = z_var(alg_cursor++);
859 SymbolicScalar rhs_partitioned = SymbolicScalar::substitute(rhs_sub, y_var, partitioned_y);
861 SymbolicScalar::substitute(mass_sub, y_var, partitioned_y);
865 for (
int i = 0; i < n_diff; ++i) {
866 rhs_diff(i) = rhs_partitioned(differential_indices[
static_cast<std::size_t
>(i)]);
868 for (
int i = 0; i < n_alg; ++i) {
869 rhs_alg(i) = rhs_partitioned(algebraic_indices[
static_cast<std::size_t
>(i)]);
873 for (
int i = 0; i < n_diff; ++i) {
874 for (
int j = 0; j < n_diff; ++j) {
876 mass_partitioned(differential_indices[
static_cast<std::size_t
>(i)],
877 differential_indices[
static_cast<std::size_t
>(j)]);
881 SymbolicScalar ode = casadi::MX::solve(mass_diff, (tf - t0) * rhs_diff);
883 std::vector<casadi::MX> all_vars = casadi::MX::symvar(casadi::MX::vertcat(
884 {rhs_partitioned, casadi::MX::reshape(mass_partitioned, n_state * n_state, 1)}));
885 std::vector<casadi::MX> parameters;
886 for (
const auto &var : all_vars) {
887 if (casadi::MX::is_equal(var, t_normalized) || casadi::MX::is_equal(var, x_var) ||
888 casadi::MX::is_equal(var, z_var) || is_component_of(var, x_var) ||
889 is_component_of(var, z_var)) {
892 parameters.push_back(var);
895 casadi::MX p = casadi::MX::vertcat(parameters);
896 casadi::MXDict dae = {{
"x", x_var}, {
"z", z_var}, {
"t", t_normalized},
897 {
"p", p}, {
"ode", ode}, {
"alg", rhs_alg}};
899 casadi::Function integrator =
900 casadi::integrator(
"mass_matrix_ivp_integrator_partitioned",
"idas", dae, 0.0,
901 t_eval_normalized, integrator_opts);
903 casadi::DM x0_dm(n_diff, 1);
904 casadi::DM z0_dm(n_alg, 1);
905 for (
int i = 0; i < n_diff; ++i) {
906 x0_dm(i) = y0(differential_indices[
static_cast<std::size_t
>(i)]);
908 for (
int i = 0; i < n_alg; ++i) {
909 z0_dm(i) = y0(algebraic_indices[
static_cast<std::size_t
>(i)]);
912 casadi::DMDict integrator_args;
913 integrator_args[
"x0"] = x0_dm;
914 integrator_args[
"z0"] = z0_dm;
915 integrator_args[
"p"] = casadi::DM::zeros(p.size1(), p.size2());
916 casadi::DMDict res_dm = integrator(integrator_args);
918 casadi::DM xf = res_dm.at(
"xf");
919 casadi::DM zf = res_dm.at(
"zf");
920 for (
int i = 0; i < n_eval; ++i) {
923 for (
int state = 0; state < n_state; ++state) {
924 if (row_has_structural_nnz[
static_cast<std::size_t
>(state)]) {
925 result.y(state, i) =
static_cast<double>(xf(diff_out++, i));
927 result.y(state, i) =
static_cast<double>(zf(alg_out++, i));
933 result.success =
true;
934 result.message =
"Integration successful (IDAS mass matrix)";
954template <
typename Func>
956 const Eigen::VectorXd &y0,
int n_eval = 100,
957 double abstol = 1e-8,
double reltol = 1e-6) {
958 double t0 = t_span.first;
959 double tf = t_span.second;
960 int n_state = y0.size();
968 if constexpr (std::is_invocable_v<Func, casadi::MX, casadi::MX>) {
969 ode_expr = fun(t_var, y_var);
973 for (
int i = 0; i < n_state; ++i) {
976 auto result = fun(t_var, y_sym);
978 ode_expr = casadi::MX(n_state, 1);
979 for (
int i = 0; i < n_state; ++i) {
980 ode_expr(i) = result(i);
987 casadi::MX t_normalized = casadi::MX::sym(
"t_norm");
988 casadi::MX ode_normalized =
989 casadi::MX::substitute(ode_expr, t_var, t0 + (tf - t0) * t_normalized) * (tf - t0);
992 std::vector<double> t_eval_normalized(n_eval);
993 for (
int i = 0; i < n_eval; ++i) {
994 t_eval_normalized[i] =
static_cast<double>(i) / (n_eval - 1);
998 casadi::MXDict dae = {{
"x", y_var}, {
"t", t_normalized}, {
"ode", ode_normalized}};
1000 casadi::Dict opts = {{
"abstol", abstol}, {
"reltol", reltol}};
1002 casadi::Function integrator =
1003 casadi::integrator(
"ivp_integrator",
"cvodes", dae, 0.0, t_eval_normalized, opts);
1006 casadi::DM y0_dm(n_state, 1);
1007 for (
int i = 0; i < n_state; ++i) {
1012 casadi::DMDict integrator_args;
1013 integrator_args[
"x0"] = y0_dm;
1014 casadi::DMDict res_dm = integrator(integrator_args);
1019 result.
t.resize(n_eval);
1020 for (
int i = 0; i < n_eval; ++i) {
1021 result.
t(i) = t0 + (tf - t0) * t_eval_normalized[i];
1025 casadi::DM xf = res_dm.at(
"xf");
1026 result.
y.resize(n_state, n_eval);
1027 for (
int i = 0; i < n_state; ++i) {
1028 for (
int j = 0; j < n_eval; ++j) {
1029 result.
y(i, j) =
static_cast<double>(xf(i, j));
1034 result.
message =
"Integration successful (CVODES)";
1059 int n_eval = 100,
double abstol = 1e-8,
1060 double reltol = 1e-6) {
1061 double t0 = t_span.first;
1062 double tf = t_span.second;
1063 int n_state = y0.size();
1068 SymbolicScalar::substitute(ode_expr, t_var, t0 + (tf - t0) * t_normalized) * (tf - t0);
1071 std::vector<double> t_eval_normalized(n_eval);
1072 for (
int i = 0; i < n_eval; ++i) {
1073 t_eval_normalized[i] =
static_cast<double>(i) / (n_eval - 1);
1077 std::vector<casadi::MX> all_vars = casadi::MX::symvar(ode_normalized);
1078 std::vector<casadi::MX> parameters;
1079 for (
const auto &var : all_vars) {
1080 if (!casadi::MX::is_equal(var, t_normalized) && !casadi::MX::is_equal(var, y_var)) {
1083 for (
int i = 0; i < y_var.size1() * y_var.size2(); ++i) {
1084 if (casadi::MX::is_equal(var, y_var(i))) {
1090 parameters.push_back(var);
1095 casadi::MX p = casadi::MX::vertcat(parameters);
1098 casadi::MXDict dae = {{
"x", y_var}, {
"t", t_normalized}, {
"p", p}, {
"ode", ode_normalized}};
1100 casadi::Dict opts = {{
"abstol", abstol}, {
"reltol", reltol}};
1102 casadi::Function integrator =
1103 casadi::integrator(
"ivp_integrator",
"cvodes", dae, 0.0, t_eval_normalized, opts);
1106 casadi::DM y0_dm(n_state, 1);
1107 for (
int i = 0; i < n_state; ++i) {
1112 casadi::DM p_dm = casadi::DM::zeros(p.size1(), p.size2());
1115 casadi::DMDict integrator_args;
1116 integrator_args[
"x0"] = y0_dm;
1117 integrator_args[
"p"] = p_dm;
1118 casadi::DMDict res_dm = integrator(integrator_args);
1123 result.
t.resize(n_eval);
1124 for (
int i = 0; i < n_eval; ++i) {
1125 result.
t(i) = t0 + (tf - t0) * t_eval_normalized[i];
1129 casadi::DM xf = res_dm.at(
"xf");
1130 result.
y.resize(n_state, n_eval);
1131 for (
int i = 0; i < n_state; ++i) {
1132 for (
int j = 0; j < n_eval; ++j) {
1133 result.
y(i, j) =
static_cast<double>(xf(i, j));
1138 result.
message =
"Integration successful (CVODES)";
Scalar and element-wise arithmetic functions (abs, sqrt, pow, exp, log, etc.).
Single-step explicit ODE integrators for Janus framework.
C++20 concepts constraining valid Janus scalar types.
Custom exception hierarchy for Janus framework.
Core type aliases for numeric and symbolic Eigen/CasADi interop.
Linear algebra operations (solve, inverse, determinant, eigendecomposition, norms).
Stochastic quadrature rules (Gauss, Clenshaw-Curtis, Smolyak sparse grids).
Point distribution generators (linspace, cosine, sine, log, geometric).
Integration/ODE solver errors.
Definition JanusError.hpp:61
Input validation failed (e.g., mismatched sizes, invalid parameters).
Definition JanusError.hpp:31
Smooth approximation of ReLU function: softplus(x) = (1/beta) * log(1 + exp(beta * x)).
Definition Diagnostics.hpp:131
NumericVector bdf1_step(RhsFunc &&rhs, MassFunc &&mass_matrix, const NumericVector &y, double t, double dt, const MassMatrixIvpOptions &opts)
Definition Integrate.hpp:281
NumericMatrix finite_difference_jacobian(VectorFunc &&func, const NumericVector &x, double epsilon)
Definition Integrate.hpp:234
double inf_norm(const NumericVector &x)
Definition Integrate.hpp:216
void validate_mass_matrix_options(const MassMatrixIvpOptions &opts, const std::string &context)
Definition Integrate.hpp:185
void validate_eval_count(const std::string &context, int n_eval)
Definition Integrate.hpp:172
const char * method_name(SecondOrderIntegratorMethod method)
Definition Integrate.hpp:152
bool is_constant_zero(const SymbolicScalar &expr)
Definition Integrate.hpp:218
const EmbeddedQuadratureRule & gauss_kronrod_15_rule()
Definition Quadrature.hpp:78
void validate_second_order_options(const SecondOrderIvpOptions &opts, const std::string &context)
Definition Integrate.hpp:178
NumericMatrix evaluate_mass_matrix(MassFunc &&mass_matrix, double t, const NumericVector &y, const std::string &context)
Definition Integrate.hpp:255
void validate_second_order_initial_state(const NumericVector &q0, const NumericVector &v0)
Definition Integrate.hpp:207
NumericVector to_numeric_vector(std::initializer_list< double > init)
Definition Integrate.hpp:31
NumericVector rosenbrock_euler_step(RhsFunc &&rhs, MassFunc &&mass_matrix, const NumericVector &y, double t, double dt, const MassMatrixIvpOptions &opts)
Definition Integrate.hpp:265
Definition Diagnostics.hpp:19
JanusVector< SymbolicScalar > SymbolicVector
Eigen vector of MX elements.
Definition JanusTypes.hpp:72
JanusVector< Scalar > rk4_step(Func &&f, const JanusVector< Scalar > &x, Scalar t, Scalar dt)
Classic 4th-order Runge-Kutta integration step.
Definition IntegratorStep.hpp:131
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > JanusMatrix
Dynamic-size matrix for both numeric and symbolic backends.
Definition JanusTypes.hpp:43
JanusMatrix< NumericScalar > NumericMatrix
Eigen::MatrixXd equivalent.
Definition JanusTypes.hpp:66
SecondOrderStepResult< Scalar > rkn4_step(AccelFunc &&acceleration, const JanusVector< Scalar > &q, const JanusVector< Scalar > &v, Scalar t, Scalar dt)
Classical 4th-order Runge-Kutta-Nystrom step for q'' = a(t, q).
Definition IntegratorStep.hpp:193
MassMatrixIntegratorMethod
Stepper selection for mass-matrix systems M(t, y) y' = f(t, y).
Definition Integrate.hpp:80
@ RosenbrockEuler
One-stage linearly implicit Rosenbrock-Euler.
Definition Integrate.hpp:81
@ Bdf1
Backward Euler / first-order BDF with Newton iterations.
Definition Integrate.hpp:82
JanusVector< NumericScalar > NumericVector
Eigen::VectorXd equivalent.
Definition JanusTypes.hpp:67
QuadResult< T > quad(Func &&func, T a, T b, double abstol=1e-8, double reltol=1e-6)
Compute definite integral using adaptive quadrature (numeric) or CVODES (symbolic).
Definition Integrate.hpp:354
OdeResult< SymbolicScalar > solve_ivp_symbolic(Func &&fun, std::pair< double, double > t_span, const Eigen::VectorXd &y0, int n_eval=100, double abstol=1e-8, double reltol=1e-6)
Solve IVP with symbolic ODE function (CasADi CVODES backend).
Definition Integrate.hpp:955
OdeResult< double > solve_ivp_mass_matrix(RhsFunc &&rhs, MassFunc &&mass_matrix, std::pair< double, double > t_span, const NumericVector &y0, int n_eval=100, const MassMatrixIvpOptions &opts={})
Solve M(t, y) y' = f(t, y) with a native numeric stiff integrator.
Definition Integrate.hpp:638
OdeResult< double > solve_ivp(Func &&fun, std::pair< double, double > t_span, const NumericVector &y0, int n_eval=100, double abstol=1e-8, double reltol=1e-6)
Solve initial value problem: dy/dt = f(t, y), y(t0) = y0.
Definition Integrate.hpp:481
OdeResult< double > solve_ivp_mass_matrix_expr(const SymbolicScalar &rhs_expr, const SymbolicScalar &mass_expr, const SymbolicScalar &t_var, const SymbolicScalar &y_var, std::pair< double, double > t_span, const NumericVector &y0, int n_eval=100, const MassMatrixIvpOptions &opts={})
Solve a symbolic mass-matrix IVP using CasADi IDAS.
Definition Integrate.hpp:718
auto eval(const Eigen::MatrixBase< Derived > &mat)
Evaluate a symbolic matrix to a numeric Eigen matrix.
Definition JanusIO.hpp:62
SecondOrderIntegratorMethod
Stepper selection for second-order systems q'' = a(t, q).
Definition Integrate.hpp:72
@ StormerVerlet
Symplectic Stormer-Verlet / velocity-Verlet.
Definition Integrate.hpp:73
@ RungeKuttaNystrom4
Classical 4th-order Runge-Kutta-Nystrom.
Definition Integrate.hpp:74
OdeResult< double > solve_ivp_expr(const SymbolicScalar &ode_expr, const SymbolicScalar &t_var, const SymbolicScalar &y_var, std::pair< double, double > t_span, const NumericVector &y0, int n_eval=100, double abstol=1e-8, double reltol=1e-6)
Solve IVP with a symbolic expression directly (expression-based API).
Definition Integrate.hpp:1056
SecondOrderStepResult< Scalar > stormer_verlet_step(AccelFunc &&acceleration, const JanusVector< Scalar > &q, const JanusVector< Scalar > &v, Scalar t, Scalar dt)
Stormer-Verlet / velocity-Verlet step for q'' = a(t, q).
Definition IntegratorStep.hpp:167
SecondOrderOdeResult< double > solve_second_order_ivp(AccelFunc &&acceleration, std::pair< double, double > t_span, const NumericVector &q0, const NumericVector &v0, int n_eval=100, const SecondOrderIvpOptions &opts={})
Solve a second-order IVP q'' = a(t, q), q(t0) = q0, v(t0) = v0.
Definition Integrate.hpp:558
auto solve(const Eigen::MatrixBase< DerivedA > &A, const Eigen::MatrixBase< DerivedB > &b)
Solves linear system Ax = b using the default backend policy.
Definition Linalg.hpp:408
JanusVector< T > linspace(const T &start, const T &end, int n)
Generates linearly spaced vector.
Definition Spacing.hpp:26
Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > JanusVector
Dynamic-size column vector for both numeric and symbolic backends.
Definition JanusTypes.hpp:49
casadi::MX SymbolicScalar
CasADi MX symbolic scalar.
Definition JanusTypes.hpp:70
Configuration for linear system solve backend and algorithm.
Definition Linalg.hpp:86
Options for stiff mass-matrix integration.
Definition Integrate.hpp:121
double newton_tolerance
Definition Integrate.hpp:128
LinearSolvePolicy linear_solve_policy
Definition Integrate.hpp:129
double reltol
Definition Integrate.hpp:125
casadi::Dict symbolic_integrator_options
Definition Integrate.hpp:130
double abstol
Definition Integrate.hpp:124
int substeps
Definition Integrate.hpp:123
MassMatrixIntegratorMethod method
Definition Integrate.hpp:122
double finite_difference_epsilon
Definition Integrate.hpp:126
int max_newton_iterations
Definition Integrate.hpp:127
Result structure for ODE solvers.
Definition Integrate.hpp:52
bool success
Whether integration was successful.
Definition Integrate.hpp:60
std::string message
Descriptive message.
Definition Integrate.hpp:63
JanusVector< Scalar > t
Time points where solution was computed.
Definition Integrate.hpp:54
JanusMatrix< Scalar > y
Solution values at each time point (each column is a state at time t[i]).
Definition Integrate.hpp:57
int status
Status code (0 = success).
Definition Integrate.hpp:66
Result structure for quadrature (definite integration).
Definition Integrate.hpp:142
double error
Estimated error (only meaningful for numeric backend).
Definition Integrate.hpp:147
Scalar value
Integral value.
Definition Integrate.hpp:144
Options for second-order structure-preserving trajectory integration.
Definition Integrate.hpp:113
SecondOrderIntegratorMethod method
Definition Integrate.hpp:114
int substeps
Definition Integrate.hpp:115
Result structure for second-order IVP solvers.
Definition Integrate.hpp:90
JanusVector< Scalar > t
Time points where solution was computed.
Definition Integrate.hpp:92
int status
Status code (0 = success).
Definition Integrate.hpp:107
JanusMatrix< Scalar > v
Generalized velocities at each time point (each column is v(t[i])).
Definition Integrate.hpp:98
bool success
Whether integration was successful.
Definition Integrate.hpp:101
std::string message
Descriptive message.
Definition Integrate.hpp:104
JanusMatrix< Scalar > q
Generalized coordinates at each time point (each column is q(t[i])).
Definition Integrate.hpp:95
JanusVector< NumericScalar > NumericVector
Eigen::VectorXd equivalent.
Definition JanusTypes.hpp:67