void CSparseCholeskyInternal::prepare() {

    prepared_ = false;

    // Get a reference to the nonzeros of the linear system
    const vector<double>& linsys_nz = input().data();

    // Make sure that all entries of the linear system are valid
    for (int k=0; k<linsys_nz.size(); ++k) {
      casadi_assert_message(!isnan(linsys_nz[k]), "Nonzero " << k << " is not-a-number");
      casadi_assert_message(!isinf(linsys_nz[k]), "Nonzero " << k << " is infinite");
    }

    if (verbose()) {
      userOut() << "CSparseCholeskyInternal::prepare: numeric factorization" << endl;
      userOut() << "linear system to be factorized = " << endl;
      input(0).printSparse();
    }

    if (L_) cs_nfree(L_);
    L_ = cs_chol(&AT_, S_) ;                 // numeric Cholesky factorization
    if (L_==0) {
      DMatrix temp = input();
      temp.makeSparse();
      if (temp.sparsity().issingular()) {
        stringstream ss;
        ss << "CSparseCholeskyInternal::prepare: factorization failed due "
          "to matrix being singular. Matrix contains numerical zeros which are"
          " structurally non-zero. Promoting these zeros to be structural "
          "zeros, the matrix was found to be structurally rank deficient. "
          "sprank: " << sprank(temp.sparsity()) << " <-> " << temp.size2() << endl;
        if (verbose()) {
          ss << "Sparsity of the linear system: " << endl;
          input(LINSOL_A).sparsity().print(ss); // print detailed
        }
        throw CasadiException(ss.str());
      } else {
        stringstream ss;
        ss << "CSparseCholeskyInternal::prepare: factorization failed, "
            "check if Jacobian is singular" << endl;
        if (verbose()) {
          ss << "Sparsity of the linear system: " << endl;
          input(LINSOL_A).sparsity().print(ss); // print detailed
        }
        throw CasadiException(ss.str());
      }
    }
    casadi_assert(L_!=0);

    prepared_ = true;
  }
