示例#1
0
void primitive(double *hold)
{
	switch (token_type)
	{
	case VARIABLE:
		*hold = find_var(token);
		get_token();
		return;
	case NUMBER:
    //
		*hold = atof((token));
    //if (sscanf(token, "%lf", hold) != 1)
	*hold = convert(token);
	if (convert_error == ERROR)
      serror( ERR_BADNUMER);
		get_token();
		return;
	case FUNCTION:
		calc_function( hold);
		if (*token != ')')
			serror(ERR_NOBRACKET);
		get_token();
		return;
	default:	// error
		return;
	}
}
示例#2
0
void recalculate_and_draw(Coordinate_system *cs, char expr[], char number_of_derivatives, float step, bool clear_all)
{
	calc_function(cs, expr, number_of_derivatives, 0.001);
	if(clear_all)
		draw_empty_chart(cs->get_axis_coord('x'), cs->get_axis_coord('y'), GRAPH_WIDHT, GRAPH_HEIGHT, cs->get_scale_of_axis('x'), cs->get_scale_of_axis('y'));
	draw_function(cs, expr, number_of_derivatives);
}
示例#3
0
  int WorhpInterface::solve(void* mem) const {
    auto m = static_cast<WorhpMemory*>(mem);

    if (m->lbg && m->ubg) {
      for (casadi_int i=0; i<ng_; ++i) {
        casadi_assert(!(m->lbg[i]==-inf && m->ubg[i] == inf),
                        "WorhpInterface::evaluate: Worhp cannot handle the case when both "
                        "LBG and UBG are infinite."
                        "You have that case at non-zero " + str(i)+ "."
                        "Reformulate your problem eliminating the corresponding constraint.");
      }
    }

    // Pass inputs to WORHP data structures
    casadi_copy(m->x, nx_, m->worhp_o.X);
    casadi_copy(m->lbx, nx_, m->worhp_o.XL);
    casadi_copy(m->ubx, nx_, m->worhp_o.XU);
    casadi_copy(m->lam_x, nx_, m->worhp_o.Lambda);
    if (m->worhp_o.m>0) {
      casadi_copy(m->lam_g, ng_, m->worhp_o.Mu);
      casadi_copy(m->lbg, ng_, m->worhp_o.GL);
      casadi_copy(m->ubg, ng_, m->worhp_o.GU);
    }

    // Replace infinite bounds with m->worhp_p.Infty
    double inf = numeric_limits<double>::infinity();
    for (casadi_int i=0; i<nx_; ++i)
      if (m->worhp_o.XL[i]==-inf) m->worhp_o.XL[i] = -m->worhp_p.Infty;
    for (casadi_int i=0; i<nx_; ++i)
      if (m->worhp_o.XU[i]== inf) m->worhp_o.XU[i] =  m->worhp_p.Infty;
    for (casadi_int i=0; i<ng_; ++i)
      if (m->worhp_o.GL[i]==-inf) m->worhp_o.GL[i] = -m->worhp_p.Infty;
    for (casadi_int i=0; i<ng_; ++i)
      if (m->worhp_o.GU[i]== inf) m->worhp_o.GU[i] =  m->worhp_p.Infty;

    if (verbose_) casadi_message("WorhpInterface::starting iteration");

    bool firstIteration = true;

    // Reverse Communication loop
    while (m->worhp_c.status < TerminateSuccess &&  m->worhp_c.status > TerminateError) {
      if (GetUserAction(&m->worhp_c, callWorhp)) {
        Worhp(&m->worhp_o, &m->worhp_w, &m->worhp_p, &m->worhp_c);
      }


      if (GetUserAction(&m->worhp_c, iterOutput)) {

        if (!firstIteration) {
          firstIteration = true;

          if (!fcallback_.is_null()) {
            m->iter = m->worhp_w.MajorIter;
            m->iter_sqp = m->worhp_w.MinorIter;
            m->inf_pr = m->worhp_w.NormMax_CV;
            m->inf_du = m->worhp_p.ScaledKKT;
            m->alpha_pr = m->worhp_w.ArmijoAlpha;

            // Inputs
            fill_n(m->arg, fcallback_.n_in(), nullptr);
            m->arg[NLPSOL_X] = m->worhp_o.X;
            m->arg[NLPSOL_F] = &m->worhp_o.F;
            m->arg[NLPSOL_G] = m->worhp_o.G;
            m->arg[NLPSOL_LAM_P] = nullptr;
            m->arg[NLPSOL_LAM_X] = m->worhp_o.Lambda;
            m->arg[NLPSOL_LAM_G] = m->worhp_o.Mu;

            // Outputs
            fill_n(m->res, fcallback_.n_out(), nullptr);
            double ret_double;
            m->res[0] = &ret_double;

            m->fstats.at("callback_fun").tic();
            // Evaluate the callback function
            fcallback_(m->arg, m->res, m->iw, m->w, 0);
            m->fstats.at("callback_fun").toc();
            casadi_int ret = static_cast<casadi_int>(ret_double);

            if (ret) m->worhp_c.status = TerminateError;
          }
        }


        IterationOutput(&m->worhp_o, &m->worhp_w, &m->worhp_p, &m->worhp_c);
        DoneUserAction(&m->worhp_c, iterOutput);
      }

      if (GetUserAction(&m->worhp_c, evalF)) {
        m->arg[0] = m->worhp_o.X;
        m->arg[1] = m->p;
        m->res[0] = &m->worhp_o.F;
        calc_function(m, "nlp_f");
        m->f = m->worhp_o.F; // Store cost, before scaling
        m->worhp_o.F *= m->worhp_w.ScaleObj;
        DoneUserAction(&m->worhp_c, evalF);
      }

      if (GetUserAction(&m->worhp_c, evalG)) {
        m->arg[0] = m->worhp_o.X;
        m->arg[1] = m->p;
        m->res[0] = m->worhp_o.G;
        calc_function(m, "nlp_g");
        DoneUserAction(&m->worhp_c, evalG);
      }

      if (GetUserAction(&m->worhp_c, evalDF)) {
        m->arg[0] = m->worhp_o.X;
        m->arg[1] = m->p;
        m->res[0] = nullptr;
        m->res[1] = m->worhp_w.DF.val;
        calc_function(m, "nlp_grad_f");
        casadi_scal(nx_, m->worhp_w.ScaleObj, m->worhp_w.DF.val);
        DoneUserAction(&m->worhp_c, evalDF);
      }

      if (GetUserAction(&m->worhp_c, evalDG)) {
        m->arg[0] = m->worhp_o.X;
        m->arg[1] = m->p;
        m->res[0] = nullptr;
        m->res[1] = m->worhp_w.DG.val;
        calc_function(m, "nlp_jac_g");
        DoneUserAction(&m->worhp_c, evalDG);
      }

      if (GetUserAction(&m->worhp_c, evalHM)) {
        m->arg[0] = m->worhp_o.X;
        m->arg[1] = m->p;
        m->arg[2] = &m->worhp_w.ScaleObj;
        m->arg[3] = m->worhp_o.Mu;
        m->res[0] = m->worhp_w.HM.val;
        calc_function(m, "nlp_hess_l");
        // Diagonal values
        double *dval = m->w;
        casadi_fill(dval, nx_, 0.);

        // Remove diagonal
        const casadi_int* colind = hesslag_sp_.colind();
        const casadi_int* row = hesslag_sp_.row();
        casadi_int ind=0;
        for (casadi_int c=0; c<nx_; ++c) {
          for (casadi_int el=colind[c]; el<colind[c+1]; ++el) {
            if (row[el]==c) {
              dval[c] = m->worhp_w.HM.val[el];
            } else {
              m->worhp_w.HM.val[ind++] = m->worhp_w.HM.val[el];
            }
          }
        }

        // Add diagonal entries at the end
        casadi_copy(dval, nx_, m->worhp_w.HM.val+ind);
        DoneUserAction(&m->worhp_c, evalHM);
      }

      if (GetUserAction(&m->worhp_c, fidif)) {
        WorhpFidif(&m->worhp_o, &m->worhp_w, &m->worhp_p, &m->worhp_c);
      }
    }

    // Copy outputs
    casadi_copy(m->worhp_o.X, nx_, m->x);
    casadi_copy(m->worhp_o.G, ng_, m->g);
    casadi_copy(m->worhp_o.Lambda, nx_, m->lam_x);
    casadi_copy(m->worhp_o.Mu, ng_, m->lam_g);

    StatusMsg(&m->worhp_o, &m->worhp_w, &m->worhp_p, &m->worhp_c);

    m->return_code = m->worhp_c.status;
    m->return_status = return_codes(m->worhp_c.status);
    m->success = m->return_code > TerminateSuccess;
    return 0;
  }
