bool isMonotone(const std::vector<T> &v) { return isNonDecreasing(v) || isNonIncreasing(v); }
void SimulatorInternal::init() { // Let the integration time start from the first point of the time grid. if (!grid_.empty()) integrator_.setOption("t0", grid_[0]); // Let the integration time stop at the last point of the time grid. if (!grid_.empty()) integrator_.setOption("tf", grid_[grid_.size()-1]); casadi_assert_message(isNonDecreasing(grid_), "The supplied time grid must be non-decreasing."); // Initialize the integrator integrator_.init(); // Generate an output function if there is none (returns the whole state) if (output_fcn_.isNull()) { SX t = SX::sym("t"); SX x = SX::sym("x", integrator_.input(INTEGRATOR_X0).sparsity()); SX z = SX::sym("z", integrator_.input(INTEGRATOR_Z0).sparsity()); SX p = SX::sym("p", integrator_.input(INTEGRATOR_P).sparsity()); vector<SX> arg(DAE_NUM_IN); arg[DAE_T] = t; arg[DAE_X] = x; arg[DAE_Z] = z; arg[DAE_P] = p; vector<SX> out(INTEGRATOR_NUM_OUT); out[INTEGRATOR_XF] = x; out[INTEGRATOR_ZF] = z; // Create the output function output_fcn_ = SXFunction(arg, out); output_.scheme = SCHEME_IntegratorOutput; } // Initialize the output function output_fcn_.init(); // Allocate inputs setNumInputs(INTEGRATOR_NUM_IN); for (int i=0; i<INTEGRATOR_NUM_IN; ++i) { input(i) = integrator_.input(i); } // Allocate outputs setNumOutputs(output_fcn_->getNumOutputs()); for (int i=0; i<getNumOutputs(); ++i) { output(i) = Matrix<double>::zeros(output_fcn_.output(i).numel(), grid_.size()); if (!output_fcn_.output(i).isEmpty()) { casadi_assert_message(output_fcn_.output(i).isVector(), "SimulatorInternal::init: Output function output #" << i << " has shape " << output_fcn_.output(i).dimString() << ", while a column-matrix shape is expected."); } } casadi_assert_message(output_fcn_.input(DAE_T).numel() <=1, "SimulatorInternal::init: output_fcn DAE_T argument must be " "scalar or empty, but got " << output_fcn_.input(DAE_T).dimString()); casadi_assert_message( output_fcn_.input(DAE_P).isEmpty() || integrator_.input(INTEGRATOR_P).sparsity() == output_fcn_.input(DAE_P).sparsity(), "SimulatorInternal::init: output_fcn DAE_P argument must be empty or" << " have dimension " << integrator_.input(INTEGRATOR_P).dimString() << ", but got " << output_fcn_.input(DAE_P).dimString()); casadi_assert_message( output_fcn_.input(DAE_X).isEmpty() || integrator_.input(INTEGRATOR_X0).sparsity() == output_fcn_.input(DAE_X).sparsity(), "SimulatorInternal::init: output_fcn DAE_X argument must be empty or have dimension " << integrator_.input(INTEGRATOR_X0).dimString() << ", but got " << output_fcn_.input(DAE_X).dimString()); // Call base class method FunctionInternal::init(); // Output iterators output_its_.resize(getNumOutputs()); }