Beispiel #2
0
  void CsparseInterface::prepare() {
    double time_start=0;
    if (CasadiOptions::profiling && CasadiOptions::profilingBinary) {
      time_start = getRealTime(); // Start timer
      profileWriteEntry(CasadiOptions::profilingLog, this);
    }
    if (!called_once_) {
      if (verbose()) {
        cout << "CsparseInterface::prepare: symbolic factorization" << endl;
      }

      // ordering and symbolic analysis
      int order = 0; // ordering?
      if (S_) cs_sfree(S_);
      S_ = cs_sqr(order, &A_, 0) ;
    }

    prepared_ = false;
    called_once_ = true;

    // Get a referebce to the nonzeros of the linear system
    const vector<double>& linsys_nz = input().data();

    // Make sure that all entries of the linear system are valid
    for (int k=0; k<linsys_nz.size(); ++k) {
      casadi_assert_message(!isnan(linsys_nz[k]), "Nonzero " << k << " is not-a-number");
      casadi_assert_message(!isinf(linsys_nz[k]), "Nonzero " << k << " is infinite");
    }

    if (verbose()) {
      cout << "CsparseInterface::prepare: numeric factorization" << endl;
      cout << "linear system to be factorized = " << endl;
      input(0).printSparse();
    }

    double tol = 1e-8;

    if (N_) cs_nfree(N_);
    N_ = cs_lu(&A_, S_, tol) ;                 // numeric LU factorization
    if (N_==0) {
      DMatrix temp = input();
      temp.makeSparse();
      if (temp.sparsity().isSingular()) {
        stringstream ss;
        ss << "CsparseInterface::prepare: factorization failed due to matrix"
          " being singular. Matrix contains numerical zeros which are "
            "structurally non-zero. Promoting these zeros to be structural "
            "zeros, the matrix was found to be structurally rank deficient."
            " sprank: " << sprank(temp.sparsity()) << " <-> " << temp.size2() << endl;
        if (verbose()) {
          ss << "Sparsity of the linear system: " << endl;
          input(LINSOL_A).sparsity().print(ss); // print detailed
        }
        throw CasadiException(ss.str());
      } else {
        stringstream ss;
        ss << "CsparseInterface::prepare: factorization failed, check if Jacobian is singular"
           << endl;
        if (verbose()) {
          ss << "Sparsity of the linear system: " << endl;
          input(LINSOL_A).sparsity().print(ss); // print detailed
        }
        throw CasadiException(ss.str());
      }
    }
    casadi_assert(N_!=0);

    prepared_ = true;

    if (CasadiOptions::profiling && CasadiOptions::profilingBinary) {
      double time_stop = getRealTime(); // Stop timer
      profileWriteTime(CasadiOptions::profilingLog, this, 0,
                       time_stop-time_start,
                       time_stop-time_start);
      profileWriteExit(CasadiOptions::profilingLog, this, time_stop-time_start);
    }
  }
  void ImplicitFunctionInternal::init() {

    // Initialize the residual function
    f_.init(false);

    // Which input/output correspond to the root-finding problem?
    iin_ = getOption("implicit_input");
    iout_ = getOption("implicit_output");

    // Get the number of equations and check consistency
    casadi_assert_message(iin_>=0 && iin_<f_.getNumInputs() && f_.getNumInputs()>0,
                          "Implicit input not in range");
    casadi_assert_message(iout_>=0 && iout_<f_.getNumOutputs() && f_.getNumOutputs()>0,
                          "Implicit output not in range");
    casadi_assert_message(f_.output(iout_).isDense() && f_.output(iout_).isVector(),
                          "Residual must be a dense vector");
    casadi_assert_message(f_.input(iin_).isDense() && f_.input(iin_).isVector(),
                          "Unknown must be a dense vector");
    n_ = f_.output(iout_).size();
    casadi_assert_message(n_ == f_.input(iin_).size(),
                          "Dimension mismatch. Input size is "
                          << f_.input(iin_).size()
                          << ", while output size is "
                          << f_.output(iout_).size());

    // Allocate inputs
    setNumInputs(f_.getNumInputs());
    for (int i=0; i<getNumInputs(); ++i) {
      input(i) = f_.input(i);
    }

    // Allocate output
    setNumOutputs(f_.getNumOutputs());
    for (int i=0; i<getNumOutputs(); ++i) {
      output(i) = f_.output(i);
    }

    // Same input and output schemes
    setInputScheme(f_.getInputScheme());
    setOutputScheme(f_.getOutputScheme());

    // Call the base class initializer
    FunctionInternal::init();

    // Generate Jacobian if not provided
    if (jac_.isNull()) jac_ = f_.jacobian(iin_, iout_);
    jac_.init(false);

    // Check for structural singularity in the Jacobian
    casadi_assert_message(
      !jac_.output().sparsity().isSingular(),
      "ImplicitFunctionInternal::init: singularity - the jacobian is structurally rank-deficient. "
      "sprank(J)=" << sprank(jac_.output()) << " (instead of "<< jac_.output().size1() << ")");

    // Get the linear solver creator function
    if (linsol_.isNull()) {
      if (hasSetOption("linear_solver")) {
        std::string linear_solver_name = getOption("linear_solver");

        // Allocate an NLP solver
        linsol_ = LinearSolver(linear_solver_name, jac_.output().sparsity(), 1);

        // Pass options
        if (hasSetOption("linear_solver_options")) {
          const Dictionary& linear_solver_options = getOption("linear_solver_options");
          linsol_.setOption(linear_solver_options);
        }

        // Initialize
        linsol_.init();
      }
    } else {
      // Initialize the linear solver, if provided
      linsol_.init(false);
      casadi_assert(linsol_.input().sparsity()==jac_.output().sparsity());
    }

    // No factorization yet;
    fact_up_to_date_ = false;

    // Constraints
    if (hasSetOption("constraints")) u_c_ = getOption("constraints");

    casadi_assert_message(u_c_.size()==n_ || u_c_.empty(),
                          "Constraint vector if supplied, must be of length n, but got "
                          << u_c_.size() << " and n = " << n_);
  }
