예제 #1
0
파일: switch.cpp 프로젝트: casadi/casadi
  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;
  }
예제 #2
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;
}
예제 #3
0
파일: switch.cpp 프로젝트: casadi/casadi
  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;
  }
예제 #4
0
파일: project.cpp 프로젝트: BrechtBa/casadi
 void Project::evalGen(const T** arg, T** res, int* iw, T* w) {
   casadi_project(arg[0], dep().sparsity(), res[0], sparsity(), w);
 }