示例#4
0
  void SnoptInterface::
  userfun(SnoptMemory* m, int* mode, int nnObj, int nnCon, int nnJac, int nnL, int neJac,
          double* x, double* fObj, double*gObj, double* fCon, double* gCon,
          int nState, char* cu, int lencu, int* iu, int leniu, double* ru,
          int lenru) const {
    try {

      casadi_assert_message(nnCon_ == nnCon, "Con " << nnCon_ << " <-> " << nnCon);
      casadi_assert_message(nnObj_ == nnObj, "Obj " << nnObj_ << " <-> " << nnObj);
      casadi_assert_message(nnJac_ == nnJac, "Jac " << nnJac_ << " <-> " << nnJac);

      // Get reduced decision variables
      casadi_fill(m->xk2, nx_, 0.);
      for (int k = 0; k < nnObj; ++k) m->xk2[k] = x[k];

      // Evaluate gradF with the linear variables put to zero
      const double** arg = m->arg;
      *arg++ = m->xk2;
      *arg++ = m->p;
      double** res = m->res;
      *res++ = fObj;
      *res++ = m->jac_fk;
      calc_function(m, "nlp_jac_f");

      // provide nonlinear part of objective gradient to SNOPT
      for (int k = 0; k < nnObj; ++k) {
        int el = jac_f_fcn_.sparsity_out(1).colind(k);
        if (jac_f_fcn_.sparsity_out(1).colind(k+1) > el) {
          gObj[k] = m->jac_fk[el];
        } else {
          gObj[k] = 0;
        }
      }

      jac_f_fcn_.sparsity_out(1).sanity_check(true);
      jac_f_fcn_.sparsity_out(1).sanity_check(false);

      if (!jac_g_fcn_.is_null()) {
        // Get reduced decision variables
        casadi_fill(m->xk2, nx_, 0.);
        for (int k = 0; k < nnJac; ++k) {
          m->xk2[k] = x[k];
        }

        // Evaluate jacG with the linear variabes put to zero
        const double** arg = m->arg;
        *arg++ = m->xk2;
        *arg++ = m->p;
        double** res = m->res;
        *res++ = m->gk;
        *res++ = m->jac_gk;
        calc_function(m, "nlp_jac_g");

        // provide nonlinear part of constraint jacobian to SNOPT
        int kk = 0;
        for (int j = 0; j < nnJac; ++j) {
          for (int k = A_structure_.colind(j); k < A_structure_.sparsity().colind(j+1); ++k) {
            if (A_structure_.row(k) >= nnCon) break;
            int i = A_structure_.nonzeros()[k];
            if (i > 0) {
              gCon[kk++] = m->jac_gk[i-1];
            }
          }
        }

        casadi_assert(kk == 0 || kk == neJac);

        // provide nonlinear part of objective to SNOPT
        for (int k = 0; k < nnCon; ++k) {
          fCon[k] = m->gk[k];
        }
      }

    } catch(std::exception& ex) {
      userOut<true, PL_WARN>() << "eval_nlp failed: " << ex.what() << std::endl;
      *mode = -1;  // Reduce step size - we've got problems
      return;
    }
  }