void ImplicitFunctionInternal::init(){
  // Initialize the residual function
  if(!f_.isInit()) f_.init();
  
  // Allocate inputs
  setNumInputs(f_.getNumInputs()-1);
  for(int i=0; i<getNumInputs(); ++i){
    input(i) = f_.input(i+1);
  }
  
  // Allocate outputs
  setNumOutputs(f_.getNumOutputs());
  output(0) = f_.input(0);
  for(int i=1; i<getNumOutputs(); ++i){
    output(i) = f_.output(i);
  }

  // Call the base class initializer
  FXInternal::init();

  // Number of equations
  N_ = output().size();

  // Generate Jacobian if not provided
  if(J_.isNull()) J_ = f_.jacobian(0,0);
  J_.init();
  
  casadi_assert_message(J_.output().size1()==J_.output().size2(),"ImplicitFunctionInternal::init: the jacobian must be square but got " << J_.output().dimString());
  
  casadi_assert_message(!isSingular(J_.output().sparsity()),"ImplicitFunctionInternal::init: singularity - the jacobian is structurally rank-deficient. sprank(J)=" << sprank(J_.output()) << " (in stead of "<< J_.output().size1() << ")");
  
  // Get the linear solver creator function
  if(linsol_.isNull() && hasSetOption("linear_solver")){
    linearSolverCreator linear_solver_creator = getOption("linear_solver");
  
    // Allocate an NLP solver
    linsol_ = linear_solver_creator(CRSSparsity());
  
    // Pass options
    if(hasSetOption("linear_solver_options")){
      const Dictionary& linear_solver_options = getOption("linear_solver_options");
      linsol_.setOption(linear_solver_options);
    }
  }
  
  // Initialize the linear solver, if provided
  if(!linsol_.isNull()){
    linsol_.setSparsity(J_.output().sparsity());
    linsol_.init();
  }
    
  // Allocate memory for directional derivatives
  ImplicitFunctionInternal::updateNumSens(false);

}
  void SundialsInterface::init(const Dict& opts) {
    // Call the base class method
    Integrator::init(opts);

    // Default options
    abstol_ = 1e-8;
    reltol_ = 1e-6;
    exact_jacobian_ = true;
    max_num_steps_ = 10000;
    finite_difference_fsens_ = false;
    stop_at_end_ = true;
    use_preconditioner_ = false;
    max_krylov_ = 10;
    string linear_solver_type = "dense";
    string iterative_solver = "gmres";
    string pretype = "none";
    string linear_solver;
    Dict linear_solver_options;
    upper_bandwidth_ = -1;
    lower_bandwidth_ = -1;
    upper_bandwidthB_ = -1;
    lower_bandwidthB_ = -1;
    quad_err_con_ = false;
    interpolation_type_ = "hermite";
    steps_per_checkpoint_ = 20;
    disable_internal_warnings_ = false;
    max_multistep_order_ = 5;

    // Read options
    for (auto&& op : opts) {
      if (op.first=="abstol") {
        abstol_ = op.second;
      } else if (op.first=="reltol") {
        reltol_ = op.second;
      } else if (op.first=="exact_jacobian") {
        exact_jacobian_ = op.second;
      } else if (op.first=="max_num_steps") {
        max_num_steps_ = op.second;
      } else if (op.first=="finite_difference_fsens") {
        finite_difference_fsens_ = op.second;
      } else if (op.first=="stop_at_end") {
        stop_at_end_ = op.second;
      } else if (op.first=="use_preconditioner") {
        use_preconditioner_ = op.second;
      } else if (op.first=="max_krylov") {
        max_krylov_ = op.second;
      } else if (op.first=="linear_solver_type") {
        linear_solver_type = op.second.to_string();
      } else if (op.first=="iterative_solver") {
        iterative_solver = op.second.to_string();
      } else if (op.first=="pretype") {
        pretype = op.second.to_string();
      } else if (op.first=="linear_solver") {
        linear_solver = op.second.to_string();
      } else if (op.first=="linear_solver_options") {
        linear_solver_options = op.second;
      } else if (op.first=="upper_bandwidth") {
        upper_bandwidth_ = op.second;
      } else if (op.first=="lower_bandwidth") {
        lower_bandwidth_ = op.second;
      } else if (op.first=="upper_bandwidthB") {
        upper_bandwidthB_ = op.second;
      } else if (op.first=="lower_bandwidthB") {
        lower_bandwidthB_ = op.second;
      } else if (op.first=="quad_err_con") {
        quad_err_con_ = op.second;
      } else if (op.first=="interpolation_type") {
        interpolation_type_ = op.second.to_string();
      } else if (op.first=="steps_per_checkpoint") {
        steps_per_checkpoint_ = op.second;
      } else if (op.first=="disable_internal_warnings") {
        disable_internal_warnings_ = op.second;
      } else if (op.first=="max_multistep_order") {
        max_multistep_order_ = op.second;
      }
    }

    // Default dependent options
    exact_jacobianB_ = exact_jacobian_;
    fsens_abstol_ = abstol_;
    fsens_reltol_ = reltol_;
    abstolB_ = abstol_;
    reltolB_ = reltol_;
    use_preconditionerB_ = use_preconditioner_;
    max_krylovB_ = max_krylov_;
    std::string linear_solver_typeB = linear_solver_type;
    std::string iterative_solverB = iterative_solver;
    std::string pretypeB = pretype;
    string linear_solverB = linear_solver;
    Dict linear_solver_optionsB = linear_solver_options;

    // Read options again
    for (auto&& op : opts) {
      if (op.first=="exact_jacobianB") {
        exact_jacobianB_ = op.second;
      } else if (op.first=="fsens_abstol") {
        fsens_abstol_ = op.second;
      } else if (op.first=="fsens_reltol") {
        fsens_reltol_ = op.second;
      } else if (op.first=="abstolB") {
        abstolB_ = op.second;
      } else if (op.first=="reltolB") {
        reltolB_ = op.second;
      } else if (op.first=="use_preconditionerB") {
        use_preconditionerB_ = op.second;
      } else if (op.first=="max_krylovB") {
        max_krylovB_ = op.second;
      } else if (op.first=="linear_solver_typeB") {
        linear_solver_typeB = op.second.to_string();
      } else if (op.first=="iterative_solverB") {
        iterative_solverB = op.second.to_string();
      } else if (op.first=="pretypeB") {
        pretypeB = op.second.to_string();
      } else if (op.first=="linear_solverB") {
        linear_solverB = op.second.to_string();
      } else if (op.first=="linear_solver_optionsB") {
        linear_solver_optionsB = op.second;
      }
    }

    // No Jacobian of g if g doesn't exist
    if (g_.is_null()) {
      exact_jacobianB_ = false;
    }

    // Linear solver for forward integration
    if (linear_solver_type=="dense") {
      linsol_f_ = SD_DENSE;
    } else if (linear_solver_type=="banded") {
      linsol_f_ = SD_BANDED;
    } else if (linear_solver_type=="iterative") {
      linsol_f_ = SD_ITERATIVE;

      // Iterative solver
      if (iterative_solver=="gmres") {
        itsol_f_ = SD_GMRES;
      } else if (iterative_solver=="bcgstab") {
        itsol_f_ = SD_BCGSTAB;
      } else if (iterative_solver=="tfqmr") {
        itsol_f_ = SD_TFQMR;
      } else {
        casadi_error("Unknown iterative solver for forward integration: " + iterative_solver);
      }

      // Preconditioning type
      if (pretype=="none") {
        pretype_f_ = PREC_NONE;
      } else if (pretype=="left") {
        pretype_f_ = PREC_LEFT;
      } else if (pretype=="right") {
        pretype_f_ = PREC_RIGHT;
      } else if (pretype=="both") {
        pretype_f_ = PREC_BOTH;
      } else {
        casadi_error("Unknown preconditioning type for forward integration: " + pretype);
      }
    } else if (linear_solver_type=="user_defined") {
      linsol_f_ = SD_USER_DEFINED;
    } else {
      casadi_error("Unknown linear solver for forward integration: " + linear_solver_type);
    }

    // Linear solver for backward integration
    if (linear_solver_typeB=="dense") {
      linsol_g_ = SD_DENSE;
    } else if (linear_solver_typeB=="banded") {
      linsol_g_ = SD_BANDED;
    } else if (linear_solver_typeB=="iterative") {
      linsol_g_ = SD_ITERATIVE;

      // Iterative solver
      if (iterative_solverB=="gmres") {
        itsol_g_ = SD_GMRES;
      } else if (iterative_solverB=="bcgstab") {
        itsol_g_ = SD_BCGSTAB;
      } else if (iterative_solverB=="tfqmr") {
        itsol_g_ = SD_TFQMR;
      } else {
        casadi_error("Unknown sparse solver for backward integration: " + iterative_solverB);
      }

      // Preconditioning type
      if (pretypeB=="none") {
        pretype_g_ = PREC_NONE;
      } else if (pretypeB=="left") {
        pretype_g_ = PREC_LEFT;
      } else if (pretypeB=="right") {
        pretype_g_ = PREC_RIGHT;
      } else if (pretypeB=="both") {
        pretype_g_ = PREC_BOTH;
      } else {
        casadi_error("Unknown preconditioning type for backward integration: " + pretypeB);
      }
    } else if (linear_solver_typeB=="user_defined") {
      linsol_g_ = SD_USER_DEFINED;
    } else {
      casadi_error("Unknown linear solver for backward integration: " + iterative_solverB);
    }

    // Create a Jacobian if requested
    if (exact_jacobian_) {
      jac_ = getJac();
      alloc(jac_);
      alloc_w(jac_.nnz_out(0), true);
    }

    if (!jac_.is_null()) {
      casadi_assert_message(jac_.size2_out(0)==jac_.size1_out(0),
                            "SundialsInterface::init: the jacobian of the forward problem must "
                            "be square but got " << jac_.sparsity_out(0).dim());

      casadi_assert_message(!jac_.sparsity_out(0).is_singular(),
                            "SundialsInterface::init: singularity - the jacobian of the forward "
                            "problem is structurally rank-deficient. sprank(J)="
                            << sprank(jac_.sparsity_out(0)) << " (in stead of "<< jac_.size2_out(0)
                            << ")");
    }

    // Create a backwards Jacobian if requested
    if (exact_jacobianB_ && !g_.is_null()) jacB_ = getJacB();

    if (!jacB_.is_null()) {
      alloc(jacB_);
      alloc_w(jacB_.nnz_out(0), true);
      casadi_assert_message(jacB_.size2_out(0)==jacB_.size1_out(0),
                            "SundialsInterface::init: the jacobian of the backward problem must be "
                            "square but got " << jacB_.sparsity_out(0).dim());

      casadi_assert_message(!jacB_.sparsity_out(0).is_singular(),
                            "SundialsInterface::init: singularity - the jacobian of the backward"
                            " problem is structurally rank-deficient. sprank(J)="
                            << sprank(jacB_.sparsity_out(0)) << " (instead of "
                            << jacB_.size2_out(0) << ")");
    }

    // Create a linear solver
    if (!linear_solver.empty() && !jac_.is_null()) {
      linsol_ = linsol("linsol", linear_solver, jac_.sparsity_out(0),
                       1, linear_solver_options);
      alloc(linsol_);
    }

    // Create a linear solver
    if (!linear_solverB.empty() && !jacB_.is_null()) {
      linsolB_ = linsol("linsolB", linear_solverB, jacB_.sparsity_out(0),
                        1, linear_solver_optionsB);
      alloc(linsolB_);
    }

    // Allocate temporary memory
    //alloc_w(np_, true); // p_
    //alloc_w(nrp_, true); // rp_
  }