Esempio n. 1
0
  void SnoptInterface::solve(void* mem) const {
    auto m = static_cast<SnoptMemory*>(mem);

    // Check the provided inputs
    checkInputs(mem);

    m->fstats.at("mainloop").tic();

    // Memory object
    snProblem prob;

    // Evaluate gradF and jacG at initial value
    const double** arg = m->arg;
    *arg++ = m->x0;
    *arg++ = m->p;
    double** res = m->res;
    *res++ = 0;
    *res++ = m->jac_gk;
    calc_function(m, "nlp_jac_g");
    res = m->res;
    *res++ = 0;
    *res++ = m->jac_fk;
    calc_function(m, "nlp_jac_f");

    // perform the mapping:
    // populate A_data_ (the nonzeros of A)
    // with numbers pulled from jacG and gradF
    for (int k = 0; k < A_structure_.nnz(); ++k) {
      int i = A_structure_.nonzeros()[k];
      if (i == 0) {
        m->A_data[k] = 0;
      } else if (i > 0) {
        m->A_data[k] = m->jac_gk[i-1];
      } else {
        m->A_data[k] = m->jac_fk[-i-1];
      }
    }

    int n = nx_;
    int nea = A_structure_.nnz();
    double ObjAdd = 0;

    casadi_assert(m_ > 0);
    casadi_assert(n > 0);
    casadi_assert(nea > 0);
    casadi_assert(A_structure_.nnz() == nea);

    // Pointer magic, courtesy of Greg
    casadi_assert_message(!jac_f_fcn_.is_null(), "blaasssshc");

    // Outputs
    //double Obj = 0; // TODO(Greg): get this from snopt

    // snInit must be called first.
    //   9, 6 are print and summary unit numbers (for Fortran).
    //   6 == standard out
    int iprint = 9;
    int isumm = 6;
    std::string outname = name_ + ".out";
    snInit(&prob, const_cast<char*>(name_.c_str()),
           const_cast<char*>(outname.c_str()), iprint, isumm);

    // Set the problem size and other data.
    // This will allocate arrays inside snProblem struct.
    setProblemSize(&prob, m_, nx_, nea, nnCon_, nnJac_, nnObj_);
    setObjective(&prob, iObj_, ObjAdd);
    setUserfun(&prob, userfunPtr);

    // user data
    prob.leniu = 1;
    prob.iu = &m->memind;

    // Pass bounds
    casadi_copy(m->lbx, nx_, prob.bl);
    casadi_copy(m->ubx, nx_, prob.bu);
    casadi_copy(m->lbg, ng_, prob.bl + nx_);
    casadi_copy(m->ubg, ng_, prob.bu + nx_);

    // Initialize states and slack
    casadi_fill(prob.hs, ng_ + nx_, 0);
    casadi_copy(m->x0, nx_, prob.x);
    casadi_fill(prob.x + nx_, ng_, 0.);

    // Initialize multipliers
    casadi_copy(m->lam_g0, ng_, prob.pi);

    // Set up Jacobian matrix
    casadi_copy(A_structure_.colind(), A_structure_.size2()+1, prob.locJ);
    casadi_copy(A_structure_.row(), A_structure_.nnz(), prob.indJ);
    casadi_copy(get_ptr(m->A_data), A_structure_.nnz(), prob.valJ);

    for (auto&& op : opts_) {
      // Replace underscores with spaces
      std::string opname = op.first;
      std::replace(opname.begin(), opname.end(), '_', ' ');

      // Try integer
      if (op.second.can_cast_to(OT_INT)) {
        casadi_assert(opname.size() <= 55);
        int flag = setIntParameter(&prob, const_cast<char*>(opname.c_str()),
                                   op.second.to_int());
        if (flag==0) continue;
      }

      // Try double
      if (op.second.can_cast_to(OT_DOUBLE)) {
        casadi_assert(opname.size() <= 55);
        int flag = setRealParameter(&prob, const_cast<char*>(opname.c_str()),
                                    op.second.to_double());
        if (flag==0) continue;
      }

      // try string
      if (op.second.can_cast_to(OT_STRING)) {
        std::string buffer = opname + " " + op.second.to_string();
        casadi_assert(buffer.size() <= 72);
        int flag = setParameter(&prob, const_cast<char*>(buffer.c_str()));
        if (flag==0) continue;
      }

      // Error if reached this point
      casadi_error("SNOPT error setting option \"" + opname + "\"");
    }

    m->fstats.at("mainloop").toc();

    // Run SNOPT
    int info = solveC(&prob, Cold_, &m->fk);
    casadi_assert_message(99 != info, "snopt problem set up improperly");

    // Negate rc to match CasADi's definition
    casadi_scal(nx_ + ng_, -1., prob.rc);

    // Get primal solution
    casadi_copy(prob.x, nx_, m->x);

    // Get dual solution
    casadi_copy(prob.rc, nx_, m->lam_x);
    casadi_copy(prob.rc+nx_, ng_, m->lam_g);

    // Copy optimal cost to output
    if (m->f) *m->f = m->fk;

    // Copy optimal constraint values to output
    casadi_copy(m->gk, ng_, m->g);

    // Free memory
    deleteSNOPT(&prob);
  }
