26 #include "integrator_impl.hpp"
27 #include "casadi_misc.hpp"
33 case DYN_T:
return "t";
34 case DYN_X:
return "x";
35 case DYN_Z:
return "z";
36 case DYN_P:
return "p";
37 case DYN_U:
return "u";
136 return integrator(name, solver, dae, 0.0, std::vector<double>{1.0}, opts);
141 return integrator(name, solver, dae, 0.0, std::vector<double>{1.0}, opts);
146 return integrator(name, solver, dae, 0.0, std::vector<double>{1.0}, opts);
150 const SXDict& dae,
double t0,
const std::vector<double>& tout,
const Dict& opts) {
155 const MXDict& dae,
double t0,
const std::vector<double>& tout,
const Dict& opts) {
160 const Function& dae,
double t0,
const std::vector<double>& tout,
const Dict& opts) {
163 casadi_error(
"Cannot create '" + name +
"' since " +
str(dae.
get_free()) +
" are free.");
170 const SXDict& dae,
double t0,
double tf,
const Dict& opts) {
171 return integrator(name, solver, dae, t0, std::vector<double>{tf}, opts);
175 const MXDict& dae,
double t0,
double tf,
const Dict& opts) {
176 return integrator(name, solver, dae, t0, std::vector<double>{tf}, opts);
180 const Function& dae,
double t0,
double tf,
const Dict& opts) {
181 return integrator(name, solver, dae, t0, std::vector<double>{tf}, opts);
207 return std::string();
221 return std::string();
233 return enum_names<DynIn>();
237 return enum_names<DynOut>();
257 return enum_names<EventIn>();
261 return enum_names<EventOut>();
265 double t0,
const std::vector<double>& tout)
355 casadi_int* iw,
double* w,
void* mem)
const {
378 setup(m, arg, res, iw, w);
390 bool first_call =
true;
396 casadi_int k_stop = -1;
399 m->reset_solver =
false;
402 for (m->k = 0; m->k <
nt(); ++m->k) {
406 m->t_next_out =
tout_[m->k];
408 m->t_next = m->t_next_out;
415 m->t_stop = m->t_step =
tout_[k_stop];
417 m->reset_solver =
true;
420 std::fill_n(m->event_triggered,
ne_, 0);
424 if (m->reset_solver) {
425 reset(m, first_call);
426 m->reset_solver =
false;
431 casadi_message(
"Interval " +
str(m->k) +
": Integrating forward from "
432 +
str(m->t) +
" to " +
str(m->t_next) +
", t_stop = " +
str(m->t_stop));
436 if (m->event_index >= 0) {
438 std::fill_n(m->event_triggered,
ne_, 0);
440 while (m->event_index >= 0) {
444 m->reset_solver =
true;
448 m->t_stop = m->t_step;
449 m->t_next = m->t_next_out;
451 }
while (m->t != m->t_next);
465 if (adj_xf) adj_xf +=
nrx_ *
nt();
466 if (rz0) rz0 +=
nrz_ *
nt();
467 if (rp) rp +=
nrp_ *
nt();
468 if (adj_u) adj_u +=
nuq_ *
nt();
474 bool any_impulse =
false;
476 for (m->k =
nt(); m->k-- > 0; ) {
479 if (adj_xf) adj_xf -=
nrx_;
480 if (rz0) rz0 -=
nrz_;
482 if (adj_u) adj_u -=
nuq_;
485 if (
verbose_) casadi_message(
"Impulse from adjoint seeds at output time " +
str(m->k));
490 casadi_int k_next = m->k - 1;
491 m->t_next = k_next < 0 ?
t0_ :
tout_[k_next];
493 if (k_next < k_stop) k_stop =
next_stopB(m->k, u);
494 m->t_stop = k_stop < 0 ?
t0_ :
tout_[k_stop];
497 if (
verbose_) casadi_message(
"Integrating backward from output time " +
str(m->k)
498 +
": t_next = " +
str(m->t_next) +
", t_stop = " +
str(m->t_stop));
502 retreat(m, u, adj_x, adj_p, adj_u);
505 if (
verbose_) casadi_message(
"No adjoint seeds from output time " +
str(m->k)
506 +
": t_next = " +
str(m->t_next) +
", t_stop = " +
str(m->t_stop));
516 for (m->k = 0; m->k <
nt() - 1; ++m->k) {
556 for (casadi_int i = 0; i <
ne_; ++i) {
562 double t_zero = m->
t - m->
e[i] / m->
edot[i];
564 if (t_zero <= m->t_start || (m->
e[i] < 0 && m->
edot[i] >= 0)) {
568 if (t_zero < m->t_next) {
578 double t_diff = std::fabs(m->
t_next - m->
t);
581 if (
verbose_) casadi_message(
"Event iteration converged, |dt| == " +
str(t_diff));
588 casadi_error(
"Maximum number of event iterations reached without convergence");
590 if (
verbose_) casadi_message(
"Max event iterations, |dt| == " +
str(t_diff));
605 "Print out statistics after integration"}},
608 "Number of forward sensitivities to be calculated [0]"}},
611 "Number of adjoint sensitivities to be calculated [0]"}},
614 "[DEPRECATED] Beginning of the time horizon"}},
617 "[DEPRECATED] End of the time horizon"}},
620 "[DEPRECATED] Time grid"}},
621 {
"augmented_options",
623 "Options to be passed down to the augmented integrator, if one is constructed"}},
626 "Function to be called a zero-crossing events"}},
629 "Maximum number of iterations to zero in on a single event"}},
632 "Maximum total number of events"}},
635 "Termination tolerance for the event iteration"}},
638 "[DEPRECATED] Output the state at the initial time"}}
644 double t0 = 0, tf = 1;
645 bool output_t0 =
false;
646 std::vector<double> grid;
647 bool uses_legacy_options =
false;
650 for (
auto&& op : opts) {
651 if (op.first==
"output_t0") {
652 output_t0 = op.second;
653 uses_legacy_options =
true;
654 }
else if (op.first==
"print_stats") {
656 }
else if (op.first==
"nfwd") {
658 }
else if (op.first==
"nadj") {
660 }
else if (op.first==
"grid") {
662 uses_legacy_options =
true;
663 }
else if (op.first==
"augmented_options") {
665 }
else if (op.first==
"transition") {
667 }
else if (op.first==
"max_event_iter") {
669 }
else if (op.first==
"max_events") {
671 }
else if (op.first==
"event_tol") {
673 }
else if (op.first==
"event_acceptable_tol") {
675 }
else if (op.first==
"t0") {
677 uses_legacy_options =
true;
678 }
else if (op.first==
"tf") {
680 uses_legacy_options =
true;
688 if (uses_legacy_options) {
689 static bool first_encounter =
true;
690 if (first_encounter) {
692 casadi_warning(
"The options 't0', 'tf', 'grid' and 'output_t0' have been deprecated.\n"
693 "The same functionality is provided by providing additional input arguments to "
694 "the 'integrator' function, in particular:\n"
695 " * Call integrator(..., t0, tf, options) for a single output time, or\n"
696 " * Call integrator(..., t0, grid, options) for multiple grid points.\n"
697 "The legacy 'output_t0' option can be emulated by including or excluding 't0' in 'grid'.\n"
698 "Backwards compatibility is provided in this release only.");
699 first_encounter =
false;
703 if (grid.empty()) grid = {t0, tf};
712 casadi_assert(
nfwd_ >= 0,
"Number of forward sensitivities must be non-negative");
713 casadi_assert(
nadj_ >= 0,
"Number of adjoint sensitivities must be non-negative");
723 casadi_assert(sp.
is_empty() || sp.
is_scalar(),
"DAE time variable must be empty or scalar. "
724 "Got dimension " +
str(sp.
size()));
726 casadi_assert(sp.
is_vector(),
"DAE inputs must be vectors. "
729 casadi_assert(sp.
is_dense(),
"DAE inputs must be dense . "
730 +
dyn_in(i) +
" is sparse.");
736 casadi_assert(sp.
is_vector(),
"DAE outputs must be vectors. "
738 casadi_assert(sp.
is_dense(),
"DAE outputs must be dense . "
752 casadi_warning(
"Event support is experimental");
756 casadi_assert(
nx1_ > 0,
"Ill-posed ODE - no state");
851 "Jacobian of the forward problem is structurally rank-deficient. "
856 "Jacobian of the backward problem is structurally rank-deficient. "
883 casadi_int*& iw,
double*& w)
const {
896 m->edot = w; w +=
ne_;
897 m->old_e = w; w +=
ne_;
898 m->xdot = w; w +=
nx_;
899 m->zdot = w; w +=
nz_;
900 m->event_triggered = iw; iw +=
ne_;
902 m->adj_x = w; w +=
nrx_;
903 m->adj_z = w; w +=
nrz_;
904 m->adj_p = w; w +=
nrq_;
905 m->adj_q = w; w +=
nrp_;
907 m->tmp1 = w; w +=
ntmp_;
908 m->tmp2 = w; w +=
ntmp_;
930 ret = get_forward_dae<SX>(aug_name);
932 ret = get_forward_dae<MX>(aug_name);
934 }
catch (std::exception& e) {
935 casadi_error(
"Failed to generate augmented DAE for " +
name_ +
":\n" + e.what());
942 template<
typename MatType>
947 casadi_assert(
ne_ == 0,
"Event support not implemented for Integrator::augmented_dae");
950 std::vector<MatType> arg = MatType::get_input(
oracle_);
951 std::vector<MatType> res =
oracle_(arg);
954 std::vector<std::vector<MatType>> aug_in(
DYN_NUM_IN);
955 for (casadi_int i = 0; i <
DYN_NUM_IN; ++i) aug_in[i].push_back(arg.at(i));
956 std::vector<std::vector<MatType>> aug_out(
DYN_NUM_OUT);
957 for (casadi_int i = 0; i <
DYN_NUM_OUT; ++i) aug_out[i].push_back(res.at(i));
963 std::vector<std::vector<MatType>> seed(
nfwd_, std::vector<MatType>(
DYN_NUM_IN));
964 for (casadi_int d = 0; d <
nfwd_; ++d) {
966 std::string pref =
"aug" +
str(d) +
"_";
976 if (i !=
DYN_T) aug_in[i].push_back(seed[d][i]);
981 std::vector<std::vector<MatType>> sens;
986 casadi_assert_dev(sens.size() ==
nfwd_);
987 for (casadi_int d = 0; d <
nfwd_; ++d) {
995 for (casadi_int i = 0; i <
DYN_NUM_IN; ++i) arg.at(i) = vertcat(aug_in[i]);
996 for (casadi_int i = 0; i <
DYN_NUM_OUT; ++i) res.at(i) = vertcat(aug_out[i]);
1014 for (casadi_int i = 0; i <
nfwd_; ++i) {
1040 for (casadi_int i = 0; i <
nfwd_; ++i) {
1074 for (casadi_int i = 0; i <
nfwd_; ++i) {
1121 for (casadi_int i = 0; i <
nfwd_; ++i) {
1148 casadi_int* iw,
bvec_t* w,
void* mem)
const {
1182 std::copy_n(x0,
nx_, x);
1185 for (casadi_int k = 0; k <
nt(); ++k) {
1188 for (casadi_int i = 0; i <
nx_; ++i) tmp1[i] |= x[i];
1191 std::copy_n(tmp1,
nx_ +
nx_, w);
1192 std::fill_n(tmp1,
nx_ +
nz_, 0);
1196 if (xf) std::copy_n(tmp1,
nx_, xf);
1197 if (zf) std::copy_n(tmp1 +
nx_,
nz_, zf);
1200 if (
nq_ > 0 && qf) {
1205 std::copy_n(tmp1,
nx_, x);
1214 std::fill_n(tmp2,
nrx_, 0);
1215 if (adj_p0) std::fill_n(adj_p0,
nrq_, 0);
1218 if (adj_xf) adj_xf +=
nrx_ *
nt();
1219 if (adj_qf) adj_qf +=
nrp_ *
nt();
1220 if (adj_u) adj_u +=
nuq_ *
nt();
1223 for (casadi_int k =
nt(); k-- > 0; ) {
1225 if (adj_xf) adj_xf -=
nrx_;
1226 if (adj_qf) adj_qf -=
nrp_;
1227 if (adj_u) adj_u -=
nuq_;
1232 for (casadi_int i = 0; i <
nrx_; ++i) tmp2[i] |= adj_xf[i];
1236 if (
bdae_sp_forward(&m, tmp1, tmp1 +
nx_, p, u, tmp2, adj_qf, adj_x, adj_z))
return 1;
1237 for (casadi_int i = 0; i <
nrx_; ++i) adj_x[i] |= tmp2[i];
1240 std::copy_n(adj_x,
nrx_ +
nrz_, w);
1241 std::fill_n(adj_x,
nrx_ +
nrz_, 0);
1245 if ((
nrq_ > 0 && adj_p0) || (
nuq_ > 0 && adj_u)) {
1250 for (casadi_int i = 0; i <
nrq_; ++i) adj_p0[i] |= adj_p[i];
1255 std::copy_n(adj_x,
nx_, tmp2);
1259 if (adj_x0) std::copy_n(adj_x,
nrx_, adj_x0);
1273 for (casadi_int i = 0; i <
nfwd_; ++i) {
1301 for (casadi_int i = 0; i <
nfwd_; ++i) {
1335 for (casadi_int i = 0; i <
nfwd_; ++i) {
1382 for (casadi_int i = 0; i <
nfwd_; ++i) {
1413 casadi_int* iw,
bvec_t* w,
void* mem)
const {
1447 std::fill_n(tmp1,
nx_ +
nz_, 0);
1452 std::copy_n(adj_x0,
nrx_, adj_x);
1453 std::fill_n(adj_x0,
nrx_, 0);
1455 std::fill_n(adj_x,
nrx_, 0);
1458 std::fill_n(adj_z,
nrz_, 0);
1461 if (adj_p0) std::copy_n(adj_p0,
nrq_, adj_p);
1464 for (casadi_int k = 0; k <
nt(); ++k) {
1466 if (adj_p0) std::copy_n(adj_p,
nrq_, adj_p0);
1470 for (casadi_int i = 0; i <
nrx_; ++i) adj_x[i] |= adj_xf[i];
1471 std::fill_n(adj_xf,
nrx_, 0);
1475 if ((
nrq_ > 0 && adj_p0) || (
nuq_ > 0 && adj_u)) {
1483 std::copy_n(w,
nrx_ +
nrz_, adj_x);
1486 std::copy_n(adj_x,
nrx_, tmp2);
1489 if (
bdae_sp_reverse(&m, tmp1, tmp1 +
nx_, p, u, tmp2, adj_qf, adj_x, adj_z))
return 1;
1492 std::copy_n(tmp2,
nrx_, adj_x);
1493 std::fill_n(adj_z,
nrz_, 0);
1496 if (adj_xf) adj_xf +=
nrx_;
1497 if (adj_qf) adj_qf +=
nrp_;
1498 if (adj_u) adj_u +=
nuq_;
1503 if (u) u +=
nu_ *
nt();
1507 if (xf) xf +=
nx_ *
nt();
1508 if (zf) zf +=
nz_ *
nt();
1509 if (qf) qf +=
nq_ *
nt();
1512 for (casadi_int k =
nt(); k-- > 0; ) {
1521 for (casadi_int i = 0; i <
nx_; ++i) tmp1[i] |= xf[i];
1522 std::fill_n(xf,
nx_, 0);
1525 for (casadi_int i = 0; i <
nz_; ++i) tmp1[
nx_ + i] |= zf[i];
1526 std::fill_n(zf,
nz_, 0);
1530 if (
nq_ > 0 && qf) {
1535 std::fill_n(w,
nx_ +
nz_, 0);
1537 std::copy_n(w,
nx_ +
nz_, tmp1);
1540 std::copy_n(tmp1,
nx_, x);
1546 std::copy_n(x,
nx_, tmp1);
1547 std::fill_n(tmp1 +
nx_,
nz_, 0);
1552 for (casadi_int i = 0; i <
nx_; ++i) x0[i] |= x[i];
1559 const std::vector<std::string>& inames,
1560 const std::vector<std::string>& onames,
1561 const Dict& opts)
const {
1567 aug_opts[i.first] = i.second;
1574 std::string aug_prefix =
"fsens" +
str(nfwd) +
"_";
1575 aug_opts[
"derivative_of"] =
self();
1576 aug_opts[
"nfwd"] = nfwd;
1577 aug_opts[
"nadj"] =
nadj_;
1582 std::vector<MX> ret_in;
1597 std::vector<MX> v(nfwd);
1599 for (casadi_int d = 0; d < nfwd; ++d) {
1601 aug_in[i].push_back(v[d]);
1603 ret_in.push_back(horzcat(v));
1611 std::vector<MX> ret_in_split = horzsplit_n(ret_in[i],
nt());
1613 std::vector<std::vector<MX>> aug_in_split(nfwd);
1614 for (casadi_int d = 0; d < nfwd; ++d) {
1615 aug_in_split[d] = horzsplit_n(aug_in[i][d],
nt());
1619 for (casadi_int k = 0; k <
nt(); ++k) {
1620 v.push_back(ret_in_split.at(k));
1621 for (casadi_int d = 0; d < nfwd; ++d) {
1622 v.push_back(aug_in_split[d].at(k));
1628 v.insert(v.begin(), ret_in[i]);
1631 for (
MX& e : v) e = vec(e);
1637 std::vector<MX> ret_out;
1642 std::vector<casadi_int> offset = {0};
1643 for (casadi_int k = 0; k < n_grid; ++k) {
1644 for (casadi_int d = 0; d <= nfwd; ++d) {
1645 offset.push_back(offset.back() +
size2_out(i) / n_grid);
1648 std::vector<MX> integrator_out_split = horzsplit(
1651 std::vector<MX> ret_out_split;
1652 ret_out_split.reserve(n_grid * nfwd);
1653 for (casadi_int d = 0; d < nfwd; ++d) {
1654 for (casadi_int k = 0; k < n_grid; ++k) {
1655 ret_out_split.push_back(integrator_out_split.at((nfwd + 1) * k + d + 1));
1658 ret_out.push_back(horzcat(ret_out_split));
1661 Dict options = opts;
1662 options[
"allow_duplicate_io_names"] =
true;
1665 return Function(name, ret_in, ret_out, inames, onames, options);
1669 const std::vector<std::string>& inames,
1670 const std::vector<std::string>& onames,
1671 const Dict& opts)
const {
1675 casadi_assert(
ne_ == 0,
"Event support not implemented for Integrator::get_reverse");
1680 aug_opts[i.first] = i.second;
1687 std::string aug_prefix =
"asens" +
str(nadj) +
"_";
1688 aug_opts[
"derivative_of"] =
self();
1691 aug_opts[
"nadj"] = nadj;
1692 aug_opts[
"nfwd"] = 0;
1695 aug_opts[
"nfwd"] = nadj;
1696 aug_opts[
"nadj"] =
nadj_;
1702 std::vector<MX> ret_in;
1717 std::vector<MX> v(nadj);
1719 for (casadi_int d=0; d<nadj; ++d) {
1721 aug_in[i].push_back(v[d]);
1723 ret_in.push_back(horzcat(v));
1732 casadi_int n_grid =
grid_in(i) ?
nt() : 1;
1734 std::vector<MX> ret_in_split;
1735 std::vector<std::vector<MX>> aug_in_split(nadj);
1738 ret_in_split = horzsplit_n(ret_in[i],
nt());
1740 for (casadi_int d = 0; d < nadj; ++d) {
1741 aug_in_split[d] = horzsplit_n(aug_in[j][d],
nt());
1745 ret_in_split = {ret_in[i]};
1746 for (casadi_int d = 0; d < nadj; ++d) aug_in_split[d] = {aug_in[j][d]};
1750 for (
auto&& e : ret_in_split) e = vec(e);
1751 for (
auto&& e1 : aug_in_split) {
1752 for (
auto&& e2 : e1) e2 = vec(e2);
1756 for (casadi_int k = 0; k < ret_in_split.size(); ++k) {
1757 v.push_back(ret_in_split.at(k));
1758 for (casadi_int d = 0; d < nadj; ++d) {
1759 v.push_back(aug_in_split[d].at(k));
1767 std::vector<MX> ret_out;
1773 std::vector<casadi_int> offset = {0};
1774 for (casadi_int k = 0; k < n_grid; ++k) {
1775 offset.push_back(offset.back() +
numel_out(j) / n_grid);
1776 for (casadi_int d = 0; d < nadj; ++d) {
1777 offset.push_back(offset.back() +
numel_in(i) / n_grid);
1780 std::vector<MX> integrator_out_split = vertsplit(vec(
integrator_out[j]), offset);
1782 std::vector<MX> ret_out_split;
1783 ret_out_split.reserve(n_grid * nadj);
1784 for (casadi_int d = 0; d < nadj; ++d) {
1785 for (casadi_int k = 0; k < n_grid; ++k) {
1786 ret_out_split.push_back(reshape(integrator_out_split.at((nadj + 1) * k + d + 1),
1790 ret_out.push_back(horzcat(ret_out_split));
1793 Dict options = opts;
1794 options[
"allow_duplicate_io_names"] =
true;
1797 return Function(name, ret_in, ret_out, inames, onames, options);
1813 return blockcat(J, J12, J21, J22);
1834 return blockcat(J_xx, J_xz, J_zx, J_zz);
1854 return blockcat(J_xx, J_xz, J_zx, J_zz);
1859 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
1860 std::mutex Integrator::mutex_solvers_;
1866 double t0,
const std::vector<double>& tout) :
Integrator(name, dae, t0, tout) {
1878 {{
"number_of_finite_elements",
1880 "Target number of finite elements. "
1881 "The actual number may be higher to accommodate all output times"}},
1884 "Implement as MX Function (codegeneratable/serializable) default: false"}},
1885 {
"simplify_options",
1887 "Any options to pass to simplified form Function constructor"}}
1897 auto it = opts.find(
"simplify");
1898 if (it != opts.end())
simplify = it->second;
1907 std::vector<MX> F_in = F.
mx_in();
1918 double h = (
tout_.back() -
t0_)/
static_cast<double>(
disc_.back());
1925 std::vector<MX> F_out;
1927 for (casadi_int k=0; k<
disc_.back(); ++k) {
1946 auto it = opts.find(
"simplify_options");
1947 if (it!=opts.end())
update_dict(sopts, it->second);
1960 for (
auto&& op : opts) {
1961 if (op.first==
"number_of_finite_elements") {
1967 casadi_assert(
nk_target_ > 0,
"Number of finite elements must be strictly positive");
1976 for (
double t_next :
tout_) {
1977 disc_.push_back(
disc_.back() + std::ceil((t_next - t_cur) / h_target));
2010 casadi_int*& iw,
double*& w)
const {
2018 m->v_prev = w; w +=
nv_;
2019 m->q_prev = w; w +=
nq_;
2022 m->rv = w; w +=
nrv_;
2023 m->adj_u = w; w +=
nuq_;
2024 m->adj_p_prev = w; w +=
nrq_;
2025 m->adj_u_prev = w; w +=
nuq_;
2029 m->x_tape = w; w += (
disc_.back() + 1) *
nx_;
2030 m->v_tape = w; w +=
disc_.back() *
nv_;
2045 double* x_prev = m->
tmp1;
2048 casadi_int nj =
disc_[m->k + 1] -
disc_[m->k];
2049 double h = (m->t_next - m->t) / nj;
2052 for (casadi_int j = 0; j < nj; ++j) {
2054 double t = m->t + j * h;
2062 stepF(m, t, h, x_prev, m->v_prev, m->x, m->v, m->q);
2067 casadi_int tapeind =
disc_[m->k] + j;
2080 double* adj_x,
double* adj_p,
double* adj_u)
const {
2087 casadi_int nj =
disc_[m->k + 1] -
disc_[m->k];
2088 double h = (m->t - m->t_next) / nj;
2091 for (casadi_int j = nj; j-- > 0; ) {
2093 double t = m->t_next + j * h;
2101 casadi_int tapeind =
disc_[m->k] + j;
2103 m->x_tape +
nx_ * tapeind, m->x_tape +
nx_ * (tapeind + 1),
2104 m->v_tape +
nv_ * tapeind,
2105 m->tmp1, m->rv, m->adj_x, m->adj_p, m->adj_u);
2118 const double* x0,
const double* v0,
double* xf,
double* vf,
double* qf)
const {
2151 const double* x0,
const double* xf,
const double* vf,
2152 const double* adj_xf,
const double* rv0,
2153 double* adj_x0,
double* adj_p,
double* adj_u)
const {
2215 casadi_fill(m->v,
nv_, std::numeric_limits<double>::quiet_NaN());
2240 const double* adj_x,
const double* adj_z,
const double* adj_q)
const {
2253 const std::string& name,
const Function& dae,
double t0,
const std::vector<double>& tout)
2264 "An implicit function solver"}},
2265 {
"rootfinder_options",
2267 "Options to be passed to the NLP Solver"}}
2276 std::string implicit_function_name =
"newton";
2280 for (
auto&& op : opts) {
2281 if (op.first==
"rootfinder") {
2282 implicit_function_name = op.second.to_string();
2283 }
else if (op.first==
"rootfinder_options") {
2308 template<
typename XType>
2310 const std::map<std::string, XType>& d) {
2312 for (
auto&& i : d) {
2314 de_in[
DYN_T]=i.second;
2315 }
else if (i.first==
"x") {
2316 de_in[
DYN_X]=i.second;
2317 }
else if (i.first==
"z") {
2318 de_in[
DYN_Z]=i.second;
2319 }
else if (i.first==
"p") {
2320 de_in[
DYN_P]=i.second;
2321 }
else if (i.first==
"u") {
2322 de_in[
DYN_U]=i.second;
2323 }
else if (i.first==
"ode") {
2325 }
else if (i.first==
"alg") {
2327 }
else if (i.first==
"quad") {
2329 }
else if (i.first==
"zero") {
2332 casadi_error(
"No such field: " + i.first);
2337 for (casadi_int i = 0; i <
DYN_NUM_IN; ++i) {
2338 const Sparsity& sp = de_in[i].sparsity();
2340 casadi_assert(sp.
is_empty() || sp.
is_scalar(),
"DAE time variable must be empty or scalar. "
2341 "Got dimension " +
str(sp.
size()));
2343 casadi_assert(sp.
is_empty() || sp.
is_vector(),
"DAE inputs must be empty or vectors. "
2346 casadi_assert(sp.
is_dense(),
"DAE inputs must be dense . "
2347 +
dyn_in(i) +
" is sparse.");
2349 de_in[i] = vec(de_in[i]);
2354 const Sparsity& sp = de_out[i].sparsity();
2355 casadi_assert(sp.
is_empty() || sp.
is_vector(),
"DAE outputs must be empty or vectors. "
2358 de_out[i] = vec(densify(de_out[i]));
2372 s.
pack(
"Integrator::t0",
t0_);
2378 s.
pack(
"Integrator::nx",
nx_);
2379 s.
pack(
"Integrator::nz",
nz_);
2380 s.
pack(
"Integrator::nq",
nq_);
2394 s.
pack(
"Integrator::np",
np_);
2399 s.
pack(
"Integrator::nu",
nu_);
2402 s.
pack(
"Integrator::ne",
ne_);
2483 s.
version(
"FixedStepIntegrator", 3);
2485 s.
pack(
"FixedStepIntegrator::disc",
disc_);
2486 s.
pack(
"FixedStepIntegrator::nv",
nv_);
2487 s.
pack(
"FixedStepIntegrator::nv1",
nv1_);
2488 s.
pack(
"FixedStepIntegrator::nrv",
nrv_);
2489 s.
pack(
"FixedStepIntegrator::nrv1",
nrv1_);
2493 s.
version(
"FixedStepIntegrator", 3);
2496 s.
unpack(
"FixedStepIntegrator::nv",
nv_);
2505 s.
version(
"ImplicitFixedStepIntegrator", 2);
2510 s.
version(
"ImplicitFixedStepIntegrator", 2);
2547 if (
nu_ == 0 || u == 0)
return nt() - 1;
2549 for (; k + 1 <
nt(); ++k) {
2551 const double *u_next = u +
nu_;
2553 for (casadi_int i = 0; i <
nu_; ++i) {
2555 if (u[i] != u_next[i])
return k;
2599 double t_event = m->
t_stop;
2600 casadi_int event_index = -1;
2606 for (casadi_int i = 0; i <
ne_; ++i) {
2609 if (m->
e[i] > 0 && m->
edot[i] < 0) {
2611 double t = m->
t - m->
e[i] / m->
edot[i];
2621 if (event_index >= 0) {
2623 if (
verbose_) casadi_message(
"Projected zero crossing for index " +
str(event_index)
2624 +
" at t = " +
str(t_event));
2635 casadi_error(
"At t = " +
str(m->
t) +
": Too many event iterations during interval "
2639 if (*ind < 0 || m->event_triggered[*ind])
return 1;
2643 if (
verbose_) casadi_message(
"Zero crossing for index " +
str(*ind) +
" at t = " +
str(m->
t));
2667 for (casadi_int i = 0; i <
nfwd_; ++i) {
2671 for (casadi_int i = 0; i <
nfwd_; ++i) {
2678 double index = *ind;
2709 for (casadi_int i = 0; i <
nfwd_; ++i) {
2719 if (
nu_ == 0 || u == 0)
return -1;
2723 const double *u_next = u -
nu_;
2725 for (casadi_int i = 0; i <
nu_; ++i) {
2727 if (u[i] != u_next[i])
return k;
2738 if (v == 0 || n == 0)
return true;
2740 for (casadi_int i = 0; i < n; ++i) {
2741 if (v[i] != 0.)
return false;
Helper class for Serialization.
void unpack(Sparsity &e)
Reconstruct an object from the input stream.
void version(const std::string &name, int v)
~FixedStepIntegrator() override
Destructor.
std::vector< casadi_int > disc_
static const Options options_
Options.
void init(const Dict &opts) override
Initialize stage.
void stepB(FixedStepMemory *m, double t, double h, const double *x0, const double *xf, const double *vf, const double *adj_xf, const double *rv0, double *adj_x0, double *adj_p, double *adj_u) const
Take integrator step backward.
int init_mem(void *mem) const override
Initalize memory block.
void stepF(FixedStepMemory *m, double t, double h, const double *x0, const double *v0, double *xf, double *vf, double *qf) const
Take integrator step forward.
void impulseB(IntegratorMemory *mem, const double *adj_x, const double *adj_z, const double *adj_q) const override
Introduce an impulse into the backwards integration at the current time.
void retreat(IntegratorMemory *mem, const double *u, double *adj_x, double *adj_p, double *adj_u) const override
Retreat solution in time.
void reset(IntegratorMemory *mem, bool first_call) const override
Reset the forward solver at the start or after an event.
casadi_int nv_
Number of dependent variables in the discrete time integration.
int advance_noevent(IntegratorMemory *mem) const override
Advance solution in time.
FixedStepIntegrator(const std::string &name, const Function &dae, double t0, const std::vector< double > &tout)
Constructor.
void resetB(IntegratorMemory *mem) const override
Reset the backward problem and take time to tf.
Function create_advanced(const Dict &opts) override
virtual void setup_step()=0
Setup step functions.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
void set_work(void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const override
Set the (persistent) work vectors.
casadi_int size1_in(casadi_int ind) const
Input/output dimensions.
void alloc_iw(size_t sz_iw, bool persistent=false)
Ensure required length of iw field.
virtual void call_forward(const std::vector< MX > &arg, const std::vector< MX > &res, const std::vector< std::vector< MX > > &fseed, std::vector< std::vector< MX > > &fsens, bool always_inline, bool never_inline) const
Forward mode AD, virtual functions overloaded in derived classes.
static std::string forward_name(const std::string &fcn, casadi_int nfwd)
Helper function: Get name of forward derivative function.
casadi_int numel_out() const
Number of input/output elements.
const Sparsity & sparsity_in(casadi_int ind) const
Input/output sparsity.
virtual void set_work(void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const
Set the (persistent) work vectors.
casadi_int numel_in() const
Number of input/output elements.
size_t n_in_
Number of inputs and outputs.
casadi_int size2_out(casadi_int ind) const
Input/output dimensions.
casadi_int size1_out(casadi_int ind) const
Input/output dimensions.
std::pair< casadi_int, casadi_int > size_out(casadi_int ind) const
Input/output dimensions.
void serialize_type(SerializingStream &s) const override
Serialize type information.
const Sparsity & sparsity_out(casadi_int ind) const
Input/output sparsity.
void alloc_w(size_t sz_w, bool persistent=false)
Ensure required length of w field.
void setup(void *mem, const double **arg, double **res, casadi_int *iw, double *w) const
Set the (persistent and temporary) work vectors.
static std::string reverse_name(const std::string &fcn, casadi_int nadj)
Helper function: Get name of adjoint derivative function.
casadi_int size2_in(casadi_int ind) const
Input/output dimensions.
casadi_int numel_in() const
Get number of input elements.
Function forward(casadi_int nfwd) const
Get a function that calculates nfwd forward derivatives.
casadi_int nnz_out() const
Get number of output nonzeros.
const MX mx_in(casadi_int ind) const
Get symbolic primitives equivalent to the input expressions.
const Sparsity & sparsity_out(casadi_int ind) const
Get sparsity of a given output.
const std::string & name() const
Name of the function.
casadi_int numel_out() const
Get number of output elements.
Function reverse(casadi_int nadj) const
Get a function that calculates nadj adjoint derivatives.
static Function create(FunctionInternal *node)
Create from node.
std::vector< double > nominal_in(casadi_int ind) const
Get nominal input value.
const Sparsity & sparsity_in(casadi_int ind) const
Get sparsity of a given input.
casadi_int n_out() const
Get the number of function outputs.
casadi_int n_in() const
Get the number of function inputs.
std::vector< std::string > get_free() const
Get free variables as a string.
bool is_a(const std::string &type, bool recursive=true) const
Check if the function is of a particular type.
bool has_free() const
Does the function have free variables.
std::pair< casadi_int, casadi_int > size_in(casadi_int ind) const
Get input dimension.
const std::vector< Sparsity > & jac_sparsity(bool compact=false) const
Get, if necessary generate, the sparsity of all Jacobian blocks.
static MX sym(const std::string &name, casadi_int nrow=1, casadi_int ncol=1)
Create an nrow-by-ncol symbolic primitive.
bool is_null() const
Is a null pointer?
~ImplicitFixedStepIntegrator() override
Destructor.
void init(const Dict &opts) override
Initialize stage.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
static const Options options_
Options.
ImplicitFixedStepIntegrator(const std::string &name, const Function &dae, double t0, const std::vector< double > &tout)
Constructor.
Internal storage for integrator related data.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
casadi_int nfwd_
Number of sensitivities.
void init(const Dict &opts) override
Initialize.
virtual void reset(IntegratorMemory *mem, bool first_call) const
Reset the forward solver at the start or after an event.
int eval(const double **arg, double **res, casadi_int *iw, double *w, void *mem) const override
evaluate
static const Options options_
Options.
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize into MX.
void set_z(IntegratorMemory *m, const double *z) const
virtual void resetB(IntegratorMemory *mem) const =0
Reset the backward problem.
void get_z(IntegratorMemory *m, double *z) const
~Integrator() override=0
Destructor.
void set_x(IntegratorMemory *m, const double *x) const
void serialize_type(SerializingStream &s) const override
Serialize type information.
casadi_int next_stopB(casadi_int k, const double *u) const
Find next stop time.
int advance(IntegratorMemory *m) const
Advance solution in time, with events handling.
Sparsity sp_jac_aug(const Sparsity &J, const Sparsity &J1) const
Helper function, get augmented system Jacobian.
static Function map2oracle(const std::string &name, const std::map< std::string, XType > &d)
Convert dictionary to Problem.
std::vector< double > nom_x_
Function rdae_
Backwards DAE function.
Integrator(const std::string &name, const Function &oracle, double t0, const std::vector< double > &tout)
Constructor.
Dict augmented_options_
Augmented user option.
Sparsity get_sparsity_in(casadi_int i) override
Sparsities of function inputs and outputs.
casadi_int nrx_
Number of states for the backward integration.
casadi_int max_events_
Maximum total number of events during the simulation.
Sparsity sp_jac_dae_
Sparsity pattern of the extended Jacobians.
void get_q(IntegratorMemory *m, double *q) const
int init_mem(void *mem) const override
Initalize memory block.
int predict_events(IntegratorMemory *m) const
Predict next event time.
casadi_int next_stop(casadi_int k, const double *u) const
Find next stop time.
int fdae_sp_reverse(SpReverseMem *m, bvec_t *x, bvec_t *p, bvec_t *u, bvec_t *ode, bvec_t *alg) const
Reverse sparsity pattern propagation through DAE, forward problem.
virtual MX algebraic_state_output(const MX &Z) const
int fquad_sp_forward(SpForwardMem *m, const bvec_t *x, const bvec_t *z, const bvec_t *p, const bvec_t *u, bvec_t *quad) const
Forward sparsity pattern propagation through quadratures, forward problem.
virtual void retreat(IntegratorMemory *mem, const double *u, double *adj_x, double *adj_p, double *adj_u) const =0
Retreat solution in time.
casadi_int np_
Number of forward and backward parameters.
casadi_int nt() const
Number of output times.
void set_u(IntegratorMemory *m, const double *u) const
bool print_stats_
Options.
casadi_int ntmp_
Length of the tmp1, tmp2 vectors.
virtual void impulseB(IntegratorMemory *mem, const double *adj_x, const double *adj_z, const double *adj_q) const =0
Introduce an impulse into the backwards integration at the current time.
int bquad_sp_reverse(SpReverseMem *m, bvec_t *x, bvec_t *z, bvec_t *p, bvec_t *u, bvec_t *adj_ode, bvec_t *adj_alg, bvec_t *adj_quad, bvec_t *adj_p, bvec_t *adj_u) const
Reverse sparsity pattern propagation through quadratures, backward problem.
std::vector< double > nom_z_
int sp_forward(const bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w, void *mem) const override
Propagate sparsity forward.
int bdae_sp_reverse(SpReverseMem *m, bvec_t *x, bvec_t *z, bvec_t *p, bvec_t *u, bvec_t *adj_ode, bvec_t *adj_quad, bvec_t *adj_x, bvec_t *adj_z) const
Reverse sparsity pattern propagation through DAE, backward problem.
static std::vector< std::string > quad_out()
IO conventions for continuous time dynamics.
static bool grid_out(casadi_int i)
Is an output repeated for each grid point?
Function get_forward(casadi_int nfwd, const std::string &name, const std::vector< std::string > &inames, const std::vector< std::string > &onames, const Dict &opts) const override
Generate a function that calculates nfwd forward derivatives.
static bool grid_in(casadi_int i)
Is an input repeated for each grid point?
virtual MX algebraic_state_init(const MX &x0, const MX &z0) const
void get_x(IntegratorMemory *m, double *x) const
virtual void print_stats(IntegratorMemory *mem) const
Print solver statistics.
virtual Function create_advanced(const Dict &opts)
Sparsity get_sparsity_out(casadi_int i) override
Sparsities of function inputs and outputs.
static std::vector< std::string > bquad_out()
IO conventions for continuous time dynamics.
Function augmented_dae() const
Generate the augmented DAE system.
int trigger_event(IntegratorMemory *m, casadi_int *ind) const
Trigger an event.
Dict opts_
Copy of the options.
static std::map< std::string, Plugin > solvers_
Collection of solvers.
static std::vector< std::string > bdyn_in()
IO conventions for continuous time dynamics.
int bquad_sp_forward(SpForwardMem *m, const bvec_t *x, const bvec_t *z, const bvec_t *p, const bvec_t *u, const bvec_t *adj_ode, const bvec_t *adj_alg, const bvec_t *adj_quad, bvec_t *adj_p, bvec_t *adj_u) const
Forward sparsity pattern propagation through quadratures, backward problem.
static bool all_zero(const double *v, casadi_int n)
Helper function: Vector has only zeros?
void set_work(void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const override
Set the (persistent) work vectors.
int fquad_sp_reverse(SpReverseMem *m, bvec_t *x, bvec_t *z, bvec_t *p, bvec_t *u, bvec_t *quad) const
Reverse sparsity pattern propagation through quadratures, forward problem.
std::vector< double > tout_
Output time grid.
double event_tol_
Termination tolerance for the event iteration.
void set_q(IntegratorMemory *m, const double *q) const
static std::vector< std::string > dae_out()
IO conventions for continuous time dynamics.
int sp_reverse(bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w, void *mem) const override
Propagate sparsity backwards.
double event_acceptable_tol_
Acceptable tolerance for the event iteration.
virtual Dict getDerivativeOptions(bool fwd) const
Set solver specific options to generated augmented integrators.
virtual int advance_noevent(IntegratorMemory *mem) const =0
Advance solution in time, without events handling.
Function get_reverse(casadi_int nadj, const std::string &name, const std::vector< std::string > &inames, const std::vector< std::string > &onames, const Dict &opts) const override
Generate a function that calculates nadj adjoint derivatives.
Function transition_
Function to be called at state events.
static std::vector< std::string > bdae_out()
IO conventions for continuous time dynamics.
Sparsity sp_jac_rdae()
Create sparsity pattern of the extended Jacobian (backward problem)
casadi_int max_event_iter_
Maximum number of event iterations for a single event.
Function get_forward_dae(const std::string &name) const
Generate the augmented DAE system.
static const std::string infix_
Infix.
casadi_int nu_
Number of controls.
casadi_int nx_
Number of states for the forward integration.
Sparsity sp_jac_dae()
Create sparsity pattern of the extended Jacobian (forward problem)
int calc_edot(IntegratorMemory *m) const
Linearize the zero crossing function.
static std::vector< std::string > bdyn_out()
IO conventions for continuous time dynamics.
int fdae_sp_forward(SpForwardMem *m, const bvec_t *x, const bvec_t *p, const bvec_t *u, bvec_t *ode, bvec_t *alg) const
Forward sparsity pattern propagation through DAE, forward problem.
int bdae_sp_forward(SpForwardMem *m, const bvec_t *x, const bvec_t *z, const bvec_t *p, const bvec_t *u, const bvec_t *adj_ode, const bvec_t *adj_quad, bvec_t *adj_x, bvec_t *adj_z) const
Forward sparsity pattern propagation through DAE, backward problem.
casadi_int ne_
Number of of zero-crossing functions.
void set_p(IntegratorMemory *m, const double *p) const
static casadi_int adjmap_out(casadi_int i)
Which output is used to calculate a given input in adjoint sensitivity analysis.
Base class for functions that perform calculation with an oracle.
void set_function(const Function &fcn, const std::string &fname, bool jit=false)
Function oracle_
Oracle: Used to generate other functions.
int calc_sp_forward(const std::string &fcn, const bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w) const
Function create_function(const Function &oracle, const std::string &fname, const std::vector< std::string > &s_in, const std::vector< std::string > &s_out, const Function::AuxOut &aux=Function::AuxOut(), const Dict &opts=Dict())
void join_results(OracleMemory *m) const
Combine results from different threads.
void init(const Dict &opts) override
Function create_forward(const std::string &fname, casadi_int nfwd)
int init_mem(void *mem) const override
Initalize memory block.
int calc_function(OracleMemory *m, const std::string &fcn, const double *const *arg=nullptr, int thread_id=0) const
std::vector< std::string > get_function() const override
Get list of dependency functions.
bool has_function(const std::string &fname) const override
static const Options options_
Options.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
int calc_sp_reverse(const std::string &fcn, bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w) const
static bool has_plugin(const std::string &pname, bool verbose=false)
Check if a plugin is available or can be loaded.
void serialize_type(SerializingStream &s) const
Serialize type information.
static Plugin & getPlugin(const std::string &pname)
Load and get the creator function.
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize with type disambiguation.
virtual const char * plugin_name() const=0
static Plugin load_plugin(const std::string &pname, bool register_plugin=true, bool needs_lock=true)
Load a plugin dynamically.
Base class for FunctionInternal and LinsolInternal.
bool verbose_
Verbose printout.
void clear_mem()
Clear all memory (called from destructor)
Helper class for Serialization.
void version(const std::string &name, int v)
void pack(const Sparsity &e)
Serializes an object to the output stream.
bool is_vector() const
Check if the pattern is a row or column vector.
casadi_int size1() const
Get the number of rows.
static Sparsity diag(casadi_int nrow)
Create diagonal sparsity pattern *.
static Sparsity dense(casadi_int nrow, casadi_int ncol=1)
Create a dense rectangular sparsity pattern *.
void spsolve(bvec_t *X, bvec_t *B, bool tr) const
Propagate sparsity through a linear solve.
bool is_scalar(bool scalar_and_dense=false) const
Is scalar?
casadi_int size2() const
Get the number of columns.
std::pair< casadi_int, casadi_int > size() const
Get the shape.
bool is_empty(bool both=false) const
Check if the sparsity is empty.
bool is_singular() const
Check whether the sparsity-pattern indicates structural singularity.
bool is_dense() const
Is dense?
std::vector< std::string > dyn_out()
Get output scheme of a DAE function.
std::vector< std::string > event_in()
Get input scheme of an event transition function.
bool has_integrator(const std::string &name)
Check if a particular plugin is available.
std::vector< std::string > dyn_in()
Get input scheme of a DAE function.
casadi_int integrator_n_out()
Get the number of integrator outputs.
casadi_int dyn_n_in()
Get the number of inputs for a DAE function.
std::vector< std::string > integrator_out()
Get integrator output scheme of integrators.
std::vector< std::string > event_out()
Get output scheme of an event transition functions.
void load_integrator(const std::string &name)
Explicitly load a plugin dynamically.
casadi_int integrator_n_in()
Get the number of integrator inputs.
std::vector< std::string > integrator_in()
Get input scheme of integrators.
Function integrator(const std::string &name, const std::string &solver, const SXDict &dae, const Dict &opts)
std::string doc_integrator(const std::string &name)
Get the documentation string for a plugin.
casadi_int dyn_n_out()
Get the number of outputs for a DAE function.
std::vector< std::string > rootfinder_options(const std::string &name)
Get all options for a plugin.
Function rootfinder(const std::string &name, const std::string &solver, const SXDict &rfp, const Dict &opts)
std::map< std::string, MX > MXDict
@ STEP_NUM_IN
Number of arguments.
@ STEP_V0
Dependent variables.
IntegratorOutput
Output arguments of an integrator.
@ INTEGRATOR_ADJ_U
Adjoint sensitivities corresponding to the control vector.
@ INTEGRATOR_ADJ_Z0
Adjoint sensitivities corresponding to the algebraic variable guess.
@ INTEGRATOR_QF
Quadrature state at all output times.
@ INTEGRATOR_ADJ_P
Adjoint sensitivities corresponding to the parameter vector.
@ INTEGRATOR_ZF
Algebraic variable at all output times.
@ INTEGRATOR_XF
Differential state at all output times.
@ INTEGRATOR_NUM_OUT
Number of output arguments of an integrator.
@ INTEGRATOR_ADJ_X0
Adjoint sensitivities corresponding to the initial state.
IntegratorInput
Input arguments of an integrator.
@ INTEGRATOR_U
Piecewise constant control, a new control interval starts at each output time.
@ INTEGRATOR_ADJ_QF
Adjoint seeds corresponding to the quadratures at the output times.
@ INTEGRATOR_ADJ_ZF
Adjoint seeds corresponding to the algebraic variables at the output times.
@ INTEGRATOR_P
Parameters.
@ INTEGRATOR_ADJ_XF
Adjoint seeds corresponding to the states at the output times.
@ INTEGRATOR_Z0
Initial guess for the algebraic variable at the initial time.
@ INTEGRATOR_NUM_IN
Number of input arguments of an integrator.
@ INTEGRATOR_X0
Differential state at the initial time.
unsigned long long bvec_t
@ STEP_XF
State vector at next time.
@ STEP_QF
Quadrature state contribution.
@ STEP_VF
Dependent variables at next time.
@ STEP_NUM_OUT
Number of arguments.
EventIn
Inputs of an event transition function.
void casadi_copy(const T1 *x, casadi_int n, T1 *y)
COPY: y <-x.
DynIn
Inputs of the symbolic representation of the DAE.
EventOut
Outputs of an event transition function.
void casadi_fill(T1 *x, casadi_int n, T1 alpha)
FILL: x <- alpha.
std::map< std::string, SX > SXDict
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
DynOut
Outputs of the symbolic representation of the DAE.
void update_dict(Dict &target, const Dict &source, bool recurse)
Update the target dictionary in place with source elements.
std::string to_string(TypeFmi2 v)
void casadi_axpy(casadi_int n, T1 alpha, const T1 *x, T1 *y)
AXPY: y <- a*x + y.
void casadi_clear(T1 *x, casadi_int n)
CLEAR: x <- 0.
double simplify(double x)
casadi_int * event_triggered
Options metadata for a class.
Memory struct, forward sparsity pattern propagation.
Memory struct, backward sparsity pattern propagation.