void InexactLSAcceptor::InitThisLineSearch( bool in_watchdog ) { DBG_START_METH("InexactLSAcceptor::InitThisLineSearch", dbg_verbosity); InexData().set_full_step_accepted(false); // Set the values for the reference point if( !in_watchdog ) { reference_theta_ = IpCq().curr_constraint_violation(); reference_barr_ = IpCq().curr_barrier_obj(); //////////////////// Update the penalty parameter const Number uWu = InexCq().curr_uWu(); SmartPtr<const Vector> tangential_x = InexData().tangential_x(); SmartPtr<const Vector> tangential_s = InexData().tangential_s(); const Number scaled_tangential_norm = InexCq().slack_scaled_norm(*tangential_x, *tangential_s); SmartPtr<const Vector> delta_x = IpData().delta()->x(); SmartPtr<const Vector> delta_s = IpData().delta()->s(); // Get the product of the steps with the Jacobian SmartPtr<Vector> cplusAd_c = IpData().curr()->y_c()->MakeNew(); cplusAd_c->AddTwoVectors(1., *IpCq().curr_jac_c_times_vec(*delta_x), 1., *IpCq().curr_c(), 0.); SmartPtr<Vector> cplusAd_d = delta_s->MakeNew(); cplusAd_d->AddTwoVectors(1., *IpCq().curr_jac_d_times_vec(*delta_x), -1., *delta_s, 0.); cplusAd_d->Axpy(1., *IpCq().curr_d_minus_s()); const Number norm_cplusAd = IpCq().CalcNormOfType(NORM_2, *cplusAd_c, *cplusAd_d); const Number gradBarrTDelta = IpCq().curr_gradBarrTDelta(); bool compute_normal = InexData().compute_normal(); Number Upsilon = -1.; Number Nu = -1.; if( !compute_normal ) { #if 0 // Compute Nu = ||A*u||^2/||A||^2 SmartPtr<const Vector> curr_Au_c = IpCq().curr_jac_c_times_vec(*tangential_x); SmartPtr<Vector> curr_Au_d = delta_s->MakeNew(); curr_Au_d->AddTwoVectors(1., *IpCq().curr_jac_d_times_vec(*tangential_x), -1., *tangential_s, 0.); Number Nu = IpCq().CalcNormOfType(NORM_2, *curr_Au_c, *curr_Au_d); Nu = pow(Nu, 2); Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "nu update: ||A*u||^2 = %23.16e\n", Nu); Number A_norm2 = InexCq().curr_scaled_A_norm2(); Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "nu update: ||A||^2 = %23.16e\n", A_norm2); #endif Nu = 0; //Nu/A_norm2; Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "nu update: Nu = ||A*u||^2/||A||^2 = %23.16e\n", Nu); // Compute Upsilon = ||u||^2 - Nu Upsilon = scaled_tangential_norm - Nu; Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "nu update: Upsilon = ||u||^2 - ||A*u||^2/||A||^2 = %23.16e\n", Upsilon); } DBG_PRINT((1, "gradBarrTDelta = %e norm_cplusAd = %e reference_theta_ = %e\n", gradBarrTDelta, norm_cplusAd, reference_theta_)); // update the upper penalty parameter Number nu_mid = nu_; Number norm_delta_xs = Max(delta_x->Amax(), delta_s->Amax()); last_nu_ = nu_; if( flexible_penalty_function_ ) { last_nu_low_ = nu_low_; } in_tt2_ = false; if( norm_delta_xs == 0. ) { Jnlst().Printf(J_DETAILED, J_LINE_SEARCH, " Zero step, skipping line search\n"); in_tt2_ = true; } // TODO: We need to find a proper cut-off value else if( reference_theta_ > nu_update_inf_skip_tol_ ) { // Different numerator for different algorithms Number numerator; Number denominator; if( !compute_normal ) { numerator = (gradBarrTDelta + Max(0.5 * uWu, tcc_theta_ * Upsilon)); denominator = (1 - rho_) * (reference_theta_ - norm_cplusAd); } else { DBG_PRINT((1, "uWu=%e scaled_tangential_norm=%e\n", uWu , scaled_tangential_norm )); numerator = (gradBarrTDelta + Max(0.5 * uWu, tcc_theta_ * pow(scaled_tangential_norm, 2))); denominator = (1 - rho_) * (reference_theta_ - norm_cplusAd); } const Number nu_trial = numerator / denominator; // Different numerator for different algorithms if( !compute_normal ) { Jnlst().Printf(J_MOREDETAILED, J_LINE_SEARCH, "In penalty parameter update formula:\n gradBarrTDelta = %e 0.5*dWd = %e tcc_theta_*Upsilon = %e numerator = %e\n reference_theta_ = %e norm_cplusAd + %e denominator = %e nu_trial = %e\n", gradBarrTDelta, 0.5 * uWu, tcc_theta_ * Upsilon, numerator, reference_theta_, norm_cplusAd, denominator, nu_trial); } else { Jnlst().Printf(J_MOREDETAILED, J_LINE_SEARCH, "In penalty parameter update formula:\n gradBarrTDelta = %e 0.5*uWu = %e tcc_theta_*pow(scaled_tangential_norm,2) = %e numerator = %e\n reference_theta_ = %e norm_cplusAd + %e denominator = %e nu_trial = %e\n", gradBarrTDelta, 0.5 * uWu, tcc_theta_ * pow(scaled_tangential_norm, 2), numerator, reference_theta_, norm_cplusAd, denominator, nu_trial); } if( nu_ < nu_trial ) { nu_ = nu_trial + nu_inc_; nu_mid = nu_; } if( flexible_penalty_function_ ) { nu_mid = Max(nu_low_, nu_trial); Jnlst().Printf(J_MOREDETAILED, J_LINE_SEARCH, " nu_low = %8.2e\n", nu_low_); } } else { Jnlst().Printf(J_DETAILED, J_LINE_SEARCH, "Warning: Skipping nu update because current constraint violation (%e) less than nu_update_inf_skip_tol.\n", reference_theta_); IpData().Append_info_string("nS"); } InexData().set_curr_nu(nu_); Jnlst().Printf(J_DETAILED, J_LINE_SEARCH, " using nu = %23.16e (nu_mid = %23.16e)\n", nu_, nu_mid); // Compute the linear model reduction prediction DBG_PRINT((1, "gradBarrTDelta=%e reference_theta_=%e norm_cplusAd=%e\n", gradBarrTDelta, reference_theta_, norm_cplusAd)); reference_pred_ = -gradBarrTDelta + nu_mid * (reference_theta_ - norm_cplusAd); watchdog_pred_ = 1e300; } else { reference_theta_ = watchdog_theta_; reference_barr_ = watchdog_barr_; reference_pred_ = watchdog_pred_; } }
ESymSolverStatus WsmpSolverInterface::Factorization( const Index* ia, const Index* ja, bool check_NegEVals, Index numberOfNegEVals) { DBG_START_METH("WsmpSolverInterface::Factorization",dbg_verbosity); // If desired, write out the matrix Index iter_count = -1; if (HaveIpData()) { iter_count = IpData().iter_count(); } if (iter_count == wsmp_write_matrix_iteration_) { matrix_file_number_++; char buf[256]; Snprintf(buf, 255, "wsmp_matrix_%d_%d.dat", iter_count, matrix_file_number_); Jnlst().Printf(J_SUMMARY, J_LINEAR_ALGEBRA, "Writing WSMP matrix into file %s.\n", buf); FILE* fp = fopen(buf, "w"); fprintf(fp, "%d\n", dim_); // N for (Index icol=0; icol<dim_; icol++) { fprintf(fp, "%d", ia[icol+1]-ia[icol]); // number of elements for this column // Now for each colum we write row indices and values for (Index irow=ia[icol]; irow<ia[icol+1]; irow++) { fprintf(fp, " %23.16e %d",a_[irow-1],ja[irow-1]); } fprintf(fp, "\n"); } fclose(fp); } // Check if we have to do the symbolic factorization and ordering // phase yet if (!have_symbolic_factorization_) { ESymSolverStatus retval = InternalSymFact(ia, ja, numberOfNegEVals); if (retval != SYMSOLVER_SUCCESS) { return retval; } have_symbolic_factorization_ = true; } if (HaveIpData()) { IpData().TimingStats().LinearSystemFactorization().Start(); } // Call WSSMP for numerical factorization ipfint N = dim_; ipfint NAUX = 0; IPARM_[1] = 3; // numerical factorization IPARM_[2] = 3; // numerical factorization DPARM_[10] = wsmp_pivtol_; // set current pivot tolerance ipfint idmy; double ddmy; #ifdef PARDISO_MATCHING_PREPROCESS { ipfint* tmp2_ = new ipfint[N]; smat_reordering_pardiso_wsmp_ (&N, ia, ja, a_, ia2, ja2, a2_, perm2, scale2, tmp2_, 1); delete[] tmp2_; } #endif Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "Calling WSSMP-3-3 for numerical factorization at cpu time %10.3f (wall %10.3f).\n", CpuTime(), WallclockTime()); #ifdef PARDISO_MATCHING_PREPROCESS F77_FUNC(wssmp,WSSMP)(&N, ia2, ja2, a2_, &ddmy, PERM_, INVP_, &ddmy, &idmy, #else F77_FUNC(wssmp,WSSMP)(&N, ia, ja, a_, &ddmy, PERM_, INVP_, &ddmy, &idmy, #endif &idmy, &ddmy, &NAUX, MRP_, IPARM_, DPARM_); Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "Done with WSSMP-3-3 for numerical factorization at cpu time %10.3f (wall %10.3f).\n", CpuTime(), WallclockTime()); const Index ierror = IPARM_[63]; if (ierror > 0) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "WSMP detected that the matrix is singular and encountered %d zero pivots.\n", dim_+1-ierror); if (HaveIpData()) { IpData().TimingStats().LinearSystemFactorization().End(); } return SYMSOLVER_SINGULAR; } else if (ierror != 0) { if (ierror == -102) { Jnlst().Printf(J_ERROR, J_LINEAR_ALGEBRA, "Error: WSMP is not able to allocate sufficient amount of memory during factorization.\n"); } else { Jnlst().Printf(J_ERROR, J_LINEAR_ALGEBRA, "Error in WSMP during factorization phase.\n Error code is %d.\n", ierror); } if (HaveIpData()) { IpData().TimingStats().LinearSystemFactorization().End(); } return SYMSOLVER_FATAL_ERROR; } Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Memory usage for WSSMP after factorization IPARM(23) = %d\n", IPARM_[22]); Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Number of nonzeros in WSSMP after factorization IPARM(24) = %d\n", IPARM_[23]); if (factorizations_since_recomputed_ordering_ != -1) { factorizations_since_recomputed_ordering_++; } negevals_ = IPARM_[21]; // Number of negative eigenvalues determined during factorization // Check whether the number of negative eigenvalues matches the requested // count if (check_NegEVals && (numberOfNegEVals!=negevals_)) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Wrong inertia: required are %d, but we got %d.\n", numberOfNegEVals, negevals_); if (skip_inertia_check_) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, " But wsmp_skip_inertia_check is set. Ignore inertia.\n"); IpData().Append_info_string("IC "); negevals_ = numberOfNegEVals; } else { if (HaveIpData()) { IpData().TimingStats().LinearSystemFactorization().End(); } return SYMSOLVER_WRONG_INERTIA; } } if (HaveIpData()) { IpData().TimingStats().LinearSystemFactorization().End(); } return SYMSOLVER_SUCCESS; }
ESymSolverStatus WsmpSolverInterface:: DetermineDependentRows(const Index* ia, const Index* ja, std::list<Index>& c_deps) { DBG_START_METH("WsmpSolverInterface::DetermineDependentRows", dbg_verbosity); c_deps.clear(); ASSERT_EXCEPTION(!wsmp_no_pivoting_, OPTION_INVALID, "WSMP dependency detection does not work without pivoting."); if (!have_symbolic_factorization_) { ESymSolverStatus retval = InternalSymFact(ia, ja, 0); if (retval != SYMSOLVER_SUCCESS) { return retval; } have_symbolic_factorization_ = true; } // Call WSSMP for numerical factorization to detect degenerate // rows/columns ipfint N = dim_; ipfint NAUX = 0; IPARM_[1] = 3; // numerical factorization IPARM_[2] = 3; // numerical factorization DPARM_[10] = wsmp_pivtol_; // set current pivot tolerance ipfint idmy; double ddmy; #ifdef PARDISO_MATCHING_PREPROCESS F77_FUNC(wssmp,WSSMP)(&N, ia2, ja2, a2_, &ddmy, PERM_, INVP_, &ddmy, &idmy, &idmy, &ddmy, &NAUX, MRP_, IPARM_, DPARM_); #else F77_FUNC(wssmp,WSSMP)(&N, ia, ja, a_, &ddmy, PERM_, INVP_, &ddmy, &idmy, &idmy, &ddmy, &NAUX, MRP_, IPARM_, DPARM_); #endif const Index ierror = IPARM_[63]; if (ierror == 0) { int ii = 0; for (int i=0; i<N; i++) { if (MRP_[i] == -1) { c_deps.push_back(i); ii++; } } DBG_ASSERT(ii == IPARM_[20]); } if (ierror > 0) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "WSMP detected that the matrix is singular and encountered %d zero pivots.\n", dim_+1-ierror); if (HaveIpData()) { IpData().TimingStats().LinearSystemFactorization().End(); } return SYMSOLVER_SINGULAR; } else if (ierror != 0) { if (ierror == -102) { Jnlst().Printf(J_ERROR, J_LINEAR_ALGEBRA, "Error: WSMP is not able to allocate sufficient amount of memory during factorization.\n"); } else { Jnlst().Printf(J_ERROR, J_LINEAR_ALGEBRA, "Error in WSMP during factorization phase.\n Error code is %d.\n", ierror); } if (HaveIpData()) { IpData().TimingStats().LinearSystemFactorization().End(); } return SYMSOLVER_FATAL_ERROR; } return SYMSOLVER_SUCCESS; }
ESymSolverStatus Ma27TSolverInterface::Factorization(const Index* airn, const Index* ajcn, bool check_NegEVals, Index numberOfNegEVals) { DBG_START_METH("Ma27TSolverInterface::Factorization",dbg_verbosity); // Check if la should be increased IpData().TimingStats().LinearSystemFactorization().Start(); if (la_increase_) { double* a_old = a_; ipfint la_old = la_; la_ = (ipfint)(meminc_factor_ * (double)(la_)); a_ = new double[la_]; for (Index i=0; i<nonzeros_; i++) { a_[i] = a_old[i]; } delete [] a_old; la_increase_ = false; Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "In Ma27TSolverInterface::Factorization: Increasing la from %d to %d\n", la_old, la_); } // Check if liw should be increased if (liw_increase_) { delete [] iw_; ipfint liw_old = liw_; liw_ = (ipfint)(meminc_factor_ * (double)(liw_)); iw_ = new ipfint[liw_]; liw_increase_ = false; Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "In Ma27TSolverInterface::Factorization: Increasing liw from %d to %d\n", liw_old, liw_); } ipfint iflag; // Information flag ipfint ncmpbr; // Number of double precision compressions ipfint ncmpbi; // Number of integer compressions // Call MA27BD; possibly repeatedly if workspaces are too small ipfint N=dim_; ipfint NZ=nonzeros_; ipfint* IW1 = new ipfint[2*dim_]; ipfint INFO[20]; cntl_[0] = pivtol_; // Set pivot tolerance F77_FUNC(ma27bd,MA27BD)(&N, &NZ, airn, ajcn, a_, &la_, iw_, &liw_, ikeep_, &nsteps_, &maxfrt_, IW1, icntl_, cntl_, INFO); delete [] IW1; // Receive information about the factorization iflag = INFO[0]; // Information flag ipfint ierror = INFO[1]; // Error flag ncmpbr = INFO[11]; // Number of double compressions ncmpbi = INFO[12]; // Number of integer compressions negevals_ = INFO[14]; // Number of negative eigenvalues DBG_PRINT((1,"Return from MA27 iflag = %d and ierror = %d\n", iflag, ierror)); // Check if factorization failed due to insufficient memory space // iflag==-3 if LIW too small (recommended value in ierror) // iflag==-4 if LA too small (recommended value in ierror) if (iflag==-3 || iflag==-4) { // Increase size of both LIW and LA delete [] iw_; delete [] a_; ipfint liw_old = liw_; ipfint la_old = la_; if(iflag==-3) { liw_ = (ipfint)(meminc_factor_ * (double)(ierror)); la_ = (ipfint)(meminc_factor_ * (double)(la_)); } else { liw_ = (ipfint)(meminc_factor_ * (double)(liw_)); la_ = (ipfint)(meminc_factor_ * (double)(ierror)); } iw_ = new ipfint[liw_]; a_ = new double[la_]; Jnlst().Printf(J_WARNING, J_LINEAR_ALGEBRA, "MA27BD returned iflag=%d and requires more memory.\n Increase liw from %d to %d and la from %d to %d and factorize again.\n", iflag, liw_old, liw_, la_old, la_); IpData().TimingStats().LinearSystemFactorization().End(); return SYMSOLVER_CALL_AGAIN; } // Check if the system is singular, and if some other error occurred if (iflag==-5 || iflag==3) { IpData().TimingStats().LinearSystemFactorization().End(); return SYMSOLVER_SINGULAR; } else if (iflag != 0) { // There is some error IpData().TimingStats().LinearSystemFactorization().End(); return SYMSOLVER_FATAL_ERROR; } // Check if it might be more efficient to use more memory next time // (if there were too many compressions for this factorization) if (ncmpbr>=10) { la_increase_ = true; Jnlst().Printf(J_WARNING, J_LINEAR_ALGEBRA, "MA27BD returned ncmpbr=%d. Increase la before the next factorization.\n", ncmpbr); } if (ncmpbi>=10) { liw_increase_ = true; Jnlst().Printf(J_WARNING, J_LINEAR_ALGEBRA, "MA27BD returned ncmpbi=%d. Increase liw before the next factorization.\n", ncmpbr); } // Check whether the number of negative eigenvalues matches the requested // count IpData().TimingStats().LinearSystemFactorization().End(); if (check_NegEVals && (numberOfNegEVals!=negevals_)) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "In Ma27TSolverInterface::Factorization: negevals_ = %d, but numberOfNegEVals = %d\n", negevals_, numberOfNegEVals); return SYMSOLVER_WRONG_INERTIA; } return SYMSOLVER_SUCCESS; }
bool InexactSearchDirCalculator::ComputeSearchDirection() { DBG_START_METH("InexactSearchDirCalculator::ComputeSearchDirection", dbg_verbosity); // First check if the iterates have converged to a locally // infeasible point Number curr_scaled_Ac_norm = InexCq().curr_scaled_Ac_norm(); Jnlst().Printf(J_DETAILED, J_SOLVE_PD_SYSTEM, "curr_scaled_Ac_norm = %e\n", curr_scaled_Ac_norm); Number curr_inf = IpCq().curr_primal_infeasibility(NORM_2); // ToDo work on termination criteria if( curr_scaled_Ac_norm <= local_inf_Ac_tol_ && curr_inf > 1e-4 ) { THROW_EXCEPTION(LOCALLY_INFEASIBLE, "The scaled norm of Ac is satisfying tolerance"); } bool compute_normal = false; switch( decomposition_type_ ) { case ALWAYS: compute_normal = true; break; case ADAPTIVE: compute_normal = InexData().next_compute_normal(); break; case SWITCH_ONCE: compute_normal = InexData().next_compute_normal() || InexData().compute_normal(); break; } SmartPtr<Vector> normal_x; SmartPtr<Vector> normal_s; bool retval; SmartPtr<IteratesVector> delta; SmartPtr<const IteratesVector> curr = IpData().curr(); SmartPtr<IteratesVector> rhs; SmartPtr<Vector> tmp; // Now we set up the primal-dual system for computing the // tangential step and the search direction for the multipliers. // This is taken from IpPDSearchDirCal.cpp (rev 549). // We do not need entries for the variable bound multipliers // Upper part of right-hand-side vector is same for both systems rhs = curr->MakeNewContainer(); tmp = curr->x()->MakeNew(); tmp->AddOneVector(-1., *IpCq().curr_grad_lag_with_damping_x(), 0.); rhs->Set_x(*tmp); tmp = curr->s()->MakeNew(); tmp->AddOneVector(-1., *IpCq().curr_grad_lag_with_damping_s(), 0.); rhs->Set_s(*tmp); tmp = curr->v_L()->MakeNew(); tmp->AddOneVector(-1., *IpCq().curr_relaxed_compl_s_L(), 0.); rhs->Set_v_L(*tmp); tmp = curr->v_U()->MakeNew(); tmp->AddOneVector(-1., *IpCq().curr_relaxed_compl_s_U(), 0.); rhs->Set_v_U(*tmp); // Loop through algorithms bool done = false; while( !done ) { InexData().set_compute_normal(compute_normal); InexData().set_next_compute_normal(compute_normal); if( !compute_normal ) { normal_x = NULL; normal_s = NULL; } else { retval = normal_step_calculator_->ComputeNormalStep(normal_x, normal_s); if( !retval ) { return false; } // output if( Jnlst().ProduceOutput(J_VECTOR, J_SOLVE_PD_SYSTEM) ) { Jnlst().Printf(J_VECTOR, J_SOLVE_PD_SYSTEM, "Normal step (without slack scaling):\n"); normal_x->Print(Jnlst(), J_VECTOR, J_SOLVE_PD_SYSTEM, "normal_x"); normal_s->Print(Jnlst(), J_VECTOR, J_SOLVE_PD_SYSTEM, "normal_s"); } } // Lower part of right-hand-side vector is different for each system if( !compute_normal ) { tmp = curr->y_c()->MakeNew(); tmp->AddOneVector(-1., *IpCq().curr_c(), 0.); rhs->Set_y_c(*tmp); tmp = curr->y_d()->MakeNew(); tmp->AddOneVector(-1., *IpCq().curr_d_minus_s(), 0.); rhs->Set_y_d(*tmp); } else { rhs->Set_y_c(*IpCq().curr_jac_c_times_vec(*normal_x)); tmp = normal_s->MakeNew(); tmp->AddTwoVectors(1., *IpCq().curr_jac_d_times_vec(*normal_x), -1., *normal_s, 0.); rhs->Set_y_d(*tmp); } InexData().set_normal_x(normal_x); InexData().set_normal_s(normal_s); delta = rhs->MakeNewIteratesVector(); retval = inexact_pd_solver_->Solve(*rhs, *delta); // Determine if acceptable step has been computed if( !compute_normal && (!retval || InexData().next_compute_normal()) ) { // If normal step has not been computed and step is not satisfactory, try computing normal step InexData().set_compute_normal(true); compute_normal = true; } else { // If normal step has been computed, stop anyway done = true; } } if( retval ) { // Store the search directions in the IpData object IpData().set_delta(delta); if( InexData().compute_normal() ) { IpData().Append_info_string("NT "); } else { IpData().Append_info_string("PD "); } } return retval; }
bool ProbingMuOracle::CalculateMu( Number mu_min, Number mu_max, Number& new_mu ) { DBG_START_METH("ProbingMuOracle::CalculateMu", dbg_verbosity); ///////////////////////////////////// // Compute the affine scaling step // ///////////////////////////////////// Jnlst().Printf(J_DETAILED, J_BARRIER_UPDATE, "Solving the Primal Dual System for the affine step\n"); // First get the right hand side SmartPtr<IteratesVector> rhs = IpData().curr()->MakeNewContainer(); rhs->Set_x(*IpCq().curr_grad_lag_x()); rhs->Set_s(*IpCq().curr_grad_lag_s()); rhs->Set_y_c(*IpCq().curr_c()); rhs->Set_y_d(*IpCq().curr_d_minus_s()); rhs->Set_z_L(*IpCq().curr_compl_x_L()); rhs->Set_z_U(*IpCq().curr_compl_x_U()); rhs->Set_v_L(*IpCq().curr_compl_s_L()); rhs->Set_v_U(*IpCq().curr_compl_s_U()); // Get space for the affine scaling step SmartPtr<IteratesVector> step = rhs->MakeNewIteratesVector(true); // Now solve the primal-dual system to get the affine step. We // allow a somewhat inexact solution here bool allow_inexact = true; bool retval = pd_solver_->Solve(-1.0, 0.0, *rhs, *step, allow_inexact); if( !retval ) { Jnlst().Printf(J_DETAILED, J_BARRIER_UPDATE, "The linear system could not be solved for the affine step!\n"); return false; } DBG_PRINT_VECTOR(2, "step", *step); ///////////////////////////////////////////////////////////// // Use Mehrotra's formula to compute the barrier parameter // ///////////////////////////////////////////////////////////// // First compute the fraction-to-the-boundary step sizes Number alpha_primal_aff = IpCq().primal_frac_to_the_bound(1.0, *step->x(), *step->s()); Number alpha_dual_aff = IpCq().dual_frac_to_the_bound(1.0, *step->z_L(), *step->z_U(), *step->v_L(), *step->v_U()); Jnlst().Printf(J_DETAILED, J_BARRIER_UPDATE, " The affine maximal step sizes are\n" " alpha_primal_aff = %23.16e\n" " alpha_dual_aff = %23.16e\n", alpha_primal_aff, alpha_dual_aff); // now compute the average complementarity at the affine step // ToDo shoot for mu_min instead of 0? Number mu_aff = CalculateAffineMu(alpha_primal_aff, alpha_dual_aff, *step); Jnlst().Printf(J_DETAILED, J_BARRIER_UPDATE, " The average complementariy at the affine step is %23.16e\n", mu_aff); // get the current average complementarity Number mu_curr = IpCq().curr_avrg_compl(); Jnlst().Printf(J_DETAILED, J_BARRIER_UPDATE, " The average complementariy at the current point is %23.16e\n", mu_curr); DBG_ASSERT(mu_curr > 0.); // Apply Mehrotra's rule Number sigma = pow((mu_aff / mu_curr), 3); // Make sure, sigma is not too large sigma = Min(sigma, sigma_max_); Number mu = sigma * mu_curr; // Store the affine search direction (in case it is needed in the // line search for a corrector step) IpData().set_delta_aff(step); IpData().SetHaveAffineDeltas(true); char ssigma[40]; sprintf(ssigma, " sigma=%8.2e", sigma); IpData().Append_info_string(ssigma); //sprintf(ssigma, " xi=%8.2e ", IpCq().curr_centrality_measure()); //IpData().Append_info_string(ssigma); new_mu = Max(Min(mu, mu_max), mu_min); return true; }
bool PDSearchDirCalculator::ComputeSearchDirection() { DBG_START_METH("PDSearchDirCalculator::ComputeSearchDirection", dbg_verbosity); bool improve_solution = false; if (IpData().HaveDeltas()) { improve_solution = true; } bool retval; if (improve_solution && fast_step_computation_) { retval = true; } else { SmartPtr<IteratesVector> rhs = IpData().curr()->MakeNewContainer(); rhs->Set_x(*IpCq().curr_grad_lag_with_damping_x()); rhs->Set_s(*IpCq().curr_grad_lag_with_damping_s()); rhs->Set_y_c(*IpCq().curr_c()); rhs->Set_y_d(*IpCq().curr_d_minus_s()); Index nbounds = IpNLP().x_L()->Dim()+ IpNLP().x_U()->Dim() + IpNLP().d_L()->Dim()+ IpNLP().d_U()->Dim(); if (nbounds>0 && mehrotra_algorithm_) { // set up the right hand side a la Mehrotra DBG_ASSERT(IpData().HaveAffineDeltas()); DBG_ASSERT(!IpData().HaveDeltas()); const SmartPtr<const IteratesVector> delta_aff = IpData().delta_aff(); SmartPtr<Vector> tmpvec = delta_aff->z_L()->MakeNew(); IpNLP().Px_L()->TransMultVector(1., *delta_aff->x(), 0., *tmpvec); tmpvec->ElementWiseMultiply(*delta_aff->z_L()); tmpvec->Axpy(1., *IpCq().curr_relaxed_compl_x_L()); rhs->Set_z_L(*tmpvec); tmpvec = delta_aff->z_U()->MakeNew(); IpNLP().Px_U()->TransMultVector(-1., *delta_aff->x(), 0., *tmpvec); tmpvec->ElementWiseMultiply(*delta_aff->z_U()); tmpvec->Axpy(1., *IpCq().curr_relaxed_compl_x_U()); rhs->Set_z_U(*tmpvec); tmpvec = delta_aff->v_L()->MakeNew(); IpNLP().Pd_L()->TransMultVector(1., *delta_aff->s(), 0., *tmpvec); tmpvec->ElementWiseMultiply(*delta_aff->v_L()); tmpvec->Axpy(1., *IpCq().curr_relaxed_compl_s_L()); rhs->Set_v_L(*tmpvec); tmpvec = delta_aff->v_U()->MakeNew(); IpNLP().Pd_U()->TransMultVector(-1., *delta_aff->s(), 0., *tmpvec); tmpvec->ElementWiseMultiply(*delta_aff->v_U()); tmpvec->Axpy(1., *IpCq().curr_relaxed_compl_s_U()); rhs->Set_v_U(*tmpvec); } else { rhs->Set_z_L(*IpCq().curr_relaxed_compl_x_L()); rhs->Set_z_U(*IpCq().curr_relaxed_compl_x_U()); rhs->Set_v_L(*IpCq().curr_relaxed_compl_s_L()); rhs->Set_v_U(*IpCq().curr_relaxed_compl_s_U()); } DBG_PRINT_VECTOR(2, "rhs", *rhs); // Get space for the search direction SmartPtr<IteratesVector> delta = IpData().curr()->MakeNewIteratesVector(true); if (improve_solution) { // We can probably avoid copying and scaling... delta->AddOneVector(-1., *IpData().delta(), 0.); } bool& allow_inexact = fast_step_computation_; retval = pd_solver_->Solve(-1.0, 0.0, *rhs, *delta, allow_inexact, improve_solution); if (retval) { // Store the search directions in the IpData object IpData().set_delta(delta); } } return retval; }
bool OptimalityErrorConvergenceCheck::CurrentIsAcceptable() { DBG_START_METH("OptimalityErrorConvergenceCheck::CurrentIsAcceptable", dbg_verbosity); Number overall_error = IpCq().curr_nlp_error(); Number dual_inf = IpCq().unscaled_curr_dual_infeasibility(NORM_MAX); Number constr_viol = IpCq().unscaled_curr_nlp_constraint_violation(NORM_MAX); Number compl_inf = IpCq().unscaled_curr_complementarity(mu_target_, NORM_MAX); if (IpData().iter_count()!=last_obj_val_iter_) { // DELETEME Jnlst().Printf(J_MOREDETAILED, J_MAIN, "obj val update iter = %d\n",IpData().iter_count()); last_obj_val_ = curr_obj_val_; curr_obj_val_ = IpCq().curr_f(); last_obj_val_iter_ = IpData().iter_count(); } DBG_PRINT((1, "overall_error = %e\n", overall_error)); DBG_PRINT((1, "dual_inf = %e\n", dual_inf)); DBG_PRINT((1, "constr_viol = %e\n", constr_viol)); DBG_PRINT((1, "compl_inf = %e\n", compl_inf)); DBG_PRINT((1, "acceptable_tol_ = %e\n", acceptable_tol_)); DBG_PRINT((1, "acceptable_dual_inf_tol_ = %e\n", acceptable_dual_inf_tol_)); DBG_PRINT((1, "acceptable_constr_viol_tol_ = %e\n", acceptable_constr_viol_tol_)); DBG_PRINT((1, "acceptable_compl_inf_tol_ = %e\n", acceptable_compl_inf_tol_)); if (IpData().curr()->x()->Dim()==IpData().curr()->y_c()->Dim()) { // the problem is square, there is no point in looking at dual // infeasibility and complementarity as termination criterion acceptable_dual_inf_tol_ = 1e300; acceptable_compl_inf_tol_ = 1e300; } if (Jnlst().ProduceOutput(J_MOREDETAILED, J_MAIN)) { Jnlst().Printf(J_MOREDETAILED, J_MAIN, "Acceptable Check:\n"); Jnlst().Printf(J_MOREDETAILED, J_MAIN, " overall_error = %23.16e acceptable_tol_ = %23.16e\n", overall_error, acceptable_tol_); Jnlst().Printf(J_MOREDETAILED, J_MAIN, " dual_inf = %23.16e acceptable_dual_inf_tol_ = %23.16e\n", dual_inf, acceptable_dual_inf_tol_); Jnlst().Printf(J_MOREDETAILED, J_MAIN, " constr_viol = %23.16e acceptable_constr_viol_tol_ = %23.16e\n", constr_viol, acceptable_constr_viol_tol_); Jnlst().Printf(J_MOREDETAILED, J_MAIN, " compl_inf = %23.16e acceptable_compl_inf_tol_ = %23.16e\n", compl_inf, acceptable_compl_inf_tol_); Jnlst().Printf(J_MOREDETAILED, J_MAIN, " curr_obj_val_ = %23.16e last_obj_val = %23.16e\n", curr_obj_val_, last_obj_val_); Jnlst().Printf(J_MOREDETAILED, J_MAIN, " fabs(curr_obj_val_-last_obj_val_)/Max(1., fabs(curr_obj_val_)) = %23.16e acceptable_obj_change_tol_ = %23.16e\n", fabs(curr_obj_val_-last_obj_val_)/Max(1., fabs(curr_obj_val_)), acceptable_obj_change_tol_); // DELETEME Jnlst().Printf(J_MOREDETAILED, J_MAIN, "test iter = %d\n",IpData().iter_count()); } return (overall_error <= acceptable_tol_ && dual_inf <= acceptable_dual_inf_tol_ && constr_viol <= acceptable_constr_viol_tol_ && compl_inf <= acceptable_compl_inf_tol_ && fabs(curr_obj_val_-last_obj_val_)/Max(1., fabs(curr_obj_val_)) <= acceptable_obj_change_tol_); }
bool MonotoneMuUpdate::UpdateBarrierParameter() { Number mu = IpData().curr_mu(); Number tau = IpData().curr_tau(); Number sub_problem_error = IpCq().curr_barrier_error(); Jnlst().Printf(J_DETAILED, J_BARRIER_UPDATE, "Optimality Error for Barrier Sub-problem = %e\n", sub_problem_error); Number kappa_eps_mu = barrier_tol_factor_ * mu; bool done = false; bool tiny_step_flag = IpData().tiny_step_flag(); IpData().Set_tiny_step_flag(false); while ((sub_problem_error <= kappa_eps_mu || tiny_step_flag) && !done && !first_iter_resto_) { Jnlst().Printf(J_DETAILED, J_BARRIER_UPDATE, " sub_problem_error < kappa_eps * mu (%e)\n", kappa_eps_mu); // Compute the new values for mu and tau Number new_mu; Number new_tau; Jnlst().Printf(J_DETAILED, J_BARRIER_UPDATE, "Updating mu=%25.16e and tau=%25.16e to ", mu, tau); CalcNewMuAndTau(new_mu, new_tau); Jnlst().Printf(J_DETAILED, J_BARRIER_UPDATE, "new_mu=%25.16e and new_tau=%25.16e\n", new_mu, new_tau); bool mu_changed = (mu != new_mu); if (!mu_changed && tiny_step_flag) { THROW_EXCEPTION(TINY_STEP_DETECTED, "Problem solved to best possible numerical accuracy"); } // Set the new values for mu and tau IpData().Set_mu(new_mu); IpData().Set_tau(new_tau); mu = new_mu; tau = new_tau; // If this is the first iteration or if // mu_allow_fast_monotone_decrease_ is true, we want to check if // we can decrease mu even more if (initialized_ && !mu_allow_fast_monotone_decrease_) { done = true; } else if (!mu_changed) { done = true; } else { sub_problem_error = IpCq().curr_barrier_error(); kappa_eps_mu = barrier_tol_factor_ * mu; done = (sub_problem_error > kappa_eps_mu); } // Reset the line search if (done && mu_changed) { linesearch_->Reset(); } tiny_step_flag = false; } first_iter_resto_ = false; initialized_ = true; return true; }
ESymSolverStatus PardisoSolverInterface::Solve(const Index* ia, const Index* ja, Index nrhs, double *rhs_vals) { DBG_START_METH("PardisoSolverInterface::Solve",dbg_verbosity); 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(); } #ifdef PARDISO_MATCHING_PREPROCESS write_iajaa_matrix (N, ia2, ja2, a2_, rhs_vals, iter_count, debug_cnt_); #else write_iajaa_matrix (N, ia, ja, a_, rhs_vals, iter_count, debug_cnt_); #endif int attempts = 0; const int max_attempts = pardiso_iterative_ ? pardiso_max_droptol_corrections_+1: 1; while (attempts < max_attempts) { #ifdef PARDISO_MATCHING_PREPROCESS for (int i = 0; i < N; i++) { rhs_vals[perm2[i]] = scale2[i] * ORIG_RHS[ i ]; } PARDISO_FUNC(PT_, &MAXFCT_, &MNUM_, &MTYPE_, &PHASE, &N, a2_, ia2, ja2, &PERM, &NRHS, IPARM_, &MSGLVL_, rhs_vals, X, &ERROR, DPARM_); for (int i = 0; i < N; i++) { X[i] = rhs_vals[ perm2[i]]; } for (int i = 0; i < N; i++) { rhs_vals[i] = scale2[i]*X[i]; } #else for (int i = 0; i < N; i++) { rhs_vals[i] = ORIG_RHS[i]; } PARDISO_FUNC(PT_, &MAXFCT_, &MNUM_, &MTYPE_, &PHASE, &N, a_, ia, ja, &PERM, &NRHS, IPARM_, &MSGLVL_, rhs_vals, X, &ERROR, DPARM_); #endif if (ERROR <= -100 && ERROR >= -102) { 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_[41] = %e and DPARM_[44] = %e\n", DPARM_[41], DPARM_[44]); PHASE = 23; DPARM_[4] /= 2.0 ; DPARM_[5] /= 2.0 ; Jnlst().Printf(J_WARNING, J_LINEAR_ALGEBRA, " to DPARM_[41] = %e and DPARM_[44] = %e\n", DPARM_[41], DPARM_[44]); attempts++; ERROR = 0; } else { attempts = max_attempts; // TODO we could try again with some PARDISO parameters changed, i.e., enabling iterative refinement } } 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; } return SYMSOLVER_SUCCESS; }
ConvergenceCheck::ConvergenceStatus OptimalityErrorConvergenceCheck::CheckConvergence(bool call_intermediate_callback /*= true*/) { DBG_START_METH("OptimalityErrorConvergenceCheck::CheckConvergence", dbg_verbosity); if (call_intermediate_callback) { // Check if user requested termination by calling the intermediate // user callback function AlgorithmMode mode = RegularMode; // Gather the information also used in the iteration output Index iter = IpData().iter_count(); Number inf_pr = IpCq().curr_primal_infeasibility(NORM_MAX); Number inf_du = IpCq().curr_dual_infeasibility(NORM_MAX); Number mu = IpData().curr_mu(); Number dnrm; if (IsValid(IpData().delta()) && IsValid(IpData().delta()->x()) && IsValid(IpData().delta()->s())) { dnrm = Max(IpData().delta()->x()->Amax(), IpData().delta()->s()->Amax()); } else { // This is the first iteration - no search direction has been // computed yet. dnrm = 0.; } Number alpha_primal = IpData().info_alpha_primal(); Number alpha_dual = IpData().info_alpha_dual(); Number regu_x = IpData().info_regu_x(); Number unscaled_f = IpCq().unscaled_curr_f(); Index ls_count = IpData().info_ls_count(); bool request_stop = !IpNLP().IntermediateCallBack(mode, iter, unscaled_f, inf_pr, inf_du, mu, dnrm, regu_x, alpha_dual, alpha_primal, ls_count, &IpData(), &IpCq()); if (request_stop) { return ConvergenceCheck::USER_STOP; } } Number overall_error = IpCq().curr_nlp_error(); Number dual_inf = IpCq().unscaled_curr_dual_infeasibility(NORM_MAX); Number constr_viol = IpCq().unscaled_curr_nlp_constraint_violation(NORM_MAX); Number compl_inf = IpCq().unscaled_curr_complementarity(mu_target_, NORM_MAX); if (IpData().curr()->x()->Dim()==IpData().curr()->y_c()->Dim()) { // the problem is square, there is no point in looking at dual // infeasibility and complementarity as termination criterion dual_inf_tol_ = 1e300; compl_inf_tol_ = 1e300; } if (Jnlst().ProduceOutput(J_MOREDETAILED, J_MAIN)) { Jnlst().Printf(J_MOREDETAILED, J_MAIN, "Convergence Check:\n"); Jnlst().Printf(J_MOREDETAILED, J_MAIN, " overall_error = %23.16e IpData().tol() = %23.16e\n", overall_error, IpData().tol()); Jnlst().Printf(J_MOREDETAILED, J_MAIN, " dual_inf = %23.16e dual_inf_tol_ = %23.16e\n", dual_inf, dual_inf_tol_); Jnlst().Printf(J_MOREDETAILED, J_MAIN, " constr_viol = %23.16e constr_viol_tol_ = %23.16e\n", constr_viol, constr_viol_tol_); Jnlst().Printf(J_MOREDETAILED, J_MAIN, " compl_inf = %23.16e compl_inf_tol_ = %23.16e\n", compl_inf, compl_inf_tol_); } if (overall_error <= IpData().tol() && dual_inf <= dual_inf_tol_ && constr_viol <= constr_viol_tol_ && compl_inf <= compl_inf_tol_) { return ConvergenceCheck::CONVERGED; } if (acceptable_iter_>0 && CurrentIsAcceptable()) { IpData().Append_info_string("A"); acceptable_counter_++; if (acceptable_counter_ >= acceptable_iter_) { return ConvergenceCheck::CONVERGED_TO_ACCEPTABLE_POINT; } } else { acceptable_counter_ = 0; } if (IpData().curr()->x()->Amax() > diverging_iterates_tol_) { return ConvergenceCheck::DIVERGING; } if (IpData().iter_count() >= max_iterations_) { return ConvergenceCheck::MAXITER_EXCEEDED; } Number curr_cpu_time = CpuTime(); if (max_cpu_time_ < 999999. && curr_cpu_time - IpData().cpu_time_start() > max_cpu_time_) { return ConvergenceCheck::CPUTIME_EXCEEDED; } return ConvergenceCheck::CONTINUE; }
ESymSolverStatus PardisoSolverInterface::Factorization(const Index* ia, const Index* ja, bool check_NegEVals, Index numberOfNegEVals) { DBG_START_METH("PardisoSolverInterface::Factorization",dbg_verbosity); // Call Pardiso to do the factorization ipfint PHASE ; ipfint N = dim_; ipfint PERM; // This should not be accessed by Pardiso ipfint NRHS = 0; double B; // This should not be accessed by Pardiso in factorization // phase double X; // This should not be accessed by Pardiso in factorization // phase ipfint ERROR; bool done = false; bool just_performed_symbolic_factorization = false; while (!done) { if (!have_symbolic_factorization_) { if (HaveIpData()) { IpData().TimingStats().LinearSystemSymbolicFactorization().Start(); } PHASE = 11; #ifdef PARDISO_MATCHING_PREPROCESS delete[] ia2; ia2 = NULL; delete[] ja2; ja2 = NULL; delete[] a2_; a2_ = NULL; delete[] perm2; perm2 = NULL; delete[] scale2; scale2 = NULL; ia2 = new ipfint[N+1]; ja2 = new ipfint[nonzeros_]; a2_ = new double[nonzeros_]; perm2 = new ipfint[N]; scale2 = new double[N]; ipfint* tmp2_ = new ipfint[N]; smat_reordering_pardiso_wsmp_(&N, ia, ja, a_, ia2, ja2, a2_, perm2, scale2, tmp2_, 0); delete[] tmp2_; #endif Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Calling Pardiso for symbolic factorization.\n"); PARDISO_FUNC(PT_, &MAXFCT_, &MNUM_, &MTYPE_, #ifdef PARDISO_MATCHING_PREPROCESS &PHASE, &N, a2_, ia2, ja2, &PERM, #else &PHASE, &N, a_, ia, ja, &PERM, #endif &NRHS, IPARM_, &MSGLVL_, &B, &X, &ERROR, DPARM_); if (HaveIpData()) { IpData().TimingStats().LinearSystemSymbolicFactorization().End(); } if (ERROR==-7) { Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "Pardiso symbolic factorization returns ERROR = %d. Matrix is singular.\n", ERROR); return SYMSOLVER_SINGULAR; } else if (ERROR!=0) { Jnlst().Printf(J_ERROR, J_LINEAR_ALGEBRA, "Error in Pardiso during symbolic factorization phase. ERROR = %d.\n", ERROR); return SYMSOLVER_FATAL_ERROR; } have_symbolic_factorization_ = true; just_performed_symbolic_factorization = true; Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Memory in KB required for the symbolic factorization = %d.\n", IPARM_[14]); Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Integer memory in KB required for the numerical factorization = %d.\n", IPARM_[15]); Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Double memory in KB required for the numerical factorization = %d.\n", IPARM_[16]); } PHASE = 22; if (HaveIpData()) { IpData().TimingStats().LinearSystemFactorization().Start(); } Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "Calling Pardiso for factorization.\n"); // Dump matrix to file, and count number of solution steps. if (HaveIpData()) { if (IpData().iter_count() != debug_last_iter_) debug_cnt_ = 0; debug_last_iter_ = IpData().iter_count(); debug_cnt_ ++; } else { debug_cnt_ = 0; debug_last_iter_ = 0; } #ifdef PARDISO_MATCHING_PREPROCESS ipfint* tmp3_ = new ipfint[N]; smat_reordering_pardiso_wsmp_ (&N, ia, ja, a_, ia2, ja2, a2_, perm2, scale2, tmp3_, 1); delete[] tmp3_; #endif PARDISO_FUNC(PT_, &MAXFCT_, &MNUM_, &MTYPE_, #ifdef PARDISO_MATCHING_PREPROCESS &PHASE, &N, a2_, ia2, ja2, &PERM, #else &PHASE, &N, a_, ia, ja, &PERM, #endif &NRHS, IPARM_, &MSGLVL_, &B, &X, &ERROR, DPARM_); if (HaveIpData()) { IpData().TimingStats().LinearSystemFactorization().End(); } if (ERROR==-7) { Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "Pardiso factorization returns ERROR = %d. Matrix is singular.\n", ERROR); return SYMSOLVER_SINGULAR; } else if (ERROR==-4) { // I think this means that the matrix is singular // OLAF said that this will never happen (ToDo) return SYMSOLVER_SINGULAR; } else if (ERROR!=0 ) { Jnlst().Printf(J_ERROR, J_LINEAR_ALGEBRA, "Error in Pardiso during factorization phase. ERROR = %d.\n", ERROR); return SYMSOLVER_FATAL_ERROR; } negevals_ = Max(IPARM_[22], numberOfNegEVals); if (IPARM_[13] != 0) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Number of perturbed pivots in factorization phase = %d.\n", IPARM_[13]); if ( !pardiso_redo_symbolic_fact_only_if_inertia_wrong_ || (negevals_ != numberOfNegEVals) ) { if (HaveIpData()) { IpData().Append_info_string("Pn"); } have_symbolic_factorization_ = false; // We assume now that if there was just a symbolic // factorization and we still have perturbed pivots, that // the system is actually singular, if // pardiso_repeated_perturbation_means_singular_ is true if (just_performed_symbolic_factorization) { if (pardiso_repeated_perturbation_means_singular_) { if (HaveIpData()) { IpData().Append_info_string("Ps"); } return SYMSOLVER_SINGULAR; } else { done = true; } } else { done = false; } } else { if (HaveIpData()) { IpData().Append_info_string("Pp"); } done = true; } } else { done = true; } } DBG_ASSERT(IPARM_[21]+IPARM_[22] == dim_); // Check whether the number of negative eigenvalues matches the requested // count if (skip_inertia_check_) numberOfNegEVals=negevals_; if (check_NegEVals && (numberOfNegEVals!=negevals_)) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Wrong inertia: required are %d, but we got %d.\n", numberOfNegEVals, negevals_); return SYMSOLVER_WRONG_INERTIA; } return SYMSOLVER_SUCCESS; }
void RestoIterationOutput::WriteOutput() { // Get pointers to the Original NLP objects const RestoIpoptNLP* resto_ipopt_nlp = static_cast<const RestoIpoptNLP*>(&IpNLP()); DBG_ASSERT(resto_ipopt_nlp); SmartPtr<IpoptData> orig_ip_data = &resto_ipopt_nlp->OrigIpData(); SmartPtr<IpoptNLP> orig_ip_nlp = &resto_ipopt_nlp->OrigIpNLP(); SmartPtr<IpoptCalculatedQuantities> orig_ip_cq = &resto_ipopt_nlp->OrigIpCq(); // Set the iteration counter for the original NLP to the current value Index iter = IpData().iter_count(); orig_ip_data->Set_iter_count(iter); // If a resto_orig_iteration_output object was given, first do the // WriteOutput method with that one if (IsValid(resto_orig_iteration_output_)) { resto_orig_iteration_output_->WriteOutput(); } ////////////////////////////////////////////////////////////////////// // First print the summary line for the iteration // ////////////////////////////////////////////////////////////////////// std::string header = "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n"; Jnlst().Printf(J_DETAILED, J_MAIN, "\n\n**************************************************\n"); Jnlst().Printf(J_DETAILED, J_MAIN, "*** Summary of Iteration %d for original NLP:", IpData().iter_count()); Jnlst().Printf(J_DETAILED, J_MAIN, "\n**************************************************\n\n"); if (IpData().info_iters_since_header() >= 10 && !IsValid(resto_orig_iteration_output_)) { // output the header Jnlst().Printf(J_ITERSUMMARY, J_MAIN, header.c_str()); IpData().Set_info_iters_since_header(0); } else { Jnlst().Printf(J_DETAILED, J_MAIN, header.c_str()); } // For now, just print the total NLP error for the restoration // phase problem in the dual infeasibility column Number inf_du = IpCq().curr_dual_infeasibility(NORM_MAX); Number mu = IpData().curr_mu(); Number dnrm = 0.; if (IsValid(IpData().delta()) && IsValid(IpData().delta()->x()) && IsValid(IpData().delta()->s())) { dnrm = Max(IpData().delta()->x()->Amax(), IpData().delta()->s()->Amax()); } // Set the trial values for the original Data object to the // current restoration phase values SmartPtr<const Vector> x = IpData().curr()->x(); const CompoundVector* cx = static_cast<const CompoundVector*>(GetRawPtr(x)); DBG_ASSERT(dynamic_cast<const CompoundVector*>(GetRawPtr(x))); SmartPtr<const Vector> s = IpData().curr()->s(); const CompoundVector* cs = static_cast<const CompoundVector*>(GetRawPtr(s)); DBG_ASSERT(dynamic_cast<const CompoundVector*>(GetRawPtr(s))); SmartPtr<IteratesVector> trial = orig_ip_data->trial()->MakeNewContainer(); trial->Set_x(*cx->GetComp(0)); trial->Set_s(*cs->GetComp(0)); orig_ip_data->set_trial(trial); // Compute primal infeasibility Number inf_pr = 0.0; switch (inf_pr_output_) { case INTERNAL: inf_pr = orig_ip_cq->trial_primal_infeasibility(NORM_MAX); break; case ORIGINAL: inf_pr = orig_ip_cq->unscaled_trial_nlp_constraint_violation(NORM_MAX); break; } // Compute original objective function Number f = orig_ip_cq->unscaled_trial_f(); // Retrieve some information set in the different parts of the algorithm char info_iter='r'; Number alpha_primal = IpData().info_alpha_primal(); char alpha_primal_char = IpData().info_alpha_primal_char(); Number alpha_dual = IpData().info_alpha_dual(); Number regu_x = IpData().info_regu_x(); char regu_x_buf[8]; char dashes[]=" - "; char *regu_x_ptr; if (regu_x==.0) { regu_x_ptr = dashes; } else { Snprintf(regu_x_buf, 7, "%5.1f", log10(regu_x)); regu_x_ptr = regu_x_buf; } Index ls_count = IpData().info_ls_count(); const std::string info_string = IpData().info_string(); Number current_time = 0.0; Number last_output = IpData().info_last_output(); if ((iter % print_frequency_iter_) == 0 && (print_frequency_time_ == 0.0 || last_output < (current_time = WallclockTime()) - print_frequency_time_ || last_output < 0.0)) { Jnlst().Printf(J_ITERSUMMARY, J_MAIN, "%4d%c%14.7e %7.2e %7.2e %5.1f %7.2e %5s %7.2e %7.2e%c%3d", iter, info_iter, f, inf_pr, inf_du, log10(mu), dnrm, regu_x_ptr, alpha_dual, alpha_primal, alpha_primal_char, ls_count); if (print_info_string_) { Jnlst().Printf(J_ITERSUMMARY, J_MAIN, " %s", info_string.c_str()); } else { Jnlst().Printf(J_DETAILED, J_MAIN, " %s", info_string.c_str()); } Jnlst().Printf(J_ITERSUMMARY, J_MAIN, "\n"); IpData().Set_info_last_output(current_time); IpData().Inc_info_iters_since_header(); } ////////////////////////////////////////////////////////////////////// // Now if desired more detail on the iterates // ////////////////////////////////////////////////////////////////////// if (Jnlst().ProduceOutput(J_DETAILED, J_MAIN)) { Jnlst().Printf(J_DETAILED, J_MAIN, "\n**************************************************\n"); Jnlst().Printf(J_DETAILED, J_MAIN, "*** Beginning Iteration %d from the following point:", IpData().iter_count()); Jnlst().Printf(J_DETAILED, J_MAIN, "\n**************************************************\n\n"); Jnlst().Printf(J_DETAILED, J_MAIN, "Primal infeasibility for restoration phase problem = %.16e\n", IpCq().curr_primal_infeasibility(NORM_MAX)); Jnlst().Printf(J_DETAILED, J_MAIN, "Dual infeasibility for restoration phase problem = %.16e\n", IpCq().curr_dual_infeasibility(NORM_MAX)); Jnlst().Printf(J_DETAILED, J_MAIN, "||curr_x||_inf = %.16e\n", IpData().curr()->x()->Amax()); Jnlst().Printf(J_DETAILED, J_MAIN, "||curr_s||_inf = %.16e\n", IpData().curr()->s()->Amax()); Jnlst().Printf(J_DETAILED, J_MAIN, "||curr_y_c||_inf = %.16e\n", IpData().curr()->y_c()->Amax()); Jnlst().Printf(J_DETAILED, J_MAIN, "||curr_y_d||_inf = %.16e\n", IpData().curr()->y_d()->Amax()); Jnlst().Printf(J_DETAILED, J_MAIN, "||curr_z_L||_inf = %.16e\n", IpData().curr()->z_L()->Amax()); Jnlst().Printf(J_DETAILED, J_MAIN, "||curr_z_U||_inf = %.16e\n", IpData().curr()->z_U()->Amax()); Jnlst().Printf(J_DETAILED, J_MAIN, "||curr_v_L||_inf = %.16e\n", IpData().curr()->v_L()->Amax()); Jnlst().Printf(J_DETAILED, J_MAIN, "||curr_v_U||_inf = %.16e\n", IpData().curr()->v_U()->Amax()); } if (Jnlst().ProduceOutput(J_MOREDETAILED, J_MAIN)) { if (IsValid(IpData().delta())) { Jnlst().Printf(J_MOREDETAILED, J_MAIN, "\n||delta_x||_inf = %.16e\n", IpData().delta()->x()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_MAIN, "||delta_s||_inf = %.16e\n", IpData().delta()->s()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_MAIN, "||delta_y_c||_inf = %.16e\n", IpData().delta()->y_c()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_MAIN, "||delta_y_d||_inf = %.16e\n", IpData().delta()->y_d()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_MAIN, "||delta_z_L||_inf = %.16e\n", IpData().delta()->z_L()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_MAIN, "||delta_z_U||_inf = %.16e\n", IpData().delta()->z_U()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_MAIN, "||delta_v_L||_inf = %.16e\n", IpData().delta()->v_L()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_MAIN, "||delta_v_U||_inf = %.16e\n", IpData().delta()->v_U()->Amax()); } else { Jnlst().Printf(J_MOREDETAILED, J_MAIN, "\nNo search direction has been computed yet.\n"); } } if (Jnlst().ProduceOutput(J_VECTOR, J_MAIN)) { IpData().curr()->x()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_x"); IpData().curr()->s()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_s"); IpData().curr()->y_c()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_y_c"); IpData().curr()->y_d()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_y_d"); IpCq().curr_slack_x_L()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_slack_x_L"); IpCq().curr_slack_x_U()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_slack_x_U"); IpData().curr()->z_L()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_z_L"); IpData().curr()->z_U()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_z_U"); IpCq().curr_slack_s_L()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_slack_s_L"); IpCq().curr_slack_s_U()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_slack_s_U"); IpData().curr()->v_L()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_v_L"); IpData().curr()->v_U()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_v_U"); } if (Jnlst().ProduceOutput(J_MOREVECTOR, J_MAIN)) { IpCq().curr_grad_lag_x()->Print(Jnlst(), J_MOREVECTOR, J_MAIN, "curr_grad_lag_x"); IpCq().curr_grad_lag_s()->Print(Jnlst(), J_MOREVECTOR, J_MAIN, "curr_grad_lag_s"); if (IsValid(IpData().delta())) { IpData().delta()->Print(Jnlst(), J_MOREVECTOR, J_MAIN, "delta"); } } if (Jnlst().ProduceOutput(J_DETAILED, J_MAIN)) { Jnlst().Printf(J_DETAILED, J_MAIN, "\n\n***Current NLP Values for Iteration (Restoration phase problem) %d:\n", IpData().iter_count()); Jnlst().Printf(J_DETAILED, J_MAIN, "\n (scaled) (unscaled)\n"); Jnlst().Printf(J_DETAILED, J_MAIN, "Objective...............: %24.16e %24.16e\n", IpCq().curr_f(), IpCq().unscaled_curr_f()); Jnlst().Printf(J_DETAILED, J_MAIN, "Dual infeasibility......: %24.16e %24.16e\n", IpCq().curr_dual_infeasibility(NORM_MAX), IpCq().unscaled_curr_dual_infeasibility(NORM_MAX)); Jnlst().Printf(J_DETAILED, J_MAIN, "Constraint violation....: %24.16e %24.16e\n", IpCq().curr_nlp_constraint_violation(NORM_MAX), IpCq().unscaled_curr_nlp_constraint_violation(NORM_MAX)); Jnlst().Printf(J_DETAILED, J_MAIN, "Complementarity.........: %24.16e %24.16e\n", IpCq().curr_complementarity(0., NORM_MAX), IpCq().unscaled_curr_complementarity(0., NORM_MAX)); Jnlst().Printf(J_DETAILED, J_MAIN, "Overall NLP error.......: %24.16e %24.16e\n\n", IpCq().curr_nlp_error(), IpCq().unscaled_curr_nlp_error()); } if (Jnlst().ProduceOutput(J_VECTOR, J_MAIN)) { IpCq().curr_grad_f()->Print(Jnlst(), J_VECTOR, J_MAIN, "grad_f"); IpCq().curr_c()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_c"); IpCq().curr_d()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_d"); IpCq().curr_d_minus_s()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_d - curr_s"); } if (Jnlst().ProduceOutput(J_MATRIX, J_MAIN)) { IpCq().curr_jac_c()->Print(Jnlst(), J_MATRIX, J_MAIN, "jac_c"); IpCq().curr_jac_d()->Print(Jnlst(), J_MATRIX, J_MAIN, "jac_d"); IpData().W()->Print(Jnlst(), J_MATRIX, J_MAIN, "W"); } Jnlst().Printf(J_DETAILED, J_MAIN, "\n\n"); }
Number InexactLSAcceptor::ComputeAlphaForY( Number alpha_primal, Number alpha_dual, SmartPtr<IteratesVector>& delta ) { DBG_START_METH("InexactLSAcceptor::ComputeAlphaForY", dbg_verbosity); // Here, we choose as stepsize for y either alpha_primal, if the // conditions from the ineqaxt paper is satisfied for it, or we // compute the step size closest to alpha_primal but great than // it, that does give the same progress as the full step would // give. Number alpha_y = alpha_primal; SmartPtr<Vector> gx = IpCq().curr_grad_barrier_obj_x()->MakeNewCopy(); gx->AddTwoVectors(1., *IpCq().curr_jac_cT_times_curr_y_c(), 1., *IpCq().curr_jac_dT_times_curr_y_d(), 1.); SmartPtr<Vector> Jxy = gx->MakeNew(); IpCq().curr_jac_c()->TransMultVector(1., *delta->y_c(), 0., *Jxy); IpCq().curr_jac_d()->TransMultVector(1., *delta->y_d(), 1., *Jxy); SmartPtr<const Vector> curr_scaling_slacks = InexCq().curr_scaling_slacks(); SmartPtr<Vector> gs = curr_scaling_slacks->MakeNew(); gs->AddTwoVectors(1., *IpCq().curr_grad_barrier_obj_s(), -1., *IpData().curr()->y_d(), 0.); gs->ElementWiseMultiply(*curr_scaling_slacks); SmartPtr<Vector> Sdy = delta->y_d()->MakeNewCopy(); Sdy->ElementWiseMultiply(*curr_scaling_slacks); // using the magic formula in my notebook Number a = pow(Jxy->Nrm2(), 2) + pow(Sdy->Nrm2(), 2); Number b = 2 * (gx->Dot(*Jxy) - gs->Dot(*Sdy)); Number c = pow(gx->Nrm2(), 2) + pow(gs->Nrm2(), 2); // First we check if the primal step size is good enough: Number val_ap = alpha_primal * alpha_primal * a + alpha_primal * b + c; Number val_1 = a + b + c; if( val_ap <= val_1 ) { Jnlst().Printf(J_DETAILED, J_LINE_SEARCH, " Step size for y: using alpha_primal\n."); } else { Number alpha_2 = -b / a - 1.; Jnlst().Printf(J_DETAILED, J_LINE_SEARCH, " Step size for y candidate: %8.2e - ", alpha_2); if( alpha_2 > alpha_primal && alpha_2 < 1. ) { alpha_y = alpha_2; Jnlst().Printf(J_DETAILED, J_LINE_SEARCH, "using that one\n."); } else { alpha_y = 1.; Jnlst().Printf(J_DETAILED, J_LINE_SEARCH, "using 1 instead\n"); } } return alpha_y; }
bool CGPerturbationHandler::ConsiderNewSystem(Number& delta_x, Number& delta_s, Number& delta_c, Number& delta_d) { DBG_START_METH("CGPerturbationHandler::ConsiderNewSystem",dbg_verbosity); // Check if we can conclude that some components of the system are // structurally degenerate finalize_test(); // If the current iterate is restored from a previous iteration, // initialize perturbationhandler data if (CGPenData().restor_iter() == IpData().iter_count()) { hess_degenerate_ = NOT_YET_DETERMINED; jac_degenerate_ = NOT_YET_DETERMINED; degen_iters_ = 0; hess_degenerate_ = NOT_DEGENERATE; jac_degenerate_ = NOT_DEGENERATE; delta_x_curr_ = 0.; delta_s_curr_ = 0.; delta_c_curr_ = 0.; delta_d_curr_ = 0.; delta_x_last_ = 0.; delta_s_last_ = 0.; delta_c_last_ = 0.; delta_d_last_ = 0.; test_status_ = NO_TEST; } // Store the perturbation from the previous matrix if (reset_last_) { delta_x_last_ = delta_x_curr_; delta_s_last_ = delta_s_curr_; delta_c_last_ = delta_c_curr_; delta_d_last_ = delta_d_curr_; } else { if (delta_x_curr_ > 0.) { delta_x_last_ = delta_x_curr_; } if (delta_s_curr_ > 0.) { delta_s_last_ = delta_s_curr_; } if (delta_c_curr_ > 0.) { delta_c_last_ = delta_c_curr_; } if (delta_d_curr_ > 0.) { delta_d_last_ = delta_d_curr_; } } DBG_ASSERT((hess_degenerate_ != NOT_YET_DETERMINED || jac_degenerate_ != DEGENERATE) && (jac_degenerate_ != NOT_YET_DETERMINED || hess_degenerate_ != DEGENERATE)); if (hess_degenerate_ == NOT_YET_DETERMINED || jac_degenerate_ == NOT_YET_DETERMINED) { if (!perturb_always_cd_ || CGPenCq().curr_cg_pert_fact() < delta_cd() || !CGPenData().NeverTryPureNewton()) { test_status_ = TEST_DELTA_C_EQ_0_DELTA_X_EQ_0; } else { test_status_ = TEST_DELTA_C_GT_0_DELTA_X_EQ_0; } } else { test_status_ = NO_TEST; } Number pert_fact = CGPenCq().curr_cg_pert_fact(); if (jac_degenerate_ == DEGENERATE || CGPenData().NeverTryPureNewton() || perturb_always_cd_) { Number mach_eps = std::numeric_limits<Number>::epsilon(); if (pert_fact < 100.*mach_eps && jac_degenerate_ == DEGENERATE) { delta_c = delta_c_curr_ = 100.*mach_eps; } else { delta_c = delta_c_curr_ = pert_fact; } } else { delta_c = delta_c_curr_ = 0.; } CGPenData().SetCurrPenaltyPert(delta_c); delta_d = delta_d_curr_ = delta_c; if (hess_degenerate_ == DEGENERATE) { delta_x_curr_ = 0.; delta_s_curr_ = 0.; bool retval = get_deltas_for_wrong_inertia(delta_x, delta_s, delta_c, delta_d); if (!retval) { return false; } } else { delta_x = 0.; delta_s = delta_x; } delta_x_curr_ = delta_x; delta_s_curr_ = delta_s; delta_c_curr_ = delta_c; delta_d_curr_ = delta_d; IpData().Set_info_regu_x(delta_x); get_deltas_for_wrong_inertia_called_ = false; return true; }
bool WarmStartIterateInitializer::SetInitialIterates() { DBG_START_METH("WarmStartIterateInitializer::SetInitialIterates", dbg_verbosity); // Get the starting values provided by the NLP and store them // in the ip_data current fields. SmartPtr<IteratesVector> init_vec; bool have_iterate = false; if (warm_start_entire_iterate_) { if (!IpData().InitializeDataStructures(IpNLP(), false, false, false, false, false)) { return false; } init_vec = IpData().curr()->MakeNewIteratesVector(true); have_iterate = IpNLP().GetWarmStartIterate(*init_vec); if (!have_iterate) { Jnlst().Printf(J_DETAILED, J_LINE_SEARCH, "Tried to obtain entire warm start iterate from NLP, but it returned false.\n"); IpData().Append_info_string("NW"); } // Make sure given bounds are respected if (have_iterate && warm_start_mult_init_max_>0.) { SmartPtr<Vector> y_c = init_vec->create_new_y_c_copy(); SmartPtr<Vector> tmp = y_c->MakeNew(); tmp->Set(warm_start_mult_init_max_); y_c->ElementWiseMin(*tmp); tmp->Set(-warm_start_mult_init_max_); y_c->ElementWiseMax(*tmp); SmartPtr<Vector> y_d = init_vec->create_new_y_d_copy(); tmp = y_d->MakeNew(); tmp->Set(warm_start_mult_init_max_); y_d->ElementWiseMin(*tmp); tmp->Set(-warm_start_mult_init_max_); y_d->ElementWiseMax(*tmp); SmartPtr<Vector> z_L = init_vec->create_new_z_L_copy(); tmp = z_L->MakeNew(); tmp->Set(warm_start_mult_init_max_); z_L->ElementWiseMin(*tmp); SmartPtr<Vector> z_U = init_vec->create_new_z_U_copy(); tmp = z_U->MakeNew(); tmp->Set(warm_start_mult_init_max_); z_U->ElementWiseMin(*tmp); SmartPtr<Vector> v_L = init_vec->create_new_v_L_copy(); tmp = v_L->MakeNew(); tmp->Set(warm_start_mult_init_max_); v_L->ElementWiseMin(*tmp); SmartPtr<Vector> v_U = init_vec->create_new_v_U_copy(); tmp = v_U->MakeNew(); tmp->Set(warm_start_mult_init_max_); v_U->ElementWiseMin(*tmp); } } if (!have_iterate) { ///////////////////////////////////////////////////////////////////// // Initialize primal variables // ///////////////////////////////////////////////////////////////////// // Get the intial values for x, y_c, y_d, z_L, z_U, if (!IpData().InitializeDataStructures(IpNLP(), true, true, true, true, true)) { return false; } IpData().curr()->x()->Print(Jnlst(), J_VECTOR, J_INITIALIZATION, "user-provided x"); IpData().curr()->y_c()->Print(Jnlst(), J_VECTOR, J_INITIALIZATION, "user-provided y_c"); IpData().curr()->y_d()->Print(Jnlst(), J_VECTOR, J_INITIALIZATION, "user-provided y_d"); IpData().curr()->z_L()->Print(Jnlst(), J_VECTOR, J_INITIALIZATION, "user-provided z_L"); IpData().curr()->z_U()->Print(Jnlst(), J_VECTOR, J_INITIALIZATION, "user-provided z_U"); if (Jnlst().ProduceOutput(J_MOREVECTOR, J_INITIALIZATION)) { IpCq().curr_d()->Print(Jnlst(), J_MOREVECTOR, J_INITIALIZATION, "d at user-provided x"); } SmartPtr<Vector> tmp; init_vec = IpData().curr()->MakeNewContainer(); // If requested, make sure that the multipliers are not too large if (warm_start_mult_init_max_>0.) { SmartPtr<Vector> y_c = init_vec->create_new_y_c_copy(); tmp = y_c->MakeNew(); tmp->Set(warm_start_mult_init_max_); y_c->ElementWiseMin(*tmp); tmp->Set(-warm_start_mult_init_max_); y_c->ElementWiseMax(*tmp); SmartPtr<Vector> y_d = init_vec->create_new_y_d_copy(); tmp = y_d->MakeNew(); tmp->Set(warm_start_mult_init_max_); y_d->ElementWiseMin(*tmp); tmp->Set(-warm_start_mult_init_max_); y_d->ElementWiseMax(*tmp); SmartPtr<Vector> z_L = init_vec->create_new_z_L_copy(); tmp = z_L->MakeNew(); tmp->Set(warm_start_mult_init_max_); z_L->ElementWiseMin(*tmp); SmartPtr<Vector> z_U = init_vec->create_new_z_U_copy(); tmp = z_U->MakeNew(); tmp->Set(warm_start_mult_init_max_); z_U->ElementWiseMin(*tmp); } // Get the initial values for v_L and v_U out of y_d SmartPtr<Vector> v_L = init_vec->create_new_v_L(); IpNLP().Pd_L()->TransMultVector(-1., *init_vec->y_d(), 0., *v_L); tmp = v_L->MakeNew(); tmp->Set(warm_start_mult_bound_push_); v_L->ElementWiseMax(*tmp); SmartPtr<Vector> v_U = init_vec->create_new_v_U(); IpNLP().Pd_U()->TransMultVector(1., *init_vec->y_d(), 0., *v_U); tmp = v_U->MakeNew(); tmp->Set(warm_start_mult_bound_push_); v_U->ElementWiseMax(*tmp); // Initialize slack variables init_vec->Set_s(*IpCq().curr_d()); } // Make the corrected values current (and initialize s) IpData().set_trial(init_vec); IpData().AcceptTrialPoint(); // Now apply the target mu heuristic if required if (warm_start_target_mu_>0.) { SmartPtr<const Vector> new_x; SmartPtr<const Vector> new_z_L; SmartPtr<const IteratesVector> curr = IpData().curr(); process_target_mu(1., *curr->x(), *IpCq().curr_slack_x_L(), *curr->z_L(), *IpNLP().Px_L(), new_x, new_z_L); SmartPtr<const Vector> new_s; SmartPtr<const Vector> new_v_L; process_target_mu(1., *curr->s(), *IpCq().curr_slack_s_L(), *curr->v_L(), *IpNLP().Pd_L(), new_s, new_v_L); // Set the trial pointers to new_x and new_s. The process_target_mu // methods below create new vectors in new_x and new_s and do not alter // the existing ones. init_vec->Set_x(*new_x); init_vec->Set_s(*new_s); IpData().set_trial(init_vec); SmartPtr<const Vector> new_z_U; process_target_mu(-1., *IpData().trial()->x(), *IpCq().trial_slack_x_U(), *IpData().curr()->z_U(), *IpNLP().Px_U(), new_x, new_z_U); SmartPtr<const Vector> new_v_U; process_target_mu(-1., *IpData().trial()->s(), *IpCq().trial_slack_s_U(), *IpData().curr()->v_U(), *IpNLP().Pd_U(), new_s, new_v_U); // Now submit the full modified point init_vec->Set_x(*new_x); init_vec->Set_s(*new_s); // y_c and y_d currently contain a copy of curr()->y_c... // we set them back to the actual pointer to reuse the tags init_vec->Set_y_c(*IpData().curr()->y_c()); init_vec->Set_y_d(*IpData().curr()->y_d()); init_vec->Set_z_L(*new_z_L); init_vec->Set_z_U(*new_z_U); init_vec->Set_v_L(*new_v_L); init_vec->Set_v_U(*new_v_U); IpData().set_trial(init_vec); IpData().AcceptTrialPoint(); // We need to call this to make sure that we don't get an error // message because at some point a slack became too small IpCq().ResetAdjustedTrialSlacks(); } SmartPtr<const Vector> new_x; SmartPtr<const Vector> new_s; // Push the primal x variables DefaultIterateInitializer::push_variables(Jnlst(), warm_start_bound_push_, warm_start_bound_frac_, "x", *IpData().curr()->x(), new_x, *IpNLP().x_L(), *IpNLP().x_U(), *IpNLP().Px_L(), *IpNLP().Px_U()); // Push the primal s variables DefaultIterateInitializer::push_variables(Jnlst(), warm_start_slack_bound_push_, warm_start_slack_bound_frac_, "s", *IpData().curr()->s(), new_s, *IpNLP().d_L(), *IpNLP().d_U(), *IpNLP().Pd_L(), *IpNLP().Pd_U()); // Push the multipliers SmartPtr<Vector> new_z_L = IpData().curr()->z_L()->MakeNewCopy(); SmartPtr<Vector> tmp = IpData().curr()->z_L()->MakeNew(); tmp->Set(warm_start_mult_bound_push_); new_z_L->ElementWiseMax(*tmp); SmartPtr<Vector> new_z_U = IpData().curr()->z_U()->MakeNewCopy(); tmp = IpData().curr()->z_U()->MakeNew(); tmp->Set(warm_start_mult_bound_push_); new_z_U->ElementWiseMax(*tmp); SmartPtr<Vector> new_v_L = IpData().curr()->v_L()->MakeNewCopy(); tmp = IpData().curr()->v_L()->MakeNew(); tmp->Set(warm_start_mult_bound_push_); new_v_L->ElementWiseMax(*tmp); SmartPtr<Vector> new_v_U = IpData().curr()->v_U()->MakeNewCopy(); tmp = IpData().curr()->v_U()->MakeNew(); tmp->Set(warm_start_mult_bound_push_); new_v_U->ElementWiseMax(*tmp); // Make sure the new variables are current init_vec = IpData().curr()->MakeNewContainer(); init_vec->Set_x(*new_x); init_vec->Set_s(*new_s); init_vec->Set_z_L(*new_z_L); init_vec->Set_z_U(*new_z_U); init_vec->Set_v_L(*new_v_L); init_vec->Set_v_U(*new_v_U); IpData().set_trial(init_vec); IpData().AcceptTrialPoint(); IpData().curr()->x()->Print(Jnlst(), J_VECTOR, J_INITIALIZATION, "initial x"); IpData().curr()->s()->Print(Jnlst(), J_VECTOR, J_INITIALIZATION, "initial s"); IpData().curr()->y_c()->Print(Jnlst(), J_VECTOR, J_INITIALIZATION, "initial y_c"); IpData().curr()->y_d()->Print(Jnlst(), J_VECTOR, J_INITIALIZATION, "initial y_d"); IpData().curr()->z_L()->Print(Jnlst(), J_VECTOR, J_INITIALIZATION, "initial z_L"); IpData().curr()->z_U()->Print(Jnlst(), J_VECTOR, J_INITIALIZATION, "initial z_U"); IpData().curr()->v_L()->Print(Jnlst(), J_VECTOR, J_INITIALIZATION, "initial v_L"); IpData().curr()->v_U()->Print(Jnlst(), J_VECTOR, J_INITIALIZATION, "initial v_U"); if (Jnlst().ProduceOutput(J_MOREVECTOR, J_INITIALIZATION)) { IpCq().curr_slack_x_L()->Print(Jnlst(), J_MOREVECTOR, J_INITIALIZATION, "initial slack_x_L"); IpCq().curr_slack_x_U()->Print(Jnlst(), J_MOREVECTOR, J_INITIALIZATION, "initial slack_x_U"); IpCq().curr_slack_s_L()->Print(Jnlst(), J_MOREVECTOR, J_INITIALIZATION, "initial slack_s_L"); IpCq().curr_slack_s_U()->Print(Jnlst(), J_MOREVECTOR, J_INITIALIZATION, "initial slack_s_U"); } return true; }
Number ProbingMuOracle::CalculateAffineMu( Number alpha_primal, Number alpha_dual, const IteratesVector& step ) { // Get the current values of the slack variables and bound multipliers SmartPtr<const Vector> slack_x_L = IpCq().curr_slack_x_L(); SmartPtr<const Vector> slack_x_U = IpCq().curr_slack_x_U(); SmartPtr<const Vector> slack_s_L = IpCq().curr_slack_s_L(); SmartPtr<const Vector> slack_s_U = IpCq().curr_slack_s_U(); SmartPtr<const Vector> z_L = IpData().curr()->z_L(); SmartPtr<const Vector> z_U = IpData().curr()->z_U(); SmartPtr<const Vector> v_L = IpData().curr()->v_L(); SmartPtr<const Vector> v_U = IpData().curr()->v_U(); SmartPtr<Vector> tmp_slack; SmartPtr<Vector> tmp_mult; SmartPtr<const Matrix> P; Index ncomp = 0; Number sum = 0.; // For each combination of slack and multiplier, compute the new // values and their dot products. // slack_x_L if( slack_x_L->Dim() > 0 ) { ncomp += slack_x_L->Dim(); P = IpNLP().Px_L(); tmp_slack = slack_x_L->MakeNew(); tmp_slack->Copy(*slack_x_L); P->TransMultVector(alpha_primal, *step.x(), 1.0, *tmp_slack); tmp_mult = z_L->MakeNew(); tmp_mult->Copy(*z_L); tmp_mult->Axpy(alpha_dual, *step.z_L()); sum += tmp_slack->Dot(*tmp_mult); } // slack_x_U if( slack_x_U->Dim() > 0 ) { ncomp += slack_x_U->Dim(); P = IpNLP().Px_U(); tmp_slack = slack_x_U->MakeNew(); tmp_slack->Copy(*slack_x_U); P->TransMultVector(-alpha_primal, *step.x(), 1.0, *tmp_slack); tmp_mult = z_U->MakeNew(); tmp_mult->Copy(*z_U); tmp_mult->Axpy(alpha_dual, *step.z_U()); sum += tmp_slack->Dot(*tmp_mult); } // slack_s_L if( slack_s_L->Dim() > 0 ) { ncomp += slack_s_L->Dim(); P = IpNLP().Pd_L(); tmp_slack = slack_s_L->MakeNew(); tmp_slack->Copy(*slack_s_L); P->TransMultVector(alpha_primal, *step.s(), 1.0, *tmp_slack); tmp_mult = v_L->MakeNew(); tmp_mult->Copy(*v_L); tmp_mult->Axpy(alpha_dual, *step.v_L()); sum += tmp_slack->Dot(*tmp_mult); } // slack_s_U if( slack_s_U->Dim() > 0 ) { ncomp += slack_s_U->Dim(); P = IpNLP().Pd_U(); tmp_slack = slack_s_U->MakeNew(); tmp_slack->Copy(*slack_s_U); P->TransMultVector(-alpha_primal, *step.s(), 1.0, *tmp_slack); tmp_mult = v_U->MakeNew(); tmp_mult->Copy(*v_U); tmp_mult->Axpy(alpha_dual, *step.v_U()); sum += tmp_slack->Dot(*tmp_mult); } DBG_ASSERT(ncomp > 0); return sum / ((Number) ncomp); }
bool PDFullSpaceSolver::Solve(Number alpha, Number beta, const IteratesVector& rhs, IteratesVector& res, bool allow_inexact, bool improve_solution /* = false */) { DBG_START_METH("PDFullSpaceSolver::Solve",dbg_verbosity); DBG_ASSERT(!allow_inexact || !improve_solution); DBG_ASSERT(!improve_solution || beta==0.); // Timing of PDSystem solver starts here IpData().TimingStats().PDSystemSolverTotal().Start(); DBG_PRINT_VECTOR(2, "rhs_x", *rhs.x()); DBG_PRINT_VECTOR(2, "rhs_s", *rhs.s()); DBG_PRINT_VECTOR(2, "rhs_c", *rhs.y_c()); DBG_PRINT_VECTOR(2, "rhs_d", *rhs.y_d()); DBG_PRINT_VECTOR(2, "rhs_zL", *rhs.z_L()); DBG_PRINT_VECTOR(2, "rhs_zU", *rhs.z_U()); DBG_PRINT_VECTOR(2, "rhs_vL", *rhs.v_L()); DBG_PRINT_VECTOR(2, "rhs_vU", *rhs.v_U()); DBG_PRINT_VECTOR(2, "res_x in", *res.x()); DBG_PRINT_VECTOR(2, "res_s in", *res.s()); DBG_PRINT_VECTOR(2, "res_c in", *res.y_c()); DBG_PRINT_VECTOR(2, "res_d in", *res.y_d()); DBG_PRINT_VECTOR(2, "res_zL in", *res.z_L()); DBG_PRINT_VECTOR(2, "res_zU in", *res.z_U()); DBG_PRINT_VECTOR(2, "res_vL in", *res.v_L()); DBG_PRINT_VECTOR(2, "res_vU in", *res.v_U()); // if beta is nonzero, keep a copy of the incoming values in res_ */ SmartPtr<IteratesVector> copy_res; if (beta != 0.) { copy_res = res.MakeNewIteratesVectorCopy(); } // Receive data about matrix SmartPtr<const Vector> x = IpData().curr()->x(); SmartPtr<const Vector> s = IpData().curr()->s(); SmartPtr<const SymMatrix> W = IpData().W(); SmartPtr<const Matrix> J_c = IpCq().curr_jac_c(); SmartPtr<const Matrix> J_d = IpCq().curr_jac_d(); SmartPtr<const Matrix> Px_L = IpNLP().Px_L(); SmartPtr<const Matrix> Px_U = IpNLP().Px_U(); SmartPtr<const Matrix> Pd_L = IpNLP().Pd_L(); SmartPtr<const Matrix> Pd_U = IpNLP().Pd_U(); SmartPtr<const Vector> z_L = IpData().curr()->z_L(); SmartPtr<const Vector> z_U = IpData().curr()->z_U(); SmartPtr<const Vector> v_L = IpData().curr()->v_L(); SmartPtr<const Vector> v_U = IpData().curr()->v_U(); SmartPtr<const Vector> slack_x_L = IpCq().curr_slack_x_L(); SmartPtr<const Vector> slack_x_U = IpCq().curr_slack_x_U(); SmartPtr<const Vector> slack_s_L = IpCq().curr_slack_s_L(); SmartPtr<const Vector> slack_s_U = IpCq().curr_slack_s_U(); SmartPtr<const Vector> sigma_x = IpCq().curr_sigma_x(); SmartPtr<const Vector> sigma_s = IpCq().curr_sigma_s(); DBG_PRINT_VECTOR(2, "Sigma_x", *sigma_x); DBG_PRINT_VECTOR(2, "Sigma_s", *sigma_s); bool done = false; // The following flag is set to true, if we asked the linear // solver to improve the quality of the solution in // the next solve bool resolve_with_better_quality = false; // the following flag is set to true, if iterative refinement // failed and we want to try if a modified system is able to // remedy that problem by pretending the matrix is singular bool pretend_singular = false; bool pretend_singular_last_time = false; // Beginning of loop for solving the system (including all // modifications for the linear system to ensure good solution // quality) while (!done) { // if improve_solution is true, we are given already a solution // from the calling function, so we can skip the first solve bool solve_retval = true; if (!improve_solution) { solve_retval = SolveOnce(resolve_with_better_quality, pretend_singular, *W, *J_c, *J_d, *Px_L, *Px_U, *Pd_L, *Pd_U, *z_L, *z_U, *v_L, *v_U, *slack_x_L, *slack_x_U, *slack_s_L, *slack_s_U, *sigma_x, *sigma_s, 1., 0., rhs, res); resolve_with_better_quality = false; pretend_singular = false; } improve_solution = false; if (!solve_retval) { // If system seems not to be solvable, we return with false // and let the calling routine deal with it. IpData().TimingStats().PDSystemSolverTotal().End(); return false; } if (allow_inexact) { // no safety checks required if (Jnlst().ProduceOutput(J_MOREDETAILED, J_LINEAR_ALGEBRA)) { SmartPtr<IteratesVector> resid = res.MakeNewIteratesVector(true); ComputeResiduals(*W, *J_c, *J_d, *Px_L, *Px_U, *Pd_L, *Pd_U, *z_L, *z_U, *v_L, *v_U, *slack_x_L, *slack_x_U, *slack_s_L, *slack_s_U, *sigma_x, *sigma_s, alpha, beta, rhs, res, *resid); } break; } // Get space for the residual SmartPtr<IteratesVector> resid = res.MakeNewIteratesVector(true); // ToDo don't to that after max refinement? ComputeResiduals(*W, *J_c, *J_d, *Px_L, *Px_U, *Pd_L, *Pd_U, *z_L, *z_U, *v_L, *v_U, *slack_x_L, *slack_x_U, *slack_s_L, *slack_s_U, *sigma_x, *sigma_s, alpha, beta, rhs, res, *resid); Number residual_ratio = ComputeResidualRatio(rhs, res, *resid); Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "residual_ratio = %e\n", residual_ratio); Number residual_ratio_old = residual_ratio; // Beginning of loop for iterative refinement Index num_iter_ref = 0; bool quit_refinement = false; while (!allow_inexact && !quit_refinement && (num_iter_ref < min_refinement_steps_ || residual_ratio > residual_ratio_max_) ) { // To the next back solve solve_retval = SolveOnce(resolve_with_better_quality, false, *W, *J_c, *J_d, *Px_L, *Px_U, *Pd_L, *Pd_U, *z_L, *z_U, *v_L, *v_U, *slack_x_L, *slack_x_U, *slack_s_L, *slack_s_U, *sigma_x, *sigma_s, -1., 1., *resid, res); ASSERT_EXCEPTION(solve_retval, INTERNAL_ABORT, "SolveOnce returns false during iterative refinement."); ComputeResiduals(*W, *J_c, *J_d, *Px_L, *Px_U, *Pd_L, *Pd_U, *z_L, *z_U, *v_L, *v_U, *slack_x_L, *slack_x_U, *slack_s_L, *slack_s_U, *sigma_x, *sigma_s, alpha, beta, rhs, res, *resid); residual_ratio = ComputeResidualRatio(rhs, res, *resid); Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "residual_ratio = %e\n", residual_ratio); num_iter_ref++; // Check if we have to give up on iterative refinement if (residual_ratio > residual_ratio_max_ && num_iter_ref>min_refinement_steps_ && (num_iter_ref>max_refinement_steps_ || residual_ratio>residual_improvement_factor_*residual_ratio_old)) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Iterative refinement failed with residual_ratio = %e\n", residual_ratio); quit_refinement = true; // Pretend singularity only once - if it didn't help, we // have to live with what we got so far resolve_with_better_quality = false; DBG_PRINT((1, "pretend_singular = %d\n", pretend_singular)); if (!pretend_singular_last_time) { // First try if we can ask the augmented system solver to // improve the quality of the solution (only if that hasn't // been done before for this linear system) if (!augsys_improved_) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Asking augmented system solver to improve quality of its solutions.\n"); augsys_improved_ = augSysSolver_->IncreaseQuality(); if (augsys_improved_) { IpData().Append_info_string("q"); resolve_with_better_quality = true; } else { // solver said it cannot improve quality, so let // possibly conclude that the current modification is // singular pretend_singular = true; } } else { // we had already asked the solver before to improve the // quality of the solution, so let's now pretend that the // modification is possibly singular pretend_singular = true; } pretend_singular_last_time = pretend_singular; if (pretend_singular) { // let's only conclude that the current linear system // including modifications is singular, if the residual is // quite bad if (residual_ratio < residual_ratio_singular_) { pretend_singular = false; IpData().Append_info_string("S"); Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Just accept current solution.\n"); } else { IpData().Append_info_string("s"); Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Pretend that the current system (including modifications) is singular.\n"); } } } else { pretend_singular = false; DBG_PRINT((1,"Resetting pretend_singular to false.\n")); } } residual_ratio_old = residual_ratio; } // End of loop for iterative refinement done = !(resolve_with_better_quality) && !(pretend_singular); } // End of loop for solving the linear system (incl. modifications) // Finally let's assemble the res result vectors if (alpha != 0.) { res.Scal(alpha); } if (beta != 0.) { res.Axpy(beta, *copy_res); } DBG_PRINT_VECTOR(2, "res_x", *res.x()); DBG_PRINT_VECTOR(2, "res_s", *res.s()); DBG_PRINT_VECTOR(2, "res_c", *res.y_c()); DBG_PRINT_VECTOR(2, "res_d", *res.y_d()); DBG_PRINT_VECTOR(2, "res_zL", *res.z_L()); DBG_PRINT_VECTOR(2, "res_zU", *res.z_U()); DBG_PRINT_VECTOR(2, "res_vL", *res.v_L()); DBG_PRINT_VECTOR(2, "res_vU", *res.v_U()); IpData().TimingStats().PDSystemSolverTotal().End(); return true; }
bool RestoIterateInitializer::SetInitialIterates() { DBG_START_METH("RestoIterateInitializer::SetInitialIterates", dbg_verbosity); // Get a grip on the restoration phase NLP and obtain the pointers // to the original NLP data SmartPtr<RestoIpoptNLP> resto_ip_nlp = static_cast<RestoIpoptNLP*> (&IpNLP()); SmartPtr<IpoptNLP> orig_ip_nlp = static_cast<IpoptNLP*> (&resto_ip_nlp->OrigIpNLP()); SmartPtr<IpoptData> orig_ip_data = static_cast<IpoptData*> (&resto_ip_nlp->OrigIpData()); SmartPtr<IpoptCalculatedQuantities> orig_ip_cq = static_cast<IpoptCalculatedQuantities*> (&resto_ip_nlp->OrigIpCq()); // Set the value of the barrier parameter Number resto_mu; resto_mu = Max(orig_ip_data->curr_mu(), orig_ip_cq->curr_c()->Amax(), orig_ip_cq->curr_d_minus_s()->Amax()); IpData().Set_mu(resto_mu); Jnlst().Printf(J_DETAILED, J_INITIALIZATION, "Initial barrier parameter resto_mu = %e\n", resto_mu); ///////////////////////////////////////////////////////////////////// // Initialize primal varialbes // ///////////////////////////////////////////////////////////////////// // initialize the data structures in the restoration phase NLP IpData().InitializeDataStructures(IpNLP(), false, false, false, false, false); SmartPtr<Vector> new_x = IpData().curr()->x()->MakeNew(); SmartPtr<CompoundVector> Cnew_x = static_cast<CompoundVector*> (GetRawPtr(new_x)); // Set the trial x variables from the original NLP Cnew_x->GetCompNonConst(0)->Copy(*orig_ip_data->curr()->x()); // Compute the initial values for the n and p variables for the // equality constraints Number rho = resto_ip_nlp->Rho(); DBG_PRINT((1,"rho = %e\n", rho)); SmartPtr<Vector> nc = Cnew_x->GetCompNonConst(1); SmartPtr<Vector> pc = Cnew_x->GetCompNonConst(2); SmartPtr<const Vector> cvec = orig_ip_cq->curr_c(); DBG_PRINT_VECTOR(2, "cvec", *cvec); SmartPtr<Vector> a = nc->MakeNew(); SmartPtr<Vector> b = nc->MakeNew(); a->Set(resto_mu/(2.*rho)); a->Axpy(-0.5, *cvec); b->Copy(*cvec); b->Scal(resto_mu/(2.*rho)); DBG_PRINT_VECTOR(2, "a", *a); DBG_PRINT_VECTOR(2, "b", *b); solve_quadratic(*a, *b, *nc); pc->Copy(*cvec); pc->Axpy(1., *nc); DBG_PRINT_VECTOR(2, "nc", *nc); DBG_PRINT_VECTOR(2, "pc", *pc); // initial values for the n and p variables for the inequality // constraints SmartPtr<Vector> nd = Cnew_x->GetCompNonConst(3); SmartPtr<Vector> pd = Cnew_x->GetCompNonConst(4); cvec = orig_ip_cq->curr_d_minus_s(); a = nd->MakeNew(); b = nd->MakeNew(); a->Set(resto_mu/(2.*rho)); a->Axpy(-0.5, *cvec); b->Copy(*cvec); b->Scal(resto_mu/(2.*rho)); solve_quadratic(*a, *b, *nd); pd->Copy(*cvec); pd->Axpy(1., *nd); DBG_PRINT_VECTOR(2, "nd", *nd); DBG_PRINT_VECTOR(2, "pd", *pd); // Leave the slacks unchanged SmartPtr<const Vector> new_s = orig_ip_data->curr()->s(); // Now set the primal trial variables DBG_PRINT_VECTOR(2,"new_s",*new_s); DBG_PRINT_VECTOR(2,"new_x",*new_x); SmartPtr<IteratesVector> trial = IpData().curr()->MakeNewContainer(); trial->Set_primal(*new_x, *new_s); IpData().set_trial(trial); DBG_PRINT_VECTOR(2, "resto_c", *IpCq().trial_c()); DBG_PRINT_VECTOR(2, "resto_d_minus_s", *IpCq().trial_d_minus_s()); ///////////////////////////////////////////////////////////////////// // Initialize bound multipliers // ///////////////////////////////////////////////////////////////////// SmartPtr<Vector> new_z_L = IpData().curr()->z_L()->MakeNew(); SmartPtr<CompoundVector> Cnew_z_L = static_cast<CompoundVector*> (GetRawPtr(new_z_L)); DBG_ASSERT(IsValid(Cnew_z_L)); SmartPtr<Vector> new_z_U = IpData().curr()->z_U()->MakeNew(); SmartPtr<Vector> new_v_L = IpData().curr()->v_L()->MakeNew(); SmartPtr<Vector> new_v_U = IpData().curr()->v_U()->MakeNew(); // multipliers for the original bounds are SmartPtr<const Vector> orig_z_L = orig_ip_data->curr()->z_L(); SmartPtr<const Vector> orig_z_U = orig_ip_data->curr()->z_U(); SmartPtr<const Vector> orig_v_L = orig_ip_data->curr()->v_L(); SmartPtr<const Vector> orig_v_U = orig_ip_data->curr()->v_U(); // Set the new multipliers to the min of the penalty parameter Rho // and their current value SmartPtr<Vector> Cnew_z_L0 = Cnew_z_L->GetCompNonConst(0); Cnew_z_L0->Set(rho); Cnew_z_L0->ElementWiseMin(*orig_z_L); new_z_U->Set(rho); new_z_U->ElementWiseMin(*orig_z_U); new_v_L->Set(rho); new_v_L->ElementWiseMin(*orig_v_L); new_v_U->Set(rho); new_v_U->ElementWiseMin(*orig_v_U); // Set the multipliers for the p and n bounds to the "primal" multipliers SmartPtr<Vector> Cnew_z_L1 = Cnew_z_L->GetCompNonConst(1); Cnew_z_L1->Set(resto_mu); Cnew_z_L1->ElementWiseDivide(*nc); SmartPtr<Vector> Cnew_z_L2 = Cnew_z_L->GetCompNonConst(2); Cnew_z_L2->Set(resto_mu); Cnew_z_L2->ElementWiseDivide(*pc); SmartPtr<Vector> Cnew_z_L3 = Cnew_z_L->GetCompNonConst(3); Cnew_z_L3->Set(resto_mu); Cnew_z_L3->ElementWiseDivide(*nd); SmartPtr<Vector> Cnew_z_L4 = Cnew_z_L->GetCompNonConst(4); Cnew_z_L4->Set(resto_mu); Cnew_z_L4->ElementWiseDivide(*pd); // Set those initial values to be the trial values in Data trial = IpData().trial()->MakeNewContainer(); trial->Set_bound_mult(*new_z_L, *new_z_U, *new_v_L, *new_v_U); IpData().set_trial(trial); ///////////////////////////////////////////////////////////////////// // Initialize equality constraint multipliers // ///////////////////////////////////////////////////////////////////// DefaultIterateInitializer::least_square_mults( Jnlst(), IpNLP(), IpData(), IpCq(), resto_eq_mult_calculator_, constr_mult_init_max_); // upgrade the trial to the current point IpData().AcceptTrialPoint(); DBG_PRINT_VECTOR(2, "y_c", *IpData().curr()->y_c()); DBG_PRINT_VECTOR(2, "y_d", *IpData().curr()->y_d()); DBG_PRINT_VECTOR(2, "z_L", *IpData().curr()->z_L()); DBG_PRINT_VECTOR(2, "z_U", *IpData().curr()->z_U()); DBG_PRINT_VECTOR(2, "v_L", *IpData().curr()->v_L()); DBG_PRINT_VECTOR(2, "v_U", *IpData().curr()->v_U()); return true; }
bool PDFullSpaceSolver::SolveOnce(bool resolve_with_better_quality, bool pretend_singular, const SymMatrix& W, const Matrix& J_c, const Matrix& J_d, const Matrix& Px_L, const Matrix& Px_U, const Matrix& Pd_L, const Matrix& Pd_U, const Vector& z_L, const Vector& z_U, const Vector& v_L, const Vector& v_U, const Vector& slack_x_L, const Vector& slack_x_U, const Vector& slack_s_L, const Vector& slack_s_U, const Vector& sigma_x, const Vector& sigma_s, Number alpha, Number beta, const IteratesVector& rhs, IteratesVector& res) { // TO DO LIST: // // 1. decide for reasonable return codes (e.g. fatal error, too // ill-conditioned...) // 2. Make constants parameters that can be set from the outside // 3. Get Information out of Ipopt structures // 4. add heuristic for structurally singular problems // 5. see if it makes sense to distinguish delta_x and delta_s, // or delta_c and delta_d // 6. increase pivot tolerance if number of get evals so too small DBG_START_METH("PDFullSpaceSolver::SolveOnce",dbg_verbosity); IpData().TimingStats().PDSystemSolverSolveOnce().Start(); // Compute the right hand side for the augmented system formulation SmartPtr<Vector> augRhs_x = rhs.x()->MakeNewCopy(); Px_L.AddMSinvZ(1.0, slack_x_L, *rhs.z_L(), *augRhs_x); Px_U.AddMSinvZ(-1.0, slack_x_U, *rhs.z_U(), *augRhs_x); SmartPtr<Vector> augRhs_s = rhs.s()->MakeNewCopy(); Pd_L.AddMSinvZ(1.0, slack_s_L, *rhs.v_L(), *augRhs_s); Pd_U.AddMSinvZ(-1.0, slack_s_U, *rhs.v_U(), *augRhs_s); // Get space into which we can put the solution of the augmented system SmartPtr<IteratesVector> sol = res.MakeNewIteratesVector(true); // Now check whether any data has changed std::vector<const TaggedObject*> deps(13); deps[0] = &W; deps[1] = &J_c; deps[2] = &J_d; deps[3] = &z_L; deps[4] = &z_U; deps[5] = &v_L; deps[6] = &v_U; deps[7] = &slack_x_L; deps[8] = &slack_x_U; deps[9] = &slack_s_L; deps[10] = &slack_s_U; deps[11] = &sigma_x; deps[12] = &sigma_s; void* dummy; bool uptodate = dummy_cache_.GetCachedResult(dummy, deps); if (!uptodate) { dummy_cache_.AddCachedResult(dummy, deps); augsys_improved_ = false; } // improve_current_solution can only be true, if that system has // been solved before DBG_ASSERT((!resolve_with_better_quality && !pretend_singular) || uptodate); ESymSolverStatus retval; if (uptodate && !pretend_singular) { // Get the perturbation values Number delta_x; Number delta_s; Number delta_c; Number delta_d; perturbHandler_->CurrentPerturbation(delta_x, delta_s, delta_c, delta_d); // No need to go through the pain of finding the appropriate // values for the deltas, because the matrix hasn't changed since // the last call. So, just call the Solve Method // // Note: resolve_with_better_quality is true, then the Solve // method has already asked the augSysSolver to increase the // quality at the end solve, and we are now getting the solution // with that better quality retval = augSysSolver_->Solve(&W, 1.0, &sigma_x, delta_x, &sigma_s, delta_s, &J_c, NULL, delta_c, &J_d, NULL, delta_d, *augRhs_x, *augRhs_s, *rhs.y_c(), *rhs.y_d(), *sol->x_NonConst(), *sol->s_NonConst(), *sol->y_c_NonConst(), *sol->y_d_NonConst(), false, 0); if (retval!=SYMSOLVER_SUCCESS) { IpData().TimingStats().PDSystemSolverSolveOnce().End(); return false; } } else { const Index numberOfEVals=rhs.y_c()->Dim()+rhs.y_d()->Dim(); // counter for the number of trial evaluations // (ToDo is not at the correct place) Index count = 0; // Get the very first perturbation values from the perturbation // Handler Number delta_x; Number delta_s; Number delta_c; Number delta_d; perturbHandler_->ConsiderNewSystem(delta_x, delta_s, delta_c, delta_d); retval = SYMSOLVER_SINGULAR; bool fail = false; while (retval!= SYMSOLVER_SUCCESS && !fail) { if (pretend_singular) { retval = SYMSOLVER_SINGULAR; pretend_singular = false; } else { count++; Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "Solving system with delta_x=%e delta_s=%e\n delta_c=%e delta_d=%e\n", delta_x, delta_s, delta_c, delta_d); bool check_inertia = true; if (neg_curv_test_tol_ > 0.) { check_inertia = false; } retval = augSysSolver_->Solve(&W, 1.0, &sigma_x, delta_x, &sigma_s, delta_s, &J_c, NULL, delta_c, &J_d, NULL, delta_d, *augRhs_x, *augRhs_s, *rhs.y_c(), *rhs.y_d(), *sol->x_NonConst(), *sol->s_NonConst(), *sol->y_c_NonConst(), *sol->y_d_NonConst(), check_inertia, numberOfEVals); } if (retval==SYMSOLVER_FATAL_ERROR) return false; if (retval==SYMSOLVER_SINGULAR && (rhs.y_c()->Dim()+rhs.y_d()->Dim() > 0) ) { // Get new perturbation factors from the perturbation // handlers for the singular case bool pert_return = perturbHandler_->PerturbForSingularity(delta_x, delta_s, delta_c, delta_d); if (!pert_return) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "PerturbForSingularity can't be done\n"); IpData().TimingStats().PDSystemSolverSolveOnce().End(); return false; } } else if (retval==SYMSOLVER_WRONG_INERTIA && augSysSolver_->NumberOfNegEVals() < numberOfEVals) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Number of negative eigenvalues too small!\n"); // If the number of negative eigenvalues is too small, then // we first try to remedy this by asking for better quality // solution (e.g. increasing pivot tolerance), and if that // doesn't help, we assume that the system is singular bool assume_singular = true; if (!augsys_improved_) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Asking augmented system solver to improve quality of its solutions.\n"); augsys_improved_ = augSysSolver_->IncreaseQuality(); if (augsys_improved_) { IpData().Append_info_string("q"); assume_singular = false; } else { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Quality could not be improved\n"); } } if (assume_singular) { bool pert_return = perturbHandler_->PerturbForSingularity(delta_x, delta_s, delta_c, delta_d); if (!pert_return) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "PerturbForSingularity can't be done for assume singular.\n"); IpData().TimingStats().PDSystemSolverSolveOnce().End(); return false; } IpData().Append_info_string("a"); } } else if (retval==SYMSOLVER_WRONG_INERTIA || retval==SYMSOLVER_SINGULAR) { // Get new perturbation factors from the perturbation // handlers for the case of wrong inertia bool pert_return = perturbHandler_->PerturbForWrongInertia(delta_x, delta_s, delta_c, delta_d); if (!pert_return) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "PerturbForWrongInertia can't be done for wrong interia or singular.\n"); IpData().TimingStats().PDSystemSolverSolveOnce().End(); return false; } } else if (neg_curv_test_tol_ > 0.) { DBG_ASSERT(augSysSolver_->ProvidesInertia()); // we now check if the inertia is possible wrong Index neg_values = augSysSolver_->NumberOfNegEVals(); if (neg_values != numberOfEVals) { // check if we have a direction of sufficient positive curvature SmartPtr<Vector> x_tmp = sol->x()->MakeNew(); W.MultVector(1., *sol->x(), 0., *x_tmp); Number xWx = x_tmp->Dot(*sol->x()); x_tmp->Copy(*sol->x()); x_tmp->ElementWiseMultiply(sigma_x); xWx += x_tmp->Dot(*sol->x()); SmartPtr<Vector> s_tmp = sol->s()->MakeNewCopy(); s_tmp->ElementWiseMultiply(sigma_s); xWx += s_tmp->Dot(*sol->s()); Number xs_nrmsq = pow(sol->x()->Nrm2(),2) + pow(sol->s()->Nrm2(),2); Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "In inertia heuristic: xWx = %e xx = %e\n", xWx, xs_nrmsq); if (xWx < neg_curv_test_tol_*xs_nrmsq) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, " -> Redo with modified matrix.\n"); bool pert_return = perturbHandler_->PerturbForWrongInertia(delta_x, delta_s, delta_c, delta_d); if (!pert_return) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "PerturbForWrongInertia can't be done for inertia heuristic.\n"); IpData().TimingStats().PDSystemSolverSolveOnce().End(); return false; } retval = SYMSOLVER_WRONG_INERTIA; } } } } // while (retval!=SYMSOLVER_SUCCESS && !fail) { // Some output Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Number of trial factorizations performed: %d\n", count); Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Perturbation parameters: delta_x=%e delta_s=%e\n delta_c=%e delta_d=%e\n", delta_x, delta_s, delta_c, delta_d); // Set the perturbation values in the Data object IpData().setPDPert(delta_x, delta_s, delta_c, delta_d); } // Compute the remaining sol Vectors Px_L.SinvBlrmZMTdBr(-1., slack_x_L, *rhs.z_L(), z_L, *sol->x(), *sol->z_L_NonConst()); Px_U.SinvBlrmZMTdBr(1., slack_x_U, *rhs.z_U(), z_U, *sol->x(), *sol->z_U_NonConst()); Pd_L.SinvBlrmZMTdBr(-1., slack_s_L, *rhs.v_L(), v_L, *sol->s(), *sol->v_L_NonConst()); Pd_U.SinvBlrmZMTdBr(1., slack_s_U, *rhs.v_U(), v_U, *sol->s(), *sol->v_U_NonConst()); // Finally let's assemble the res result vectors res.AddOneVector(alpha, *sol, beta); IpData().TimingStats().PDSystemSolverSolveOnce().End(); return true; }
void OrigIterationOutput::WriteOutput() { ////////////////////////////////////////////////////////////////////// // First print the summary line for the iteration // ////////////////////////////////////////////////////////////////////// Index iter = IpData().iter_count(); std::string header = "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n"; Jnlst().Printf(J_DETAILED, J_MAIN, "\n\n**************************************************\n"); Jnlst().Printf(J_DETAILED, J_MAIN, "*** Summary of Iteration: %d:", IpData().iter_count()); Jnlst().Printf(J_DETAILED, J_MAIN, "\n**************************************************\n\n"); if (iter%10 == 0 && !IpData().info_skip_output()) { // output the header Jnlst().Printf(J_ITERSUMMARY, J_MAIN, header.c_str()); } else { Jnlst().Printf(J_DETAILED, J_MAIN, header.c_str()); } Number inf_pr; switch (inf_pr_output_) { case INTERNAL: inf_pr = IpCq().curr_primal_infeasibility(NORM_MAX); break; case ORIGINAL: inf_pr = IpCq().unscaled_curr_nlp_constraint_violation(NORM_MAX); break; } Number inf_du = IpCq().curr_dual_infeasibility(NORM_MAX); Number mu = IpData().curr_mu(); Number dnrm; if (IsValid(IpData().delta()) && IsValid(IpData().delta()->x()) && IsValid(IpData().delta()->s())) { dnrm = Max(IpData().delta()->x()->Amax(), IpData().delta()->s()->Amax()); } else { // This is the first iteration - no search direction has been // computed yet. dnrm = 0.; } Number unscaled_f = IpCq().unscaled_curr_f(); // Retrieve some information set in the different parts of the algorithm char info_iter=' '; Number alpha_primal = IpData().info_alpha_primal(); char alpha_primal_char = IpData().info_alpha_primal_char(); Number alpha_dual = IpData().info_alpha_dual(); Number regu_x = IpData().info_regu_x(); char regu_x_buf[8]; char dashes[]=" - "; char *regu_x_ptr; if (regu_x==.0) { regu_x_ptr = dashes; } else { Snprintf(regu_x_buf, 7, "%5.1f", log10(regu_x)); regu_x_ptr = regu_x_buf; } Index ls_count = IpData().info_ls_count(); const std::string info_string = IpData().info_string(); if (!IpData().info_skip_output()) { Jnlst().Printf(J_ITERSUMMARY, J_MAIN, "%4d%c%14.7e %7.2e %7.2e %5.1f %7.2e %5s %7.2e %7.2e%c%3d", iter, info_iter, unscaled_f, inf_pr, inf_du, log10(mu), dnrm, regu_x_ptr, alpha_dual, alpha_primal, alpha_primal_char, ls_count); if (print_info_string_) { Jnlst().Printf(J_ITERSUMMARY, J_MAIN, " %s", info_string.c_str()); } else { Jnlst().Printf(J_DETAILED, J_MAIN, " %s", info_string.c_str()); } Jnlst().Printf(J_ITERSUMMARY, J_MAIN, "\n"); } ////////////////////////////////////////////////////////////////////// // Now if desired more detail on the iterates // ////////////////////////////////////////////////////////////////////// if (Jnlst().ProduceOutput(J_DETAILED, J_MAIN)) { Jnlst().Printf(J_DETAILED, J_MAIN, "\n**************************************************\n"); Jnlst().Printf(J_DETAILED, J_MAIN, "*** Beginning Iteration %d from the following point:", IpData().iter_count()); Jnlst().Printf(J_DETAILED, J_MAIN, "\n**************************************************\n\n"); Jnlst().Printf(J_DETAILED, J_MAIN, "Current barrier parameter mu = %21.16e\n", IpData().curr_mu()); Jnlst().Printf(J_DETAILED, J_MAIN, "Current fraction-to-the-boundary parameter tau = %21.16e\n\n", IpData().curr_tau()); Jnlst().Printf(J_DETAILED, J_MAIN, "||curr_x||_inf = %.16e\n", IpData().curr()->x()->Amax()); Jnlst().Printf(J_DETAILED, J_MAIN, "||curr_s||_inf = %.16e\n", IpData().curr()->s()->Amax()); Jnlst().Printf(J_DETAILED, J_MAIN, "||curr_y_c||_inf = %.16e\n", IpData().curr()->y_c()->Amax()); Jnlst().Printf(J_DETAILED, J_MAIN, "||curr_y_d||_inf = %.16e\n", IpData().curr()->y_d()->Amax()); Jnlst().Printf(J_DETAILED, J_MAIN, "||curr_z_L||_inf = %.16e\n", IpData().curr()->z_L()->Amax()); Jnlst().Printf(J_DETAILED, J_MAIN, "||curr_z_U||_inf = %.16e\n", IpData().curr()->z_U()->Amax()); Jnlst().Printf(J_DETAILED, J_MAIN, "||curr_v_L||_inf = %.16e\n", IpData().curr()->v_L()->Amax()); Jnlst().Printf(J_DETAILED, J_MAIN, "||curr_v_U||_inf = %.16e\n", IpData().curr()->v_U()->Amax()); } if (Jnlst().ProduceOutput(J_MOREDETAILED, J_MAIN)) { if (IsValid(IpData().delta())) { Jnlst().Printf(J_MOREDETAILED, J_MAIN, "\n||delta_x||_inf = %.16e\n", IpData().delta()->x()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_MAIN, "||delta_s||_inf = %.16e\n", IpData().delta()->s()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_MAIN, "||delta_y_c||_inf = %.16e\n", IpData().delta()->y_c()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_MAIN, "||delta_y_d||_inf = %.16e\n", IpData().delta()->y_d()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_MAIN, "||delta_z_L||_inf = %.16e\n", IpData().delta()->z_L()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_MAIN, "||delta_z_U||_inf = %.16e\n", IpData().delta()->z_U()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_MAIN, "||delta_v_L||_inf = %.16e\n", IpData().delta()->v_L()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_MAIN, "||delta_v_U||_inf = %.16e\n", IpData().delta()->v_U()->Amax()); } else { Jnlst().Printf(J_MOREDETAILED, J_MAIN, "\nNo search direction has been computed yet.\n"); } } if (Jnlst().ProduceOutput(J_VECTOR, J_MAIN)) { IpData().curr()->x()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_x"); IpData().curr()->s()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_s"); IpData().curr()->y_c()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_y_c"); IpData().curr()->y_d()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_y_d"); IpCq().curr_slack_x_L()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_slack_x_L"); IpCq().curr_slack_x_U()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_slack_x_U"); IpData().curr()->z_L()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_z_L"); IpData().curr()->z_U()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_z_U"); IpCq().curr_slack_s_L()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_slack_s_L"); IpCq().curr_slack_s_U()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_slack_s_U"); IpData().curr()->v_L()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_v_L"); IpData().curr()->v_U()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_v_U"); } if (Jnlst().ProduceOutput(J_MOREVECTOR, J_MAIN)) { IpCq().curr_grad_lag_x()->Print(Jnlst(), J_MOREVECTOR, J_MAIN, "curr_grad_lag_x"); IpCq().curr_grad_lag_s()->Print(Jnlst(), J_MOREVECTOR, J_MAIN, "curr_grad_lag_s"); if (IsValid(IpData().delta())) { IpData().delta()->Print(Jnlst(), J_MOREVECTOR, J_MAIN, "delta"); } } if (Jnlst().ProduceOutput(J_DETAILED, J_MAIN)) { Jnlst().Printf(J_DETAILED, J_MAIN, "\n\n***Current NLP Values for Iteration %d:\n", IpData().iter_count()); Jnlst().Printf(J_DETAILED, J_MAIN, "\n (scaled) (unscaled)\n"); Jnlst().Printf(J_DETAILED, J_MAIN, "Objective...............: %24.16e %24.16e\n", IpCq().curr_f(), IpCq().unscaled_curr_f()); Jnlst().Printf(J_DETAILED, J_MAIN, "Dual infeasibility......: %24.16e %24.16e\n", IpCq().curr_dual_infeasibility(NORM_MAX), IpCq().unscaled_curr_dual_infeasibility(NORM_MAX)); Jnlst().Printf(J_DETAILED, J_MAIN, "Constraint violation....: %24.16e %24.16e\n", IpCq().curr_nlp_constraint_violation(NORM_MAX), IpCq().unscaled_curr_nlp_constraint_violation(NORM_MAX)); Jnlst().Printf(J_DETAILED, J_MAIN, "Complementarity.........: %24.16e %24.16e\n", IpCq().curr_complementarity(0., NORM_MAX), IpCq().unscaled_curr_complementarity(0., NORM_MAX)); Jnlst().Printf(J_DETAILED, J_MAIN, "Overall NLP error.......: %24.16e %24.16e\n\n", IpCq().curr_nlp_error(), IpCq().unscaled_curr_nlp_error()); } if (Jnlst().ProduceOutput(J_VECTOR, J_MAIN)) { IpCq().curr_grad_f()->Print(Jnlst(), J_VECTOR, J_MAIN, "grad_f"); IpCq().curr_c()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_c"); IpCq().curr_d()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_d"); IpCq().curr_d_minus_s()->Print(Jnlst(), J_VECTOR, J_MAIN, "curr_d - curr_s"); } if (Jnlst().ProduceOutput(J_MATRIX, J_MAIN)) { IpCq().curr_jac_c()->Print(Jnlst(), J_MATRIX, J_MAIN, "jac_c"); IpCq().curr_jac_d()->Print(Jnlst(), J_MATRIX, J_MAIN, "jac_d"); if (IsValid(IpData().W())) { IpData().W()->Print(Jnlst(), J_MATRIX, J_MAIN, "W"); } } Jnlst().Printf(J_DETAILED, J_MAIN, "\n\n"); Jnlst().FlushBuffer(); }
void PDFullSpaceSolver::ComputeResiduals( const SymMatrix& W, const Matrix& J_c, const Matrix& J_d, const Matrix& Px_L, const Matrix& Px_U, const Matrix& Pd_L, const Matrix& Pd_U, const Vector& z_L, const Vector& z_U, const Vector& v_L, const Vector& v_U, const Vector& slack_x_L, const Vector& slack_x_U, const Vector& slack_s_L, const Vector& slack_s_U, const Vector& sigma_x, const Vector& sigma_s, Number alpha, Number beta, const IteratesVector& rhs, const IteratesVector& res, IteratesVector& resid) { DBG_START_METH("PDFullSpaceSolver::ComputeResiduals", dbg_verbosity); DBG_PRINT_VECTOR(2, "res", res); IpData().TimingStats().ComputeResiduals().Start(); // Get the current sizes of the perturbation factors Number delta_x; Number delta_s; Number delta_c; Number delta_d; perturbHandler_->CurrentPerturbation(delta_x, delta_s, delta_c, delta_d); SmartPtr<Vector> tmp; // x W.MultVector(1., *res.x(), 0., *resid.x_NonConst()); J_c.TransMultVector(1., *res.y_c(), 1., *resid.x_NonConst()); J_d.TransMultVector(1., *res.y_d(), 1., *resid.x_NonConst()); Px_L.MultVector(-1., *res.z_L(), 1., *resid.x_NonConst()); Px_U.MultVector(1., *res.z_U(), 1., *resid.x_NonConst()); resid.x_NonConst()->AddTwoVectors(delta_x, *res.x(), -1., *rhs.x(), 1.); // s Pd_U.MultVector(1., *res.v_U(), 0., *resid.s_NonConst()); Pd_L.MultVector(-1., *res.v_L(), 1., *resid.s_NonConst()); resid.s_NonConst()->AddTwoVectors(-1., *res.y_d(), -1., *rhs.s(), 1.); if (delta_s!=0.) { resid.s_NonConst()->Axpy(delta_s, *res.s()); } // c J_c.MultVector(1., *res.x(), 0., *resid.y_c_NonConst()); resid.y_c_NonConst()->AddTwoVectors(-delta_c, *res.y_c(), -1., *rhs.y_c(), 1.); // d J_d.MultVector(1., *res.x(), 0., *resid.y_d_NonConst()); resid.y_d_NonConst()->AddTwoVectors(-1., *res.s(), -1., *rhs.y_d(), 1.); if (delta_d!=0.) { resid.y_d_NonConst()->Axpy(-delta_d, *res.y_d()); } // zL resid.z_L_NonConst()->Copy(*res.z_L()); resid.z_L_NonConst()->ElementWiseMultiply(slack_x_L); tmp = z_L.MakeNew(); Px_L.TransMultVector(1., *res.x(), 0., *tmp); tmp->ElementWiseMultiply(z_L); resid.z_L_NonConst()->AddTwoVectors(1., *tmp, -1., *rhs.z_L(), 1.); // zU resid.z_U_NonConst()->Copy(*res.z_U()); resid.z_U_NonConst()->ElementWiseMultiply(slack_x_U); tmp = z_U.MakeNew(); Px_U.TransMultVector(1., *res.x(), 0., *tmp); tmp->ElementWiseMultiply(z_U); resid.z_U_NonConst()->AddTwoVectors(-1., *tmp, -1., *rhs.z_U(), 1.); // vL resid.v_L_NonConst()->Copy(*res.v_L()); resid.v_L_NonConst()->ElementWiseMultiply(slack_s_L); tmp = v_L.MakeNew(); Pd_L.TransMultVector(1., *res.s(), 0., *tmp); tmp->ElementWiseMultiply(v_L); resid.v_L_NonConst()->AddTwoVectors(1., *tmp, -1., *rhs.v_L(), 1.); // vU resid.v_U_NonConst()->Copy(*res.v_U()); resid.v_U_NonConst()->ElementWiseMultiply(slack_s_U); tmp = v_U.MakeNew(); Pd_U.TransMultVector(1., *res.s(), 0., *tmp); tmp->ElementWiseMultiply(v_U); resid.v_U_NonConst()->AddTwoVectors(-1., *tmp, -1., *rhs.v_U(), 1.); DBG_PRINT_VECTOR(2, "resid", resid); if (Jnlst().ProduceOutput(J_MOREVECTOR, J_LINEAR_ALGEBRA)) { resid.Print(Jnlst(), J_MOREVECTOR, J_LINEAR_ALGEBRA, "resid"); } if (Jnlst().ProduceOutput(J_MOREDETAILED, J_LINEAR_ALGEBRA)) { Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "max-norm resid_x %e\n", resid.x()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "max-norm resid_s %e\n", resid.s()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "max-norm resid_c %e\n", resid.y_c()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "max-norm resid_d %e\n", resid.y_d()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "max-norm resid_zL %e\n", resid.z_L()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "max-norm resid_zU %e\n", resid.z_U()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "max-norm resid_vL %e\n", resid.v_L()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "max-norm resid_vU %e\n", resid.v_U()->Amax()); } IpData().TimingStats().ComputeResiduals().End(); }
ESymSolverStatus MumpsSolverInterface::SymbolicFactorization() { DBG_START_METH("MumpsSolverInterface::SymbolicFactorization", dbg_verbosity); DMUMPS_STRUC_C* mumps_data = (DMUMPS_STRUC_C*)mumps_ptr_; if (HaveIpData()) { IpData().TimingStats().LinearSystemSymbolicFactorization().Start(); } mumps_data->job = 1;//symbolic ordering pass //mumps_data->icntl[1] = 6; //mumps_data->icntl[2] = 6;//QUIETLY! //mumps_data->icntl[3] = 4; mumps_data->icntl[5] = mumps_permuting_scaling_; mumps_data->icntl[6] = mumps_pivot_order_; mumps_data->icntl[7] = mumps_scaling_; mumps_data->icntl[9] = 0;//no iterative refinement iterations mumps_data->icntl[12] = 1;//avoid lapack bug, ensures proper inertia mumps_data->icntl[13] = mem_percent_; //% memory to allocate over expected mumps_data->cntl[0] = pivtol_; // Set pivot tolerance dump_matrix(mumps_data); Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "Calling MUMPS-1 for symbolic factorization at cpu time %10.3f (wall %10.3f).\n", CpuTime(), WallclockTime()); dmumps_c(mumps_data); Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "Done with MUMPS-1 for symbolic factorization at cpu time %10.3f (wall %10.3f).\n", CpuTime(), WallclockTime()); int error = mumps_data->info[0]; const int& mumps_permuting_scaling_used = mumps_data->infog[22]; const int& mumps_pivot_order_used = mumps_data->infog[6]; Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "MUMPS used permuting_scaling %d and pivot_order %d.\n", mumps_permuting_scaling_used, mumps_pivot_order_used); Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, " scaling will be %d.\n", mumps_data->icntl[7]); if (HaveIpData()) { IpData().TimingStats().LinearSystemSymbolicFactorization().End(); } //return appropriat value if (error == -6) {//system is singular Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "MUMPS returned INFO(1) = %d matrix is singular.\n",error); return SYMSOLVER_SINGULAR; } if (error < 0) { Jnlst().Printf(J_ERROR, J_LINEAR_ALGEBRA, "Error=%d returned from MUMPS in Factorization.\n", error); return SYMSOLVER_FATAL_ERROR; } return SYMSOLVER_SUCCESS; }
bool MinC_1NrmRestorationPhase::PerformRestoration() { DBG_START_METH("MinC_1NrmRestorationPhase::PerformRestoration", dbg_verbosity); // Increase counter for restoration phase calls count_restorations_++; Jnlst().Printf(J_DETAILED, J_MAIN, "Starting Restoration Phase for the %d. time\n", count_restorations_); DBG_ASSERT(IpCq().curr_constraint_violation()>0.); // ToDo set those up during initialize? // Create the restoration phase NLP etc objects SmartPtr<IpoptData> resto_ip_data = new IpoptData(NULL, IpData().cpu_time_start()); SmartPtr<IpoptNLP> resto_ip_nlp = new RestoIpoptNLP(IpNLP(), IpData(), IpCq()); SmartPtr<IpoptCalculatedQuantities> resto_ip_cq = new IpoptCalculatedQuantities(resto_ip_nlp, resto_ip_data); // Determine if this is a square problem bool square_problem = IpCq().IsSquareProblem(); // Decide if we want to use the original option or want to make // some changes SmartPtr<OptionsList> actual_resto_options = resto_options_; if (square_problem) { actual_resto_options = new OptionsList(*resto_options_); // If this is a square problem, the want the restoration phase // never to be left until the problem is converged actual_resto_options->SetNumericValueIfUnset("required_infeasibility_reduction", 0.); } else if (expect_infeasible_problem_) { actual_resto_options = new OptionsList(*resto_options_); actual_resto_options->SetStringValueIfUnset("resto.expect_infeasible_problem", "no"); if (count_restorations_==1 && IpCq().curr_constraint_violation()>1e-3) { // Ask for significant reduction of infeasibility, in the hope // that we do not return from the restoration phase is the // problem is infeasible actual_resto_options->SetNumericValueIfUnset("required_infeasibility_reduction", 1e-3); } } // Initialize the restoration phase algorithm resto_alg_->Initialize(Jnlst(), *resto_ip_nlp, *resto_ip_data, *resto_ip_cq, *actual_resto_options, "resto."); // Set iteration counter and info field for the restoration phase resto_ip_data->Set_iter_count(IpData().iter_count()+1); resto_ip_data->Set_info_regu_x(IpData().info_regu_x()); resto_ip_data->Set_info_alpha_primal(IpData().info_alpha_primal()); resto_ip_data->Set_info_alpha_primal_char(IpData().info_alpha_primal_char()); resto_ip_data->Set_info_alpha_dual(IpData().info_alpha_dual()); resto_ip_data->Set_info_ls_count(IpData().info_ls_count()); resto_ip_data->Set_info_iters_since_header(IpData().info_iters_since_header()); resto_ip_data->Set_info_last_output(IpData().info_last_output()); // Call the optimization algorithm to solve the restoration phase // problem SolverReturn resto_status = resto_alg_->Optimize(true); int retval=-1; if (resto_status != SUCCESS) { SmartPtr<const IteratesVector> resto_curr = resto_ip_data->curr(); if (IsValid(resto_curr)) { // In case of a failure, we still copy the values of primal and // dual variables into the data fields of the regular NLP, so // that they will be returned to the user SmartPtr<IteratesVector> trial = IpData().trial()->MakeNewContainer(); SmartPtr<const Vector> resto_curr_x = resto_curr->x(); SmartPtr<const CompoundVector> cx = static_cast<const CompoundVector*>(GetRawPtr(resto_curr_x)); DBG_ASSERT(dynamic_cast<const CompoundVector*>(GetRawPtr(resto_curr_x))); SmartPtr<const Vector> resto_curr_s = resto_curr->s(); SmartPtr<const CompoundVector> cs = static_cast<const CompoundVector*>(GetRawPtr(resto_curr_s)); DBG_ASSERT(dynamic_cast<const CompoundVector*>(GetRawPtr(resto_curr_s))); SmartPtr<const Vector> resto_curr_y_c = resto_curr->y_c(); SmartPtr<const CompoundVector> cy_c = static_cast<const CompoundVector*>(GetRawPtr(resto_curr_y_c)); DBG_ASSERT(dynamic_cast<const CompoundVector*>(GetRawPtr(resto_curr_y_c))); SmartPtr<const Vector> resto_curr_y_d = resto_curr->y_d(); SmartPtr<const CompoundVector> cy_d = static_cast<const CompoundVector*>(GetRawPtr(resto_curr_y_d)); DBG_ASSERT(dynamic_cast<const CompoundVector*>(GetRawPtr(resto_curr_y_d))); SmartPtr<const Vector> resto_curr_z_L = resto_curr->z_L(); SmartPtr<const CompoundVector> cz_L = static_cast<const CompoundVector*>(GetRawPtr(resto_curr_z_L)); DBG_ASSERT(dynamic_cast<const CompoundVector*>(GetRawPtr(resto_curr_z_L))); SmartPtr<const Vector> resto_curr_z_U = resto_curr->z_U(); SmartPtr<const CompoundVector> cz_U = static_cast<const CompoundVector*>(GetRawPtr(resto_curr_z_U)); DBG_ASSERT(dynamic_cast<const CompoundVector*>(GetRawPtr(resto_curr_z_U))); SmartPtr<const Vector> resto_curr_v_L = resto_curr->v_L(); SmartPtr<const CompoundVector> cv_L = static_cast<const CompoundVector*>(GetRawPtr(resto_curr_v_L)); DBG_ASSERT(dynamic_cast<const CompoundVector*>(GetRawPtr(resto_curr_v_L))); SmartPtr<const Vector> resto_curr_v_U = resto_curr->v_U(); SmartPtr<const CompoundVector> cv_U = static_cast<const CompoundVector*>(GetRawPtr(resto_curr_v_U)); DBG_ASSERT(dynamic_cast<const CompoundVector*>(GetRawPtr(resto_curr_v_U))); trial->Set_primal(*cx->GetComp(0), *cs->GetComp(0)); trial->Set_eq_mult(*cy_c->GetComp(0), *cy_d->GetComp(0)); trial->Set_bound_mult(*cz_L->GetComp(0), *cz_U->GetComp(0), *cv_L->GetComp(0), *cv_U->GetComp(0)); IpData().set_trial(trial); IpData().AcceptTrialPoint(); } } if (resto_status == SUCCESS) { if (Jnlst().ProduceOutput(J_DETAILED, J_LINE_SEARCH)) { Jnlst().Printf(J_DETAILED, J_LINE_SEARCH, "\nRESTORATION PHASE RESULTS\n"); Jnlst().Printf(J_DETAILED, J_LINE_SEARCH, "\n\nOptimal solution found! \n"); Jnlst().Printf(J_DETAILED, J_LINE_SEARCH, "Optimal Objective Value = %.16E\n", resto_ip_cq->curr_f()); Jnlst().Printf(J_DETAILED, J_LINE_SEARCH, "Number of Iterations = %d\n", resto_ip_data->iter_count()); } if (Jnlst().ProduceOutput(J_VECTOR, J_LINE_SEARCH)) { resto_ip_data->curr()->Print(Jnlst(), J_VECTOR, J_LINE_SEARCH, "curr"); } retval = 0; } else if (resto_status == STOP_AT_TINY_STEP || resto_status == STOP_AT_ACCEPTABLE_POINT) { Number orig_primal_inf = IpCq().curr_primal_infeasibility(NORM_MAX); // ToDo make the factor in following line an option if (orig_primal_inf <= resto_failure_feasibility_threshold_) { Jnlst().Printf(J_WARNING, J_LINE_SEARCH, "Restoration phase converged to a point with small primal infeasibility.\n"); THROW_EXCEPTION(RESTORATION_CONVERGED_TO_FEASIBLE_POINT, "Restoration phase converged to a point with small primal infeasibility"); } else { THROW_EXCEPTION(LOCALLY_INFEASIBLE, "Restoration phase converged to a point of local infeasibility"); } } else if (resto_status == MAXITER_EXCEEDED) { THROW_EXCEPTION(RESTORATION_MAXITER_EXCEEDED, "Maximal number of iterations exceeded in restoration phase."); } else if (resto_status == CPUTIME_EXCEEDED) { THROW_EXCEPTION(RESTORATION_CPUTIME_EXCEEDED, "Maximal CPU time exceeded in restoration phase."); } else if (resto_status == LOCAL_INFEASIBILITY) { // converged to locally infeasible point - pass this on to the outer algorithm... THROW_EXCEPTION(LOCALLY_INFEASIBLE, "Restoration phase converged to a point of local infeasibility"); } else if (resto_status == RESTORATION_FAILURE) { Jnlst().Printf(J_WARNING, J_LINE_SEARCH, "Restoration phase in the restoration phase failed.\n"); THROW_EXCEPTION(RESTORATION_FAILED, "Restoration phase in the restoration phase failed."); } else if (resto_status == USER_REQUESTED_STOP) { // Use requested stop during restoration phase - rethrow exception THROW_EXCEPTION(RESTORATION_USER_STOP, "User requested stop during restoration phase"); } else { Jnlst().Printf(J_ERROR, J_MAIN, "Sorry, things failed ?!?!\n"); retval = 1; } if (retval == 0) { // Copy the results into the trial fields;. They will be // accepted later in the full algorithm SmartPtr<const Vector> resto_curr_x = resto_ip_data->curr()->x(); SmartPtr<const CompoundVector> cx = static_cast<const CompoundVector*>(GetRawPtr(resto_curr_x)); DBG_ASSERT(dynamic_cast<const CompoundVector*>(GetRawPtr(resto_curr_x))); SmartPtr<const Vector> resto_curr_s = resto_ip_data->curr()->s(); SmartPtr<const CompoundVector> cs = static_cast<const CompoundVector*>(GetRawPtr(resto_curr_s)); DBG_ASSERT(dynamic_cast<const CompoundVector*>(GetRawPtr(resto_curr_s))); SmartPtr<IteratesVector> trial = IpData().trial()->MakeNewContainer(); trial->Set_primal(*cx->GetComp(0), *cs->GetComp(0)); IpData().set_trial(trial); // If this is a square problem, we are done because a // sufficiently feasible point has been found if (square_problem) { Number constr_viol = IpCq().unscaled_curr_nlp_constraint_violation(NORM_MAX); if (constr_viol <= constr_viol_tol_) { Jnlst().Printf(J_DETAILED, J_LINE_SEARCH, "Recursive restoration phase algorithm termined successfully for square problem.\n"); IpData().AcceptTrialPoint(); THROW_EXCEPTION(FEASIBILITY_PROBLEM_SOLVED, "Restoration phase converged to sufficiently feasible point of original square problem."); } } // Update the bound multiplers, pretending that the entire // progress in x and s in the restoration phase has been one // [rimal-dual Newton step (and therefore the result of solving // an augmented system) SmartPtr<IteratesVector> delta = IpData().curr()->MakeNewIteratesVector(true); delta->Set(0.0); ComputeBoundMultiplierStep(*delta->z_L_NonConst(), *IpData().curr()->z_L(), *IpCq().curr_slack_x_L(), *IpCq().trial_slack_x_L()); ComputeBoundMultiplierStep(*delta->z_U_NonConst(), *IpData().curr()->z_U(), *IpCq().curr_slack_x_U(), *IpCq().trial_slack_x_U()); ComputeBoundMultiplierStep(*delta->v_L_NonConst(), *IpData().curr()->v_L(), *IpCq().curr_slack_s_L(), *IpCq().trial_slack_s_L()); ComputeBoundMultiplierStep(*delta->v_U_NonConst(), *IpData().curr()->v_U(), *IpCq().curr_slack_s_U(), *IpCq().trial_slack_s_U()); DBG_PRINT_VECTOR(1, "delta_z_L", *delta->z_L()); DBG_PRINT_VECTOR(1, "delta_z_U", *delta->z_U()); DBG_PRINT_VECTOR(1, "delta_v_L", *delta->v_L()); DBG_PRINT_VECTOR(1, "delta_v_U", *delta->v_U()); Number alpha_dual = IpCq().dual_frac_to_the_bound(IpData().curr_tau(), *delta->z_L_NonConst(), *delta->z_U_NonConst(), *delta->v_L_NonConst(), *delta->v_U_NonConst()); Jnlst().Printf(J_DETAILED, J_LINE_SEARCH, "Step size for bound multipliers: %8.2e\n", alpha_dual); IpData().SetTrialBoundMultipliersFromStep(alpha_dual, *delta->z_L(), *delta->z_U(), *delta->v_L(), *delta->v_U() ); // ToDo: Check what to do here: Number bound_mult_max = Max(IpData().trial()->z_L()->Amax(), IpData().trial()->z_U()->Amax(), IpData().trial()->v_L()->Amax(), IpData().trial()->v_U()->Amax()); if (bound_mult_max > bound_mult_reset_threshold_) { trial = IpData().trial()->MakeNewContainer(); Jnlst().Printf(J_DETAILED, J_LINE_SEARCH, "Bound multipliers after restoration phase too large (max=%8.2e). Set all to 1.\n", bound_mult_max); trial->create_new_z_L(); trial->create_new_z_U(); trial->create_new_v_L(); trial->create_new_v_U(); trial->z_L_NonConst()->Set(1.0); trial->z_U_NonConst()->Set(1.0); trial->v_L_NonConst()->Set(1.0); trial->v_U_NonConst()->Set(1.0); IpData().set_trial(trial); } DefaultIterateInitializer::least_square_mults( Jnlst(), IpNLP(), IpData(), IpCq(), eq_mult_calculator_, constr_mult_reset_threshold_); DBG_PRINT_VECTOR(2, "y_c", *IpData().curr()->y_c()); DBG_PRINT_VECTOR(2, "y_d", *IpData().curr()->y_d()); IpData().Set_iter_count(resto_ip_data->iter_count()-1); // Skip the next line, because it would just replicate the first // on during the restoration phase. IpData().Set_info_skip_output(true); IpData().Set_info_iters_since_header(resto_ip_data->info_iters_since_header()); IpData().Set_info_last_output(resto_ip_data->info_last_output()); } return (retval == 0); }
ESymSolverStatus WsmpSolverInterface::InternalSymFact( const Index* ia, const Index* ja, Index numberOfNegEVals) { if (HaveIpData()) { IpData().TimingStats().LinearSystemSymbolicFactorization().Start(); } // Create space for the permutations delete [] PERM_; PERM_ = NULL; delete [] INVP_; INVP_ = NULL; delete [] MRP_; MRP_ = NULL; PERM_ = new ipfint[dim_]; INVP_ = new ipfint[dim_]; MRP_ = new ipfint[dim_]; ipfint N = dim_; #ifdef PARDISO_MATCHING_PREPROCESS delete[] ia2; ia2 = NULL; delete[] ja2; ja2 = NULL; delete[] a2_; a2_ = NULL; delete[] perm2; perm2 = NULL; delete[] scale2; scale2 = NULL; ia2 = new ipfint[N+1]; ja2 = new ipfint[nonzeros_]; a2_ = new double[nonzeros_]; perm2 = new ipfint[N]; scale2 = new double[N]; ipfint* tmp2_ = new ipfint[N]; smat_reordering_pardiso_wsmp_(&N, ia, ja, a_, ia2, ja2, a2_, perm2, scale2, tmp2_, 0); delete[] tmp2_; #endif // Call WSSMP for ordering and symbolic factorization ipfint NAUX = 0; IPARM_[1] = 1; // ordering IPARM_[2] = 2; // symbolic factorization #ifdef PARDISO_MATCHING_PREPROCESS IPARM_[9] = 2; // switch off WSMP's ordering and scaling IPARM_[15] = -1; // switch off WSMP's ordering and scaling IPARM_[30] = 6; // next step supernode pivoting , since not implemented // =2 regular Bunch/Kaufman // =1 no pivots // =6 limited pivots DPARM_[21] = 2e-8; // set pivot perturbation #endif ipfint idmy; double ddmy; if (wsmp_no_pivoting_) { IPARM_[14] = dim_ - numberOfNegEVals; // CHECK Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "Restricting WSMP static pivot sequence with IPARM(15) = %d\n", IPARM_[14]); } Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "Calling WSSMP-1-2 for ordering and symbolic factorization at cpu time %10.3f (wall %10.3f).\n", CpuTime(), WallclockTime()); #ifdef PARDISO_MATCHING_PREPROCESS F77_FUNC(wssmp,WSSMP)(&N, ia2, ja2, a2_, &ddmy, PERM_, INVP_, #else F77_FUNC(wssmp,WSSMP)(&N, ia, ja, a_, &ddmy, PERM_, INVP_, #endif &ddmy, &idmy, &idmy, &ddmy, &NAUX, MRP_, IPARM_, DPARM_); Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "Done with WSSMP-1-2 for ordering and symbolic factorization at cpu time %10.3f (wall %10.3f).\n", CpuTime(), WallclockTime()); Index ierror = IPARM_[63]; if (ierror!=0) { if (ierror==-102) { Jnlst().Printf(J_ERROR, J_LINEAR_ALGEBRA, "Error: WSMP is not able to allocate sufficient amount of memory during ordering/symbolic factorization.\n"); } else if (ierror>0) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Matrix appears to be singular (with ierror = %d).\n", ierror); if (HaveIpData()) { IpData().TimingStats().LinearSystemSymbolicFactorization().End(); } return SYMSOLVER_SINGULAR; } else { Jnlst().Printf(J_ERROR, J_LINEAR_ALGEBRA, "Error in WSMP during ordering/symbolic factorization phase.\n Error code is %d.\n", ierror); } if (HaveIpData()) { IpData().TimingStats().LinearSystemSymbolicFactorization().End(); } return SYMSOLVER_FATAL_ERROR; } Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Predicted memory usage for WSSMP after symbolic factorization IPARM(23)= %d.\n", IPARM_[22]); Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Predicted number of nonzeros in factor for WSSMP after symbolic factorization IPARM(23)= %d.\n", IPARM_[23]); if (HaveIpData()) { IpData().TimingStats().LinearSystemSymbolicFactorization().End(); } return SYMSOLVER_SUCCESS; }
bool CGPerturbationHandler::PerturbForSingularity( Number& delta_x, Number& delta_s, Number& delta_c, Number& delta_d) { DBG_START_METH("CGPerturbationHandler::PerturbForSingularity", dbg_verbosity); bool retval; // Check for structural degeneracy if (hess_degenerate_ == NOT_YET_DETERMINED || jac_degenerate_ == NOT_YET_DETERMINED) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Degeneracy test for hess_degenerate_ = %d and jac_degenerate_ = %d\n test_status_ = %d\n", hess_degenerate_, jac_degenerate_, test_status_); switch (test_status_) { case TEST_DELTA_C_EQ_0_DELTA_X_EQ_0: DBG_ASSERT(delta_x_curr_ == 0. && delta_c_curr_ == 0.); // in this case we haven't tried anything for this matrix yet if (jac_degenerate_ == NOT_YET_DETERMINED) { delta_d_curr_ = delta_c_curr_ = delta_cd(); test_status_ = TEST_DELTA_C_GT_0_DELTA_X_EQ_0; } else { DBG_ASSERT(hess_degenerate_ == NOT_YET_DETERMINED); retval = get_deltas_for_wrong_inertia(delta_x, delta_s, delta_c, delta_d); if (!retval) { return false; } DBG_ASSERT(delta_c == 0. && delta_d == 0.); test_status_ = TEST_DELTA_C_EQ_0_DELTA_X_GT_0; } break; case TEST_DELTA_C_GT_0_DELTA_X_EQ_0: DBG_ASSERT(delta_x_curr_ == 0. && delta_c_curr_ > 0.); DBG_ASSERT(jac_degenerate_ == NOT_YET_DETERMINED); //if (!perturb_always_cd_) { delta_d_curr_ = delta_c_curr_ = Max(delta_cd(), CGPenCq().curr_cg_pert_fact()); //delta_d_curr_ = delta_c_curr_ = // Max(delta_cd(), CGPenCq().curr_cg_pert_fact()); if (delta_d_curr_ < delta_cd()) { test_status_ = TEST_DELTA_C_EQ_0_DELTA_X_GT_0; } else { test_status_ = TEST_DELTA_C_GT_0_DELTA_X_GT_0; } retval = get_deltas_for_wrong_inertia(delta_x, delta_s, delta_c, delta_d); if (!retval) { return false; } DBG_ASSERT(true || delta_c == 0. && delta_d == 0.); test_status_ = TEST_DELTA_C_EQ_0_DELTA_X_GT_0; //} /* else { retval = get_deltas_for_wrong_inertia(delta_x, delta_s, delta_c, delta_d); if (!retval) { return false; } DBG_ASSERT(delta_c > 0. && delta_d > 0.); test_status_ = TEST_DELTA_C_GT_0_DELTA_X_GT_0; }*/ break; case TEST_DELTA_C_EQ_0_DELTA_X_GT_0: DBG_ASSERT(delta_x_curr_ > 0. && delta_c_curr_ == 0.); delta_d_curr_ = delta_c_curr_ = Max(delta_cd(), CGPenCq().curr_cg_pert_fact()); //delta_d_curr_ = delta_c_curr_ = CGPenCq().curr_cg_pert_fact(); retval = get_deltas_for_wrong_inertia(delta_x, delta_s, delta_c, delta_d); if (!retval) { return false; } test_status_ = TEST_DELTA_C_GT_0_DELTA_X_GT_0; break; case TEST_DELTA_C_GT_0_DELTA_X_GT_0: retval = get_deltas_for_wrong_inertia(delta_x, delta_s, delta_c, delta_d); if (!retval) { return false; } break; case NO_TEST: DBG_ASSERT(false && "we should not get here."); } } else { if (delta_c_curr_ > 0. || get_deltas_for_wrong_inertia_called_) { // If we already used a perturbation for the constraints, we do // the same thing as if we were encountering negative curvature retval = get_deltas_for_wrong_inertia(delta_x, delta_s, delta_c, delta_d); if (!retval) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Can't get_deltas_for_wrong_inertia for delta_x_curr_ = %e and delta_c_curr_ = %e\n", delta_x_curr_, delta_c_curr_); return false; } } else { // Otherwise we now perturb the lower right corner delta_d_curr_ = delta_c_curr_ = delta_cd(); // ToDo - also perturb Hessian? IpData().Append_info_string("L"); Number curr_inf = IpCq().curr_primal_infeasibility(NORM_2); if (!CGPenData().NeverTryPureNewton() && curr_inf > mult_diverg_feasibility_tol_) { Number penalty = CGPenCq().compute_curr_cg_penalty_scale(); penalty = Min(penalty_max_, Max(penalty, CGPenData().curr_kkt_penalty())); CGPenData().Set_kkt_penalty(penalty); Number mach_pro = std::numeric_limits<Number>::epsilon(); delta_d_curr_ = delta_c_curr_ = Max(1e3*mach_pro,Max(CGPenCq().curr_cg_pert_fact(),delta_cd())); IpData().Append_info_string("u"); } } } delta_x = delta_x_curr_; delta_s = delta_s_curr_; delta_c = delta_c_curr_; delta_d = delta_d_curr_; IpData().Set_info_regu_x(delta_x); return true; }
ESymSolverStatus WsmpSolverInterface::Solve( const Index* ia, const Index* ja, Index nrhs, double *rhs_vals) { DBG_START_METH("WsmpSolverInterface::Solve",dbg_verbosity); if (HaveIpData()) { IpData().TimingStats().LinearSystemBackSolve().Start(); } // Call WSMP to solve for some right hand sides (including // iterative refinement) // ToDo: Make iterative refinement an option? ipfint N = dim_; ipfint LDB = dim_; ipfint NRHS = nrhs; ipfint NAUX = 0; IPARM_[1] = 4; // Forward and Backward Elimintation IPARM_[2] = 5; // Iterative refinement IPARM_[5] = 1; DPARM_[5] = 1e-12; double ddmy; Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "Calling WSSMP-4-5 for backsolve at cpu time %10.3f (wall %10.3f).\n", CpuTime(), WallclockTime()); #ifdef PARDISO_MATCHING_PREPROCESS double* X = new double[nrhs*N]; // Initialize solution with zero and save right hand side for (int i = 0; i < nrhs*N; i++) { X[perm2[i]] = scale2[i] * rhs_vals[i]; } F77_FUNC(wssmp,WSSMP)(&N, ia, ja, a_, &ddmy, PERM_, INVP_, X, &LDB, &NRHS, &ddmy, &NAUX, MRP_, IPARM_, DPARM_); for (int i = 0; i < N; i++) { rhs_vals[i] = scale2[i]*X[perm2[i]]; } #else F77_FUNC(wssmp,WSSMP)(&N, ia, ja, a_, &ddmy, PERM_, INVP_, rhs_vals, &LDB, &NRHS, &ddmy, &NAUX, MRP_, IPARM_, DPARM_); #endif Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "Done with WSSMP-4-5 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: WSMP is not able to allocate sufficient amount of memory during ordering/symbolic factorization.\n"); } else { Jnlst().Printf(J_ERROR, J_LINEAR_ALGEBRA, "Error in WSMP 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 iterative refinement steps in WSSMP: %d\n", IPARM_[5]); #ifdef PARDISO_MATCHING_PREPROCESS delete [] X; #endif return SYMSOLVER_SUCCESS; }
Number CGPerturbationHandler::delta_cd() { return delta_cd_val_ * pow(IpData().curr_mu(), delta_cd_exp_); }
ESymSolverStatus Ma27TSolverInterface::SymbolicFactorization(const Index* airn, const Index* ajcn) { DBG_START_METH("Ma27TSolverInterface::SymbolicFactorization",dbg_verbosity); if (HaveIpData()) { IpData().TimingStats().LinearSystemSymbolicFactorization().Start(); } // Get memory for the IW workspace delete [] iw_; iw_ = NULL; // Overestimation factor for LIW (20% recommended in MA27 documentation) const double LiwFact = 2.0; // This is 100% overestimation Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "In Ma27TSolverInterface::InitializeStructure: Using overestimation factor LiwFact = %e\n", LiwFact); liw_ = (ipfint)(LiwFact*(double(2*nonzeros_+3*dim_+1))); iw_ = new ipfint[liw_]; // Get memory for IKEEP delete [] ikeep_; ikeep_ = NULL; ikeep_ = new ipfint[3*dim_]; if (Jnlst().ProduceOutput(J_MOREMATRIX, J_LINEAR_ALGEBRA)) { Jnlst().Printf(J_MOREMATRIX, J_LINEAR_ALGEBRA, "\nMatrix structure given to MA27 with dimension %d and %d nonzero entries:\n", dim_, nonzeros_); for (Index i=0; i<nonzeros_; i++) { Jnlst().Printf(J_MOREMATRIX, J_LINEAR_ALGEBRA, "A[%5d,%5d]\n", airn[i], ajcn[i]); } } // Call MA27AD (cast to ipfint for Index types) ipfint N = dim_; ipfint NZ = nonzeros_; ipfint IFLAG = 0; double OPS; ipfint INFO[20]; ipfint* IW1 = new ipfint[2*dim_]; // Get memory for IW1 (only local) F77_FUNC(ma27ad,MA27AD)(&N, &NZ, airn, ajcn, iw_, &liw_, ikeep_, IW1, &nsteps_, &IFLAG, icntl_, cntl_, INFO, &OPS); delete [] IW1; // No longer required // Receive several information const ipfint &iflag = INFO[0]; // Information flag const ipfint &ierror = INFO[1]; // Error flag const ipfint &nrlnec = INFO[4]; // recommended value for la const ipfint &nirnec = INFO[5]; // recommended value for liw Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "Return values from MA27AD: IFLAG = %d, IERROR = %d\n", iflag, ierror); // Check if error occurred if (iflag!=0) { Jnlst().Printf(J_ERROR, J_LINEAR_ALGEBRA, "*** Error from MA27AD *** IFLAG = %d IERROR = %d\n", iflag, ierror); if (iflag==1) { Jnlst().Printf(J_ERROR, J_LINEAR_ALGEBRA, "The index of a matrix is out of range.\nPlease check your implementation of the Jacobian and Hessian matrices.\n"); } if (HaveIpData()) { IpData().TimingStats().LinearSystemSymbolicFactorization().End(); } return SYMSOLVER_FATAL_ERROR; } // ToDo: try and catch // Reserve memory for iw_ for later calls, based on suggested size delete [] iw_; iw_ = NULL; Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Size of integer work space recommended by MA27 is %d\n", nirnec); liw_ = (ipfint)(liw_init_factor_ * (double)(nirnec)); Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Setting integer work space size to %d\n", liw_); iw_ = new ipfint[liw_]; // Reserve memory for a_ delete [] a_; a_ = NULL; Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Size of doublespace recommended by MA27 is %d\n", nrlnec); la_ = Max(nonzeros_,(ipfint)(la_init_factor_ * (double)(nrlnec))); Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Setting double work space size to %d\n", la_); a_ = new double[la_]; if (HaveIpData()) { IpData().TimingStats().LinearSystemSymbolicFactorization().End(); } return SYMSOLVER_SUCCESS; }
bool RestoRestorationPhase::PerformRestoration() { DBG_START_METH("RestoRestorationPhase::PerformRestoration", dbg_verbosity); Jnlst().Printf(J_DETAILED, J_MAIN, "Performing second level restoration phase for current constriant violation %8.2e\n", IpCq().curr_constraint_violation()); DBG_ASSERT(IpCq().curr_constraint_violation()>0.); // Get a grip on the restoration phase NLP and obtain the pointers // to the original NLP data SmartPtr<RestoIpoptNLP> resto_ip_nlp = static_cast<RestoIpoptNLP*> (&IpNLP()); DBG_ASSERT(dynamic_cast<RestoIpoptNLP*> (&IpNLP())); SmartPtr<IpoptNLP> orig_ip_nlp = static_cast<IpoptNLP*> (&resto_ip_nlp->OrigIpNLP()); DBG_ASSERT(dynamic_cast<IpoptNLP*> (&resto_ip_nlp->OrigIpNLP())); // Get the current point and create a new vector for the result SmartPtr<const CompoundVector> Ccurr_x = static_cast<const CompoundVector*> (GetRawPtr(IpData().curr()->x())); DBG_ASSERT(dynamic_cast<const CompoundVector*> (GetRawPtr(IpData().curr()->x()))); SmartPtr<const CompoundVector> Ccurr_s = static_cast<const CompoundVector*> (GetRawPtr(IpData().curr()->s())); DBG_ASSERT(dynamic_cast<const CompoundVector*> (GetRawPtr(IpData().curr()->s()))); DBG_ASSERT(Ccurr_s->NComps() == 1); SmartPtr<Vector> new_x = IpData().curr()->x()->MakeNew(); SmartPtr<CompoundVector> Cnew_x = static_cast<CompoundVector*> (GetRawPtr(new_x)); // The x values remain unchanged SmartPtr<Vector> x = Cnew_x->GetCompNonConst(0); x->Copy(*Ccurr_x->GetComp(0)); // ToDo in free mu mode - what to do here? Number mu = IpData().curr_mu(); // Compute the initial values for the n and p variables for the // equality constraints Number rho = resto_ip_nlp->Rho(); SmartPtr<Vector> nc = Cnew_x->GetCompNonConst(1); SmartPtr<Vector> pc = Cnew_x->GetCompNonConst(2); SmartPtr<const Vector> cvec = orig_ip_nlp->c(*Ccurr_x->GetComp(0)); SmartPtr<Vector> a = nc->MakeNew(); SmartPtr<Vector> b = nc->MakeNew(); a->Set(mu/(2.*rho)); a->Axpy(-0.5, *cvec); b->Copy(*cvec); b->Scal(mu/(2.*rho)); solve_quadratic(*a, *b, *nc); pc->Copy(*cvec); pc->Axpy(1., *nc); DBG_PRINT_VECTOR(2, "nc", *nc); DBG_PRINT_VECTOR(2, "pc", *pc); // initial values for the n and p variables for the inequality // constraints SmartPtr<Vector> nd = Cnew_x->GetCompNonConst(3); SmartPtr<Vector> pd = Cnew_x->GetCompNonConst(4); SmartPtr<Vector> dvec = pd->MakeNew(); dvec->Copy(*orig_ip_nlp->d(*Ccurr_x->GetComp(0))); dvec->Axpy(-1., *Ccurr_s->GetComp(0)); a = nd->MakeNew(); b = nd->MakeNew(); a->Set(mu/(2.*rho)); a->Axpy(-0.5, *dvec); b->Copy(*dvec); b->Scal(mu/(2.*rho)); solve_quadratic(*a, *b, *nd); pd->Copy(*dvec); pd->Axpy(1., *nd); DBG_PRINT_VECTOR(2, "nd", *nd); DBG_PRINT_VECTOR(2, "pd", *pd); // Now set the trial point to the solution of the restoration phase // s and all multipliers remain unchanged SmartPtr<IteratesVector> new_trial = IpData().curr()->MakeNewContainer(); new_trial->Set_x(*new_x); IpData().set_trial(new_trial); IpData().Append_info_string("R"); return true; }