コード例 #1
0
ファイル: sx_tools.cpp プロジェクト: kozatt/casadi
void makeSmooth(SXMatrix &ex, SXMatrix &bvar, SXMatrix &bexpr){
  // Initialize
  SXFunction fcn(SXMatrix(),ex);

  casadi_assert(bexpr.empty());

  // Nodes to be replaced
  std::map<int,SX> replace;

  // Go through all nodes and check if any node is non-smooth
  for(int i=0; i<fcn->algorithm.size(); ++i){

      // Check if we have a step node
      if(fcn->algorithm[i].op == STEP){

        // Get the index of the child
        int ch0 = fcn->algorithm[i].ch[0];

        // Binary variable corresponding to the the switch
        SXMatrix sw;

#if 0 
        // Find out if the switch has already been added
        for(int j=0; j<bexpr.size(); ++j)
          if(bexpr[j].isEqual(algorithm[i]->child0)){
            sw = bvar[j];
            break;
          }
#endif

        if(sw.empty()){ // the switch has not yet been added
          // Get an approriate name of the switch
          std::stringstream name;
          name << "sw_" << bvar.size1();
          sw = SX(name.str());
  
          // Add to list of switches
          bvar << sw;
//        bexpr << algorithm[i]->child0;
        }
        
        // Add to the substition map
        replace[i] = sw[0];
      }
  }
  SXMatrix res;
  fcn->eval(SXMatrix(),res,replace,bexpr);

  for(int i=0; i<bexpr.size(); ++i)
    bexpr[i] = bexpr[i]->dep(0);

  ex = res;

#if 0
  // Make sure that the binding expression is smooth
  bexpr.init(SXMatrix());
  SXMatrix b;
  bexpr.eval_symbolic(SXMatrix(),b,replace,bexpr);
  bexpr = b;
#endif
}
コード例 #2
0
ファイル: sx_tools.cpp プロジェクト: kozatt/casadi
void substituteInPlace(const SXMatrix &v, SXMatrix &vdef, std::vector<SXMatrix>& ex, bool reverse){
  casadi_assert_message(isSymbolic(v),"the variable is not symbolic");
  casadi_assert_message(v.sparsity() == vdef.sparsity(),"the sparsity patterns of the expression and its defining expression do not match");
  if(v.empty()) return; // quick return if nothing to replace

  // Function inputs
  std::vector<SXMatrix> f_in;
  if(!reverse) f_in.push_back(v);

  // Function outputs
  std::vector<SXMatrix> f_out;
  f_out.push_back(vdef);
  f_out.insert(f_out.end(),ex.begin(),ex.end());
    
  // Write the mapping function
  SXFunction f(f_in,f_out);
  f.init();
  
  // Get references to the internal data structures
  const vector<SXAlgEl>& algorithm = f.algorithm();
  vector<SX> work(f.getWorkSize());
  
  // Iterator to the binary operations
  vector<SX>::const_iterator b_it=f->operations_.begin();
  
  // Iterator to stack of constants
  vector<SX>::const_iterator c_it = f->constants_.begin();

  // Iterator to free variables
  vector<SX>::const_iterator p_it = f->free_vars_.begin();
  
  // Evaluate the algorithm
  for(vector<SXAlgEl>::const_iterator it=algorithm.begin(); it<algorithm.end(); ++it){
    switch(it->op){
      case OP_INPUT:
        // reverse is false, substitute out
        work[it->res] = vdef.at(it->arg.i[1]);  
        break;
      case OP_OUTPUT:
        if(it->res==0){
          vdef.at(it->arg.i[1]) = work[it->arg.i[0]];
          if(reverse){
            // Use the new variable henceforth, substitute in
            work[it->arg.i[0]] = v.at(it->arg.i[1]);
          }
        } else {
          // Auxillary output
          ex[it->res-1].at(it->arg.i[1]) = work[it->arg.i[0]];   
        }
        break;
      case OP_CONST:      work[it->res] = *c_it++; break;
      case OP_PARAMETER:  work[it->res] = *p_it++; break;
      default:
      {
        switch(it->op){
          CASADI_MATH_FUN_BUILTIN(work[it->arg.i[0]],work[it->arg.i[1]],work[it->res])
        }
        
        // Avoid creating duplicates
        const int depth = 2; // NOTE: a higher depth could possibly give more savings
        work[it->res].assignIfDuplicate(*b_it++,depth);
      }
    }
  }
}