Esempio n. 2
0
int main( int argc , char* argv[] )
{
  snProblem toy;

  int    i, info;
  int    Cold   =  0;
  int    n      =  2;
  int    m      =  3;
  int    ne     =  5;
  int    nnCon  =  2;
  int    nnObj  =  0;
  int    nnJac  =  2;
  int    iObj   =  2;
  double ObjAdd =  0;
  double objective;

  // snInit must be called first.
  //   9, 6 are print and summary unit numbers (for Fortran).
  //   6 == standard out
  snInit ( &toy, "ToyB", "ToyB.out", 9, 6 );

  // Set the problem size and other data.
  // This will allocate arrays inside snProblem struct.
  setProblemSize ( &toy, m, n, ne, nnCon, nnJac, nnObj );
  setObjective   ( &toy, iObj, ObjAdd );
  setFuncon      ( &toy, (snConB) toycon );
  setFunobj      ( &toy, (snObjB) toyobj );

  // User workspace allocated and set.
  //   May be accesed in the user-defined function toyusrfun.
  toy.leniu = 2;
  toy.iu = (int*)malloc( sizeof(int) * toy.leniu );
  toy.iu[0] = 0;
  toy.iu[1] = 1;


  // Set bounds
  toy.bl[0] =     0;  toy.bu[0] = 1e20;
  toy.bl[1] = -1e20;  toy.bu[1] = 1e20;
  toy.bl[2] = -1e20;  toy.bu[2] =    4;
  toy.bl[3] = -1e20;  toy.bu[3] =    5;
  toy.bl[4] = -1e20;  toy.bu[4] = 1e20;


  // Initialize states, x and multipliers
  for ( i = 0; i < n+m; i++ ) {
    toy.hs[i] = 0;
    toy.x[i]  = 0;
    toy.rc[i] = 0;
  }

  for ( i = 0; i < m; i++ ) {
    toy.pi[i] = 0;
  }

  toy.x[0] = 1.0;
  toy.x[1] = 1.0;

  // Set up the Jacobian matrix
  // Column 1
  toy.locJ[0] = 0;

  toy.indJ[0] = 0;
  toy.valJ[0] = 0;

  toy.indJ[1] = 1;
  toy.valJ[1] = 0;

  // Column 2
  toy.locJ[1] = 2;

  toy.indJ[2] = 0;
  toy.valJ[2] = 0;

  toy.indJ[3] = 1;
  toy.valJ[3] = 0;

  toy.indJ[4] = 2;
  toy.valJ[4] = 1;

  toy.locJ[2] = 5;

  // Read options, set options.
  info = setSpecsfile   ( &toy, "sntoy.spc" );
  setIntParameter( &toy, "Verify level", 3 );
  setIntParameter( &toy, "Derivative option", 3 );

  info = solveB( &toy, Cold, &objective );

  // Deallocate space.
  free ( toy.iu );
  deleteSNOPT ( &toy );

  return 0;
}