FX FX::operator[](int k) const { // Argument checking if (k<0) k+=getNumOutputs(); casadi_assert_message(k<getNumOutputs(),"FX[int k]:: Attempt to select the k'th output with k=" << k << ", but should be smaller or equal to number of outputs (" << getNumOutputs() << ")."); // Get the inputs in MX form std::vector< MX > in = symbolicInput(); // Clone such that we can use const. FX clone = *this; // Get the outputs std::vector< MX > result = clone.call(in); // Construct an MXFunction with only the k'th output MXFunction ret(in,result[k]); ret.setInputScheme(getInputScheme()); // Initialize it ret.init(); // And return it, will automatically cast to FX return ret; }
Function SwitchInternal ::getDerReverse(const std::string& name, int nadj, Dict& opts) { // Derivative of each case vector<Function> der(f_.size()); for (int k=0; k<f_.size(); ++k) { if (!f_[k].isNull()) der[k] = f_[k].derReverse(nadj); } // Default case Function der_def; if (!f_def_.isNull()) der_def = f_def_.derReverse(nadj); // New Switch for derivatives stringstream ss; ss << "adj" << nadj << "_" << name_; Switch sw(ss.str(), der, der_def); // Construct wrapper inputs and arguments for calling sw vector<MX> arg = symbolicInput(); vector<MX> res = symbolicOutput(); vector<vector<MX> > seed = symbolicAdjSeed(nadj, res); vector<MX> w_in = arg; w_in.insert(w_in.end(), res.begin(), res.end()); // Arguments for calling sw being constructed vector<MX> v; v.push_back(arg.at(0)); // index for (int d=0; d<nadj; ++d) { // Add to wrapper input w_in.insert(w_in.end(), seed[d].begin(), seed[d].end()); // Add to sw argument vector v.insert(v.end(), arg.begin()+1, arg.end()); v.insert(v.end(), res.begin(), res.end()); v.insert(v.end(), seed[d].begin(), seed[d].end()); } // Construct wrapper outputs casadi_assert(v.size()==sw.nIn()); v = sw(v); vector<MX> w_out; MX ind_sens = MX(1, 1); // no dependency on index vector<MX>::const_iterator v_it = v.begin(), v_it_next; for (int d=0; d<nadj; ++d) { w_out.push_back(ind_sens); v_it_next = v_it + (nIn()-1); w_out.insert(w_out.end(), v_it, v_it_next); v_it = v_it_next; } // Create wrapper return MXFunction(name, w_in, w_out, opts); }
Function SwitchInternal ::getDerForward(const std::string& name, int nfwd, Dict& opts) { // Derivative of each case vector<Function> der(f_.size()); for (int k=0; k<f_.size(); ++k) { if (!f_[k].isNull()) der[k] = f_[k].derForward(nfwd); } // Default case Function der_def; if (!f_def_.isNull()) der_def = f_def_.derForward(nfwd); // New Switch for derivatives stringstream ss; ss << "fwd" << nfwd << "_" << name_; Switch sw(ss.str(), der, der_def); // Construct wrapper inputs and arguments for calling sw vector<MX> arg = symbolicInput(); vector<MX> res = symbolicOutput(); vector<vector<MX> > seed = symbolicFwdSeed(nfwd, arg); // Wrapper input being constructed vector<MX> w_in = arg; w_in.insert(w_in.end(), res.begin(), res.end()); // Arguments for calling sw being constructed vector<MX> v; v.insert(v.end(), arg.begin(), arg.end()); v.insert(v.end(), res.begin(), res.end()); for (int d=0; d<nfwd; ++d) { // ignore seed for ind seed[d][0] = MX::sym(seed[d][0].getName(), Sparsity::scalar(false)); // Add to wrapper input w_in.insert(w_in.end(), seed[d].begin(), seed[d].end()); // Add to sw argument vector v.insert(v.end(), seed[d].begin()+1, seed[d].end()); } // Create wrapper casadi_assert(v.size()==sw.nIn()); return MXFunction(name, w_in, sw(v), opts); }