void TripletHelper::FillValuesFromVector(Index dim, const Vector& vector, Number* values) { DBG_ASSERT(dim == vector.Dim()); const DenseVector* dv = dynamic_cast<const DenseVector*>(&vector); if (dv) { if (dv->IsHomogeneous()) { Number scalar = dv->Scalar(); IpBlasDcopy(dim, &scalar, 0, values, 1); } else { const Number* dv_vals = dv->Values(); IpBlasDcopy(dim, dv_vals, 1, values, 1); } return; } const CompoundVector* cv = dynamic_cast<const CompoundVector*>(&vector); if (cv) { Index ncomps = cv->NComps(); Index total_dim = 0; for (Index i=0; i<ncomps; i++) { SmartPtr<const Vector> comp = cv->GetComp(i); Index comp_dim = comp->Dim(); FillValuesFromVector(comp_dim, *comp, values); values += comp_dim; total_dim += comp_dim; } DBG_ASSERT(total_dim == dim); return; } THROW_EXCEPTION(UNKNOWN_VECTOR_TYPE,"Unknown vector type passed to TripletHelper::FillValues"); }
void SymTMatrix::ComputeRowAMaxImpl( Vector& rows_norms, bool init ) const { DBG_ASSERT(initialized_); DenseVector* dense_vec = static_cast<DenseVector*>(&rows_norms); DBG_ASSERT(dynamic_cast<DenseVector*>(&rows_norms)); const Index* irn = Irows(); const Index* jcn = Jcols(); const Number* val = values_; Number* vec_vals = dense_vec->Values(); vec_vals--; const Number zero = 0.; IpBlasDcopy(NRows(), &zero, 0, vec_vals, 1); for( Index i = 0; i < Nonzeros(); i++ ) { const double f = fabs(*val); vec_vals[*irn] = Max(vec_vals[*irn], f); vec_vals[*jcn] = Max(vec_vals[*jcn], f); val++; irn++; jcn++; } }
void SymTMatrix::FillValues( Number* Values ) const { DBG_ASSERT(initialized_); IpBlasDcopy(Nonzeros(), values_, 1, Values, 1); }
void TripletHelper::PutValuesInVector(Index dim, const Number* values, Vector& vector) { DBG_ASSERT(dim == vector.Dim()); DenseVector* dv = dynamic_cast<DenseVector*>(&vector); if (dv) { Number* dv_vals = dv->Values(); IpBlasDcopy(dim, values, 1, dv_vals, 1); return; } CompoundVector* cv = dynamic_cast<CompoundVector*>(&vector); if (cv) { Index ncomps = cv->NComps(); Index total_dim = 0; for (Index i=0; i<ncomps; i++) { SmartPtr<Vector> comp = cv->GetCompNonConst(i); Index comp_dim = comp->Dim(); PutValuesInVector(comp_dim, values, *comp); values += comp_dim; total_dim += comp_dim; } DBG_ASSERT(total_dim == dim); return; } THROW_EXCEPTION(UNKNOWN_VECTOR_TYPE,"Unknown vector type passed to TripletHelper::PutValuesInVector"); }
void TripletHelper::FillValues_(Index n_entries, const SumSymMatrix& matrix, Number* values) { Index total_n_entries = 0; for (Index i=0; i<matrix.NTerms(); i++) { // Fill the values for the individual term Number retFactor = 0.0; SmartPtr<const SymMatrix> retTerm; matrix.GetTerm(i, retFactor, retTerm); Index term_n_entries = GetNumberEntries(*retTerm); total_n_entries += term_n_entries; if (retFactor!=0.0) { FillValues(term_n_entries, *retTerm, values); if (retFactor!=1.) { // Now adjust the values based on the factor IpBlasDscal(term_n_entries, retFactor, values, 1); } } else { const Number zero = 0.; IpBlasDcopy(term_n_entries, &zero, 0, values, 1); } // now shift the values pointer for the next term values += term_n_entries; } DBG_ASSERT(total_n_entries == n_entries); }
void SymTMatrix::SetValues( const Number* Values ) { IpBlasDcopy(Nonzeros(), Values, 1, values_, 1); initialized_ = true; ObjectChanged(); }
void DenseGenMatrix::Copy(const DenseGenMatrix& M) { DBG_ASSERT(NCols()==M.NCols()); DBG_ASSERT(NRows()==M.NRows()); IpBlasDcopy(NCols()*NRows(), M.Values(), 1, values_, 1); initialized_ = true; ObjectChanged(); }
void DenseGenMatrix::FillIdentity(Number factor /*=1.*/) { DBG_ASSERT(NCols()==NRows()); const Number zero = 0.; IpBlasDcopy(NCols()*NRows(), &zero, 0, values_, 1); if (factor!=0.) { for (Index i=0; i<NRows(); i++) { values_[i + i*NRows()] = factor; } } ObjectChanged(); initialized_ = true; }
bool IndexPCalculator::ComputeP() { DBG_START_METH("IndexPCalculator::ComputeP", dbg_verbosity); bool retval = true; // 1. check whether all columns needed by data_A() are in map cols_ - we suppose data_A is IndexSchurData const std::vector<Index>* p2col_idx = dynamic_cast<const IndexSchurData*>(GetRawPtr(data_A()))->GetColIndices(); Index col; Number* col_values = NULL; Index curr_dim, curr_schur_row=0; SmartPtr<const DenseVector> comp_vec; const Number* comp_values; std::map< Index, SmartPtr<PColumn> >::iterator find_it; SmartPtr<IteratesVector> col_vec = IpData().curr()->MakeNewIteratesVector(); SmartPtr<IteratesVector> sol_vec = col_vec->MakeNewIteratesVector(); for (std::vector<Index>::const_iterator col_it=p2col_idx->begin(); col_it!=p2col_idx->end(); ++col_it){ col = *col_it; find_it = cols_.find(col); if (find_it==cols_.end()) { // column is in data_A but not in P-matrix ->create data_A()->GetRow(curr_schur_row, *col_vec); retval = Solver()->Solve(sol_vec, ConstPtr(col_vec)); DBG_ASSERT(retval); /* This part is for displaying norm2(I_z*K^(-1)*I_1) */ DBG_PRINT((dbg_verbosity,"\ncurr_schur_row=%d, ",curr_schur_row)); DBG_PRINT((dbg_verbosity,"norm2(z)=%23.16e\n",sol_vec->x()->Nrm2())); /* end displaying norm2 */ DBG_ASSERT(col_values== NULL); col_values = new Number[nrows_]; curr_dim = 0; for (Index j=0; j<sol_vec->NComps(); ++j) { comp_vec = dynamic_cast<const DenseVector*>(GetRawPtr(sol_vec->GetComp(j))); comp_values = comp_vec->Values(); IpBlasDcopy(comp_vec->Dim(), comp_values, 1, col_values+curr_dim,1); curr_dim += comp_vec->Dim(); } cols_[col] = new PColumn(nrows_, col_values); col_values = NULL; } curr_schur_row++; } return retval; }
ESymSolverStatus IterativePardisoSolverInterface::Solve(const Index* ia, const Index* ja, Index nrhs, double *rhs_vals) { DBG_START_METH("IterativePardisoSolverInterface::Solve",dbg_verbosity); DBG_ASSERT(nrhs==1); if (HaveIpData()) { IpData().TimingStats().LinearSystemBackSolve().Start(); } // Call Pardiso to do the solve for the given right-hand sides ipfint PHASE = 33; ipfint N = dim_; ipfint PERM; // This should not be accessed by Pardiso ipfint NRHS = nrhs; double* X = new double[nrhs*dim_]; double* ORIG_RHS = new double[nrhs*dim_]; ipfint ERROR; // Initialize solution with zero and save right hand side for (int i = 0; i < N; i++) { X[i] = 0; ORIG_RHS[i] = rhs_vals[i]; } // Dump matrix to file if requested Index iter_count = 0; if (HaveIpData()) { iter_count = IpData().iter_count(); } write_iajaa_matrix (N, ia, ja, a_, rhs_vals, iter_count, debug_cnt_); IterativeSolverTerminationTester* tester; int attempts = 0; const int max_attempts = pardiso_max_droptol_corrections_+1; bool is_normal = false; if (IsNull(InexData().normal_x()) && InexData().compute_normal()) { tester = GetRawPtr(normal_tester_); is_normal = true; } else { tester = GetRawPtr(pd_tester_); } global_tester_ptr_ = tester; while (attempts<max_attempts) { bool retval = tester->InitializeSolve(); ASSERT_EXCEPTION(retval, INTERNAL_ABORT, "tester->InitializeSolve(); returned false"); for (int i = 0; i < N; i++) { rhs_vals[i] = ORIG_RHS[i]; } DPARM_[ 8] = 25; // non_improvement in SQMR iteration F77_FUNC(pardiso,PARDISO)(PT_, &MAXFCT_, &MNUM_, &MTYPE_, &PHASE, &N, a_, ia, ja, &PERM, &NRHS, IPARM_, &MSGLVL_, rhs_vals, X, &ERROR, DPARM_); if (ERROR <= -100 && ERROR >= -110) { Jnlst().Printf(J_WARNING, J_LINEAR_ALGEBRA, "Iterative solver in Pardiso did not converge (ERROR = %d)\n", ERROR); Jnlst().Printf(J_WARNING, J_LINEAR_ALGEBRA, " Decreasing drop tolerances from DPARM_[ 4] = %e and DPARM_[ 5] = %e ", DPARM_[ 4], DPARM_[ 5]); if (is_normal) { Jnlst().Printf(J_WARNING, J_LINEAR_ALGEBRA, "(normal step)\n"); } else { Jnlst().Printf(J_WARNING, J_LINEAR_ALGEBRA, "(PD step)\n"); } PHASE = 23; DPARM_[ 4] *= decr_factor_; DPARM_[ 5] *= decr_factor_; Jnlst().Printf(J_WARNING, J_LINEAR_ALGEBRA, " to DPARM_[ 4] = %e and DPARM_[ 5] = %e\n", DPARM_[ 4], DPARM_[ 5]); // Copy solution back to y to get intial values for the next iteration attempts++; ERROR = 0; } else { attempts = max_attempts; Index iterations_used = tester->GetSolverIterations(); if (is_normal) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Number of iterations in Pardiso iterative solver for normal step = %d.\n", iterations_used); } else { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Number of iterations in Pardiso iterative solver for PD step = %d.\n", iterations_used); } } tester->Clear(); } if (is_normal) { if (DPARM_[4] < normal_pardiso_iter_dropping_factor_) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Increasing drop tolerances from DPARM_[ 4] = %e and DPARM_[ 5] = %e (normal step\n", DPARM_[ 4], DPARM_[ 5]); } normal_pardiso_iter_dropping_factor_used_ = Min(DPARM_[4]/decr_factor_, normal_pardiso_iter_dropping_factor_); normal_pardiso_iter_dropping_schur_used_ = Min(DPARM_[5]/decr_factor_, normal_pardiso_iter_dropping_schur_); if (DPARM_[4] < normal_pardiso_iter_dropping_factor_) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, " to DPARM_[ 4] = %e and DPARM_[ 5] = %e for next iteration.\n", normal_pardiso_iter_dropping_factor_used_, normal_pardiso_iter_dropping_schur_used_); } } else { if (DPARM_[4] < pardiso_iter_dropping_factor_) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Increasing drop tolerances from DPARM_[ 4] = %e and DPARM_[ 5] = %e (PD step\n", DPARM_[ 4], DPARM_[ 5]); } pardiso_iter_dropping_factor_used_ = Min(DPARM_[4]/decr_factor_, pardiso_iter_dropping_factor_); pardiso_iter_dropping_schur_used_ = Min(DPARM_[5]/decr_factor_, pardiso_iter_dropping_schur_); if (DPARM_[4] < pardiso_iter_dropping_factor_) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, " to DPARM_[ 4] = %e and DPARM_[ 5] = %e for next iteration.\n", pardiso_iter_dropping_factor_used_, pardiso_iter_dropping_schur_used_); } } delete [] X; delete [] ORIG_RHS; if (IPARM_[6] != 0) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Number of iterative refinement steps = %d.\n", IPARM_[6]); if (HaveIpData()) { IpData().Append_info_string("Pi"); } } if (HaveIpData()) { IpData().TimingStats().LinearSystemBackSolve().End(); } if (ERROR!=0 ) { Jnlst().Printf(J_ERROR, J_LINEAR_ALGEBRA, "Error in Pardiso during solve phase. ERROR = %d.\n", ERROR); return SYMSOLVER_FATAL_ERROR; } if (test_result_ == IterativeSolverTerminationTester::MODIFY_HESSIAN) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Termination tester requests modification of Hessian\n"); return SYMSOLVER_WRONG_INERTIA; } #if 0 // FRANK: look at this: if (test_result_ == IterativeSolverTerminationTester::CONTINUE) { if (InexData().compute_normal()) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Termination tester not satisfied!!! Pretend singular\n"); return SYMSOLVER_SINGULAR; } } #endif if (test_result_ == IterativeSolverTerminationTester::TEST_2_SATISFIED) { // Termination Test 2 is satisfied, set the step for the primal // iterates to zero Index nvars = IpData().curr()->x()->Dim() + IpData().curr()->s()->Dim(); const Number zero = 0.; IpBlasDcopy(nvars, &zero, 0, rhs_vals, 1); } return SYMSOLVER_SUCCESS; }
ESymSolverStatus IterativeWsmpSolverInterface::Solve( const Index* ia, const Index* ja, Index nrhs, double *rhs_vals) { DBG_START_METH("IterativeWsmpSolverInterface::Solve",dbg_verbosity); if (HaveIpData()) { IpData().TimingStats().LinearSystemBackSolve().Start(); } // Call WISMP to solve for some right hand sides. The solution // will be stored in rhs_vals, and we need to make a copy of the // original right hand side before the call. ipfint N = dim_; ipfint LDB = dim_; double* RHS = new double[dim_*nrhs]; IpBlasDcopy(dim_*nrhs, rhs_vals, 1, RHS, 1); ipfint LDX = dim_; // Q: Do we have to zero out solution? ipfint NRHS = nrhs; IPARM_[1] = 4; // Iterative solver solution IPARM_[2] = 4; double* CVGH = NULL; if (Jnlst().ProduceOutput(J_MOREDETAILED, J_LINEAR_ALGEBRA)) { IPARM_[26] = 1; // Record convergence history CVGH = new double[IPARM_[5]+1]; } else { IPARM_[26] = 0; } double ddmy; Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "Calling WISMP-4-4 for backsolve at cpu time %10.3f (wall %10.3f).\n", CpuTime(), WallclockTime()); F77_FUNC(wismp,WISMP)(&N, ia, ja, a_, RHS, &LDB, rhs_vals, &LDX, &NRHS, &ddmy, CVGH, IPARM_, DPARM_); Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "Done with WISMP-4-4 for backsolve at cpu time %10.3f (wall %10.3f).\n", CpuTime(), WallclockTime()); if (HaveIpData()) { IpData().TimingStats().LinearSystemBackSolve().End(); } Index ierror = IPARM_[63]; if (ierror!=0) { if (ierror==-102) { Jnlst().Printf(J_ERROR, J_LINEAR_ALGEBRA, "Error: WISMP is not able to allocate sufficient amount of memory during ordering/symbolic factorization.\n"); } else { Jnlst().Printf(J_ERROR, J_LINEAR_ALGEBRA, "Error in WISMP during ordering/symbolic factorization phase.\n Error code is %d.\n", ierror); } return SYMSOLVER_FATAL_ERROR; } Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Number of itertive solver steps in WISMP: %d\n", IPARM_[25]); if (Jnlst().ProduceOutput(J_MOREDETAILED, J_LINEAR_ALGEBRA)) { Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "WISMP congergence history:\n"); for (Index i=0; i<=IPARM_[25]; ++i) { Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, " Resid[%3d] = %13.6e\n", i, CVGH[i]); } delete [] CVGH; } return SYMSOLVER_SUCCESS; }
void AmplTNLP::finalize_solution(SolverReturn status, Index n, const Number* x, const Number* z_L, const Number* z_U, Index m, const Number* g, const Number* lambda, Number obj_value, const IpoptData* ip_data, IpoptCalculatedQuantities* ip_cq) { ASL_pfgh* asl = asl_; if (!x_sol_) { x_sol_ = new Number[n]; } if (!z_L_sol_) { z_L_sol_ = new Number[n]; } if (!z_U_sol_) { z_U_sol_ = new Number[n]; } if (!g_sol_) { g_sol_ = new Number[m]; } if (!lambda_sol_) { lambda_sol_ = new Number[m]; } IpBlasDcopy(n, x, 1, x_sol_, 1); IpBlasDcopy(n, z_L, 1, z_L_sol_, 1); IpBlasDcopy(n, z_U, 1, z_U_sol_, 1); IpBlasDcopy(m, g, 1, g_sol_, 1); IpBlasDcopy(m, lambda, 1, lambda_sol_, 1); obj_sol_ = obj_value; std::string message; if (status == SUCCESS) { message = "Optimal Solution Found"; solve_result_num = 0; } else if (status == MAXITER_EXCEEDED) { message = "Maximum Number of Iterations Exceeded."; solve_result_num = 400; } else if (status == STOP_AT_TINY_STEP) { message = "Search Direction becomes Too Small."; solve_result_num = 500; } else if (status == STOP_AT_ACCEPTABLE_POINT) { message = "Solved To Acceptable Level."; solve_result_num = 1; } else if (status == LOCAL_INFEASIBILITY) { message = "Converged to a locally infeasible point. Problem may be infeasible."; solve_result_num = 200; } else if (status == RESTORATION_FAILURE) { message = "Restoration Phase Failed."; solve_result_num = 501; } else if (status == DIVERGING_ITERATES) { message = "Iterates divering; problem might be unbounded."; solve_result_num = 300; } else { message = "Unknown Error"; solve_result_num = 502; } if (IsValid(suffix_handler_)) { // Modified for warm-start from AMPL. Assign Bound Multipliers as Suffixes suf_rput("ipopt_zL_out", ASL_Sufkind_var, z_L_sol_); suf_rput("ipopt_zU_out", ASL_Sufkind_var, z_U_sol_); } // Write the .sol file message = " \n" PACKAGE_STRING ": " + message; write_solution_file(message.c_str()); }
bool StdStepCalculator::Step(DenseVector& delta_u, IteratesVector& sol) { DBG_START_METH("StdStepCalculator::Step", dbg_verbosity); bool retval = false; SmartPtr<IteratesVector> delta_u_long = IpData().trial()->MakeNewIteratesVector(); ift_data_->TransMultiply(delta_u, *delta_u_long); SmartPtr<IteratesVector> r_s = IpData().trial()->MakeNewIteratesVector(); if (kkt_residuals_) { /* This should be almost zero... */ r_s->Set_x_NonConst(*IpCq().curr_grad_lag_x()->MakeNewCopy()); r_s->Set_s_NonConst(*IpCq().curr_grad_lag_s()->MakeNewCopy()); r_s->Set_y_c_NonConst(*IpCq().curr_c()->MakeNewCopy()); r_s->Set_y_d_NonConst(*IpCq().curr_d_minus_s()->MakeNewCopy()); r_s->Set_z_L_NonConst(*IpCq().curr_compl_x_L()->MakeNewCopy()); r_s->Set_z_U_NonConst(*IpCq().curr_compl_x_U()->MakeNewCopy()); r_s->Set_v_L_NonConst(*IpCq().curr_compl_s_L()->MakeNewCopy()); r_s->Set_v_U_NonConst(*IpCq().curr_compl_s_U()->MakeNewCopy()); r_s->Print(Jnlst(),J_VECTOR,J_USER1,"r_s init"); delta_u.Print(Jnlst(),J_VECTOR,J_USER1,"delta_u init"); DBG_PRINT((dbg_verbosity,"r_s init Nrm2=%23.16e\n", r_s->Asum())); delta_u_long->Axpy(-1.0, *r_s); } backsolver_->Solve(&sol, ConstPtr(delta_u_long)); SmartPtr<IteratesVector> Kr_s; if (Do_Boundcheck()) { Kr_s = sol.MakeNewIteratesVectorCopy(); } sol.Axpy(1.0, *IpData().trial()); if (Do_Boundcheck()) { DBG_PRINT((dbg_verbosity, "Entering boundcheck")); // initialize Index new_du_size =0; Number* new_du_values; std::vector<Index> x_bound_violations_idx; std::vector<Number> x_bound_violations_du; std::vector<Index> delta_u_sort; bool bounds_violated; SmartPtr<DenseVectorSpace> delta_u_space = new DenseVectorSpace(0); SmartPtr<DenseVector> old_delta_u = new DenseVector(GetRawPtr(delta_u_space)); SmartPtr<DenseVector> new_delta_u; bounds_violated = BoundCheck(sol, x_bound_violations_idx, x_bound_violations_du); while (bounds_violated) { Driver()->data_A()->Print(Jnlst(),J_VECTOR,J_USER1,"data_A_init"); Driver()->data_B()->Print(Jnlst(),J_VECTOR,J_USER1,"data_B_init"); // write new schurdata A dynamic_cast<IndexSchurData*>(GetRawPtr(Driver()->data_A_nonconst()))->AddData_List(x_bound_violations_idx, delta_u_sort, new_du_size, 1); // write new schurdata B dynamic_cast<IndexSchurData*>(GetRawPtr(Driver()->data_B_nonconst()))->AddData_List(x_bound_violations_idx, delta_u_sort, new_du_size, 1); Driver()->data_A()->Print(Jnlst(),J_VECTOR,J_USER1,"data_A"); Driver()->data_B()->Print(Jnlst(),J_VECTOR,J_USER1,"data_B"); Driver()->SchurBuild(); Driver()->SchurFactorize(); old_delta_u->Print(Jnlst(),J_VECTOR,J_USER1,"old_delta_u"); delta_u_space = NULL; // delete old delta_u space delta_u_space = new DenseVectorSpace(new_du_size); // create new delta_u space new_delta_u = new DenseVector(GetRawPtr(ConstPtr(delta_u_space))); new_du_values = new_delta_u->Values(); IpBlasDcopy(old_delta_u->Dim(), old_delta_u->Values(), 1, new_du_values, 1); for (UINT i=0; i<x_bound_violations_idx.size(); ++i) { // printf("i=%d, delta_u_sort[i]=%d, x_bound_viol_du[i]=%f\n", i, delta_u_sort[i], x_bound_violations_du[i]); new_du_values[delta_u_sort[i]] = x_bound_violations_du[i]; } SmartPtr<IteratesVector> new_sol = sol.MakeNewIteratesVector(); new_delta_u->Print(Jnlst(),J_VECTOR,J_USER1,"new_delta_u"); // solve with new data_B and delta_u retval = Driver()->SchurSolve(&sol, ConstPtr(delta_u_long), dynamic_cast<Vector*>(GetRawPtr(new_delta_u)), Kr_s); sol.Axpy(1.0, *IpData().trial()); x_bound_violations_idx.clear(); x_bound_violations_du.clear(); delta_u_sort.clear(); bounds_violated = BoundCheck(sol, x_bound_violations_idx, x_bound_violations_du); // copy new vector in old vector ->has to be done becpause otherwise only pointers will be copied and then it makes no sense old_delta_u = new_delta_u->MakeNewDenseVector(); old_delta_u->Copy(*new_delta_u); } } return retval; }