示例#5
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);
  }
示例#6
0
  void Newton::solve(void* mem) const {
    auto m = static_cast<NewtonMemory*>(mem);

    // Get the initial guess
    casadi_copy(m->iarg[iin_], n_, m->x);

    // Perform the Newton iterations
    m->iter=0;
    bool success = true;
    while (true) {
      // Break if maximum number of iterations already reached
      if (m->iter >= max_iter_) {
        log("eval", "Max. iterations reached.");
        m->return_status = "max_iteration_reached";
        success = false;
        break;
      }

      // Start a new iteration
      m->iter++;

      // Use x to evaluate J
      copy_n(m->iarg, n_in(), m->arg);
      m->arg[iin_] = m->x;
      m->res[0] = m->jac;
      copy_n(m->ires, n_out(), m->res+1);
      m->res[1+iout_] = m->f;
      calc_function(m, "jac_f_z");

      // Check convergence
      double abstol = 0;
      if (abstol_ != numeric_limits<double>::infinity()) {
        for (int i=0; i<n_; ++i) {
          abstol = max(abstol, fabs(m->f[i]));
        }
        if (abstol <= abstol_) {
          casadi_msg("Converged to acceptable tolerance - abstol: " << abstol_);
          break;
        }
      }

      // Factorize the linear solver with J
      linsol_.factorize(m->jac);
      linsol_.solve(m->f, 1, false);

      // Check convergence again
      double abstolStep=0;
      if (numeric_limits<double>::infinity() != abstolStep_) {
        for (int i=0; i<n_; ++i) {
          abstolStep = max(abstolStep, fabs(m->f[i]));
        }
        if (abstolStep <= abstolStep_) {
          casadi_msg("Converged to acceptable tolerance - abstolStep: " << abstolStep_);
          break;
        }
      }

      if (print_iteration_) {
        // Only print iteration header once in a while
        if (m->iter % 10==0) {
          printIteration(userOut());
        }

        // Print iteration information
        printIteration(userOut(), m->iter, abstol, abstolStep);
      }

      // Update Xk+1 = Xk - J^(-1) F
      casadi_axpy(n_, -1., m->f, m->x);
    }

    // Get the solution
    casadi_copy(m->x, n_, m->ires[iout_]);

    // Store the iteration count
    if (success) m->return_status = "success";

    casadi_msg("Newton::solveNonLinear():end after " << m->iter << " steps");
  }