示例#1
0
void casadi_bfgs(const casadi_int* sp_h, T1* h, const T1* dx,
                 const T1* glag, const T1* glag_old, T1* w) {
  // Local variables
  casadi_int nx;
  T1 *yk, *qk, dxBkdx, omega, theta, phi;
  // Dimension
  nx = sp_h[0];
  // Work vectors
  yk = w; w += nx;
  qk = w; w += nx;
  // yk = glag - glag_old
  casadi_copy(glag, nx, yk);
  casadi_axpy(nx, -1., glag_old, yk);
  // qk = H*dx
  casadi_fill(qk, nx, 0.);
  casadi_mv(h, sp_h, dx, qk, 0);
  // Calculating theta
  dxBkdx = casadi_dot(nx, dx, qk);
  // C-REPLACE "if_else" "casadi_if_else"
  omega = if_else(casadi_dot(nx, yk, dx) < 0.2 * casadi_dot(nx, dx, qk),
                  0.8 * dxBkdx / (dxBkdx - casadi_dot(nx, dx, yk)), 1);
  // yk = omega * yk + (1 - omega) * qk;
  casadi_scal(nx, omega, yk);
  casadi_axpy(nx, 1 - omega, qk, yk);
  theta = 1. / casadi_dot(nx, dx, yk);
  phi = 1. / casadi_dot(nx, qk, dx);
  // Update H
  casadi_rank1(h, sp_h, theta, yk, yk);
  casadi_rank1(h, sp_h, -phi, qk, qk);
}
示例#2
0
  int IdasInterface::jtimesB(double t, N_Vector xz, N_Vector xzdot, N_Vector xzB,
                                    N_Vector xzdotB, N_Vector resvalB, N_Vector vB, N_Vector JvB,
                                    double cjB, void *user_data,
                                    N_Vector tmp1B, N_Vector tmp2B) {
    try {
      auto m = to_mem(user_data);
      auto& s = m->self;
      m->arg[0] = &t;
      m->arg[1] = NV_DATA_S(xz);
      m->arg[2] = NV_DATA_S(xz)+s.nx_;
      m->arg[3] = m->p;
      m->arg[4] = NV_DATA_S(xzB);
      m->arg[5] = NV_DATA_S(xzB)+s.nrx_;
      m->arg[6] = m->rp;
      m->arg[7] = NV_DATA_S(vB);
      m->arg[8] = NV_DATA_S(vB)+s.nrx_;
      m->res[0] = NV_DATA_S(JvB);
      m->res[1] = NV_DATA_S(JvB) + s.nrx_;
      s.calc_function(m, "jtimesB");

      // Subtract state derivative to get residual
      casadi_axpy(s.nrx_, cjB, NV_DATA_S(vB), NV_DATA_S(JvB));

      return 0;
    } catch(int flag) { // recoverable error
      return flag;
    } catch(exception& e) { // non-recoverable error
      userOut<true, PL_WARN>() << "jtimesB failed: " << e.what() << endl;
      return -1;
    }
  }
示例#3
0
  int IdasInterface::resB(double t, N_Vector xz, N_Vector xzdot, N_Vector rxz,
                                 N_Vector rxzdot, N_Vector rr, void *user_data) {
    try {
      auto m = to_mem(user_data);
      auto& s = m->self;
      m->arg[0] = NV_DATA_S(rxz);
      m->arg[1] = NV_DATA_S(rxz)+s.nrx_;
      m->arg[2] = m->rp;
      m->arg[3] = NV_DATA_S(xz);
      m->arg[4] = NV_DATA_S(xz)+s.nx_;
      m->arg[5] = m->p;
      m->arg[6] = &t;
      m->res[0] = NV_DATA_S(rr);
      m->res[1] = NV_DATA_S(rr)+s.nrx_;
      s.calc_function(m, "daeB");

      // Subtract state derivative to get residual
      casadi_axpy(s.nrx_, 1., NV_DATA_S(rxzdot), NV_DATA_S(rr));

      return 0;
    } catch(int flag) { // recoverable error
      return flag;
    } catch(exception& e) { // non-recoverable error
      userOut<true, PL_WARN>() << "resB failed: " << e.what() << endl;
      return -1;
    }
  }
