int Switch::eval(const double** arg, double** res, casadi_int* iw, double* w, void* mem) const { // Get the function to be evaluated casadi_int k = arg[0] ? static_cast<casadi_int>(*arg[0]) : 0; const Function& fk = k>=0 && k<f_.size() ? f_[k] : f_def_; // Project arguments with different sparsity const double** arg1; if (project_in_) { // Project one or more argument arg1 = arg + n_in_; for (casadi_int i=0; i<n_in_-1; ++i) { const Sparsity& f_sp = fk.sparsity_in(i); const Sparsity& sp = sparsity_in_[i+1]; arg1[i] = arg[i+1]; if (arg1[i] && f_sp!=sp) { casadi_project(arg1[i], sp, w, f_sp, w + f_sp.nnz()); arg1[i] = w; w += f_sp.nnz(); } } } else { // No inputs projected arg1 = arg + 1; } // Temporary memory for results with different sparsity double** res1; if (project_out_) { // Project one or more results res1 = res + n_out_; for (casadi_int i=0; i<n_out_; ++i) { const Sparsity& f_sp = fk.sparsity_out(i); const Sparsity& sp = sparsity_out_[i]; res1[i] = res[i]; if (res1[i] && f_sp!=sp) { res1[i] = w; w += f_sp.nnz(); } } } else { // No outputs projected res1 = res; } // Evaluate the corresponding function if (fk(arg1, res1, iw, w, 0)) return 1; // Project results with different sparsity if (project_out_) { for (casadi_int i=0; i<n_out_; ++i) { const Sparsity& f_sp = fk.sparsity_out(i); const Sparsity& sp = sparsity_out_[i]; if (res[i] && f_sp!=sp) { casadi_project(res1[i], f_sp, res[i], sp, w); } } } return 0; }
/* casadi_impl_ode_jac_xdot:(i0[3],i1[3],i2[4])->(o0[3x3]) */ static int casadi_f0(const casadi_real** arg, casadi_real** res, casadi_int* iw, casadi_real* w, void* mem) { casadi_real *rr, *ss; casadi_real *w0=w+3, *w1=w+6, *w2=w+9; /* #0: @0 = zeros(3x3,3nz) */ casadi_fill(w0, 3, 0.); /* #1: @1 = ones(3x1) */ casadi_fill(w1, 3, 1.); /* #2: (@0[:3] = @1) */ for (rr=w0+0, ss=w1; rr!=w0+3; rr+=1) *rr = *ss++; /* #3: @1 = @0' */ casadi_trans(w0,casadi_s0, w1, casadi_s0, iw); /* #4: @2 = dense(@1) */ casadi_project(w1, casadi_s0, w2, casadi_s1, w); /* #5: output[0][0] = @2 */ casadi_copy(w2, 9, res[0]); return 0; }
int Switch::eval_sx(const SXElem** arg, SXElem** res, casadi_int* iw, SXElem* w, void* mem) const { // Input and output buffers const SXElem** arg1 = arg + n_in_; SXElem** res1 = res + n_out_; // Extra memory needed for chaining if_else calls std::vector<SXElem> w_extra(nnz_out()); std::vector<SXElem*> res_tempv(n_out_); SXElem** res_temp = get_ptr(res_tempv); for (casadi_int k=0; k<f_.size()+1; ++k) { // Local work vector SXElem* wl = w; // Local work vector SXElem* wll = get_ptr(w_extra); if (k==0) { // For the default case, redirect the temporary results to res copy_n(res, n_out_, res_temp); } else { // For the other cases, store the temporary results for (casadi_int i=0; i<n_out_; ++i) { res_temp[i] = wll; wll += nnz_out(i); } } copy_n(arg+1, n_in_-1, arg1); copy_n(res_temp, n_out_, res1); const Function& fk = k==0 ? f_def_ : f_[k-1]; // Project arguments with different sparsity for (casadi_int i=0; i<n_in_-1; ++i) { if (arg1[i]) { const Sparsity& f_sp = fk.sparsity_in(i); const Sparsity& sp = sparsity_in_[i+1]; if (f_sp!=sp) { SXElem *t = wl; wl += f_sp.nnz(); // t is non-const casadi_project(arg1[i], sp, t, f_sp, wl); arg1[i] = t; } } } // Temporary memory for results with different sparsity for (casadi_int i=0; i<n_out_; ++i) { if (res1[i]) { const Sparsity& f_sp = fk.sparsity_out(i); const Sparsity& sp = sparsity_out_[i]; if (f_sp!=sp) { res1[i] = wl; wl += f_sp.nnz();} } } // Evaluate the corresponding function if (fk(arg1, res1, iw, wl, 0)) return 1; // Project results with different sparsity for (casadi_int i=0; i<n_out_; ++i) { if (res1[i]) { const Sparsity& f_sp = fk.sparsity_out(i); const Sparsity& sp = sparsity_out_[i]; if (f_sp!=sp) casadi_project(res1[i], f_sp, res_temp[i], sp, wl); } } if (k>0) { // output the temporary results via an if_else SXElem cond = k-1==arg[0][0]; for (casadi_int i=0; i<n_out_; ++i) { if (res[i]) { for (casadi_int j=0; j<nnz_out(i); ++j) { res[i][j] = if_else(cond, res_temp[i][j], res[i][j]); } } } } } return 0; }
void Project::evalGen(const T** arg, T** res, int* iw, T* w) { casadi_project(arg[0], dep().sparsity(), res[0], sparsity(), w); }