示例#4
0
  int IdasInterface::psolveB(double t, N_Vector xz, N_Vector xzdot, N_Vector xzB,
                                    N_Vector xzdotB, N_Vector resvalB, N_Vector rvecB,
                                    N_Vector zvecB, double cjB, double deltaB,
                                    void *user_data, N_Vector tmpB) {
    try {
      auto m = to_mem(user_data);
      auto& s = m->self;

      // Get right-hand sides in m->v1, ordered by sensitivity directions
      double* vx = NV_DATA_S(rvecB);
      double* vz = vx + s.nrx_;
      double* v_it = m->v1;
      for (int d=0; d<=s.ns_; ++d) {
        casadi_copy(vx + d*s.nrx1_, s.nrx1_, v_it);
        v_it += s.nrx1_;
        casadi_copy(vz + d*s.nrz1_, s.nrz1_, v_it);
        v_it += s.nrz1_;
      }

      // Solve for undifferentiated right-hand-side, save to output
      s.linsolB_.solve(m->v1, 1);
      vx = NV_DATA_S(zvecB); // possibly different from rvecB
      vz = vx + s.nrx_;
      casadi_copy(m->v1, s.nrx1_, vx);
      casadi_copy(m->v1 + s.nrx1_, s.nrz1_, vz);

      // Sensitivity equations
      if (s.ns_>0) {
        // Second order correction
        if (s.second_order_correction_) {
          // The outputs will double as seeds for jtimesB
          casadi_fill(vx + s.nrx1_, s.nrx_ - s.nrx1_, 0.);
          casadi_fill(vz + s.nrz1_, s.nrz_ - s.nrz1_, 0.);

          // Get second-order-correction, save to m->v2
          m->arg[0] = &t; // t
          m->arg[1] = NV_DATA_S(xz); // x
          m->arg[2] = NV_DATA_S(xz)+s.nx_; // z
          m->arg[3] = m->p; // p
          m->arg[4] = NV_DATA_S(xzB); // rx
          m->arg[5] = NV_DATA_S(xzB)+s.nrx_; // rz
          m->arg[6] = m->rp; // rp
          m->arg[7] = vx; // fwd:rx
          m->arg[8] = vz; // fwd:rz
          m->res[0] = m->v2; // fwd:rode
          m->res[1] = m->v2 + s.nrx_; // fwd:ralg
          s.calc_function(m, "jtimesB");

          // Subtract m->v2 (reordered) from m->v1
          v_it = m->v1 + s.nrx1_ + s.nrz1_;
          for (int d=1; d<=s.ns_; ++d) {
            casadi_axpy(s.nrx1_, -1., m->v2 + d*s.nrx1_, v_it);
            v_it += s.nrx1_;
            casadi_axpy(s.nrz1_, -1., m->v2 + s.nrx_ + d*s.nrz1_, v_it);
            v_it += s.nrz1_;
          }
        }

        // Solve for sensitivity right-hand-sides
        s.linsolB_.solve(m->v1 + s.nrx1_ + s.nrz1_, s.ns_);

        // Save to output, reordered
        v_it = m->v1 + s.nrx1_ + s.nrz1_;
        for (int d=1; d<=s.ns_; ++d) {
          casadi_copy(v_it, s.nrx1_, vx + d*s.nrx1_);
          v_it += s.nrx1_;
          casadi_copy(v_it, s.nrz1_, vz + d*s.nrz1_);
          v_it += s.nrz1_;
        }
      }

      return 0;
    } catch(int flag) { // recoverable error
      return flag;
    } catch(exception& e) { // non-recoverable error
      userOut<true, PL_WARN>() << "psolveB failed: " << e.what() << endl;
      return -1;
    }
  }
示例#5
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");
  }