/home/coin/SVN-release/OS-2.2.0/Bonmin/src/Interfaces/Ipopt/BonIpoptInteriorWarmStarter.cpp

Go to the documentation of this file.
00001 // (C) Copyright International Business Machines Corporation 2006
00002 // All Rights Reserved.
00003 // This code is published under the Common Public License.
00004 //
00005 // $Id: BonIpoptInteriorWarmStarter.cpp 916 2007-11-19 19:11:02Z pbonami $
00006 //
00007 // Authors:  Andreas Waechter          IBM    2006-03-09
00008 
00009 #include "BonIpoptInteriorWarmStarter.hpp"
00010 #include "IpDenseVector.hpp"
00011 
00012 #include "IpIpoptData.hpp"
00013 #include "IpIpoptCalculatedQuantities.hpp"
00014 namespace Bonmin
00015 {
00016   IpoptInteriorWarmStarter::
00017   IpoptInteriorWarmStarter(Index n,
00018       const Number* x_l, const Number* x_u,
00019       Number nlp_lower_bound_inf,
00020       Number nlp_upper_bound_inf,
00021       bool store_several_iterates)
00022       :
00023       nlp_lower_bound_inf_(nlp_lower_bound_inf),
00024       nlp_upper_bound_inf_(nlp_upper_bound_inf),
00025       store_several_iterates_(store_several_iterates),
00026       n_(n),
00027       n_stored_iterates_(0)
00028   {
00029     x_l_prev_ = new double[n];
00030     x_u_prev_ = new double[n];
00031 
00032     for (Index i=0; i<n; i++) {
00033       x_l_prev_[i] = x_l[i];
00034       x_u_prev_[i] = x_u[i];
00035     }
00036   }
00037 
00038   IpoptInteriorWarmStarter::
00039   ~IpoptInteriorWarmStarter()
00040   {
00041     delete [] x_l_prev_;
00042     delete [] x_u_prev_;
00043   }
00044 
00045   bool IpoptInteriorWarmStarter::
00046   UpdateStoredIterates(AlgorithmMode mode,
00047       const IpoptData& ip_data,
00048       IpoptCalculatedQuantities& ip_cq)
00049   {
00050     // Don't store anything during the restoration phase
00051     if (mode==RestorationPhaseMode) {
00052       return true;
00053     }
00054 
00055     // Get some useful information out of the Ipopt objects
00056     Index iter = ip_data.iter_count();
00057     Number mu = ip_data.curr_mu();
00058     Number nlp_error = ip_cq.curr_nlp_error();
00059     Number primal_inf = ip_cq.curr_primal_infeasibility(NORM_MAX);
00060     Number dual_inf = ip_cq.curr_dual_infeasibility(NORM_MAX);
00061     Number complementarity = ip_cq.curr_complementarity(0., NORM_MAX);
00062     if (store_several_iterates_ || n_stored_iterates_==0) {
00063       // For now, we just store everything
00064       n_stored_iterates_++;
00065       stored_iter_.push_back(iter);
00066       stored_iterates_.push_back(ip_data.curr());
00067       stored_mu_.push_back(mu);
00068       stored_nlp_error_.push_back(nlp_error);
00069       stored_primal_inf_.push_back(primal_inf);
00070       stored_dual_inf_.push_back(dual_inf);
00071       stored_compl_.push_back(complementarity);
00072     }
00073     else {
00074       stored_iter_[0] = iter;
00075       stored_iterates_[0] = ip_data.curr();
00076       stored_mu_[0] = mu;
00077       stored_nlp_error_[0] = nlp_error;
00078       stored_primal_inf_[0] = primal_inf;
00079       stored_dual_inf_[0] = dual_inf;
00080       stored_compl_[0] = complementarity;
00081     }
00082     return true;
00083   }
00084 
00085   bool IpoptInteriorWarmStarter::
00086   Finalize()
00087   {
00088     // For now, nothing.  Later we could clean up, reduce storage etc.
00089     return true;
00090   }
00091 
00092   bool IpoptInteriorWarmStarter::
00093   WarmStartIterate(Index n, const Number* x_l_new,
00094       const Number* x_u_new,
00095       IteratesVector& warm_start_iterate)
00096   {
00097     assert(n==n_);
00098 
00099     if (n_stored_iterates_==0) {
00100       return false;
00101     }
00102 
00103     // For now let's just assume that we want to restore the 4-th latest
00104     // iterate from the previous solve
00105 
00106     Index iter_wanted = Max(0, n_stored_iterates_-5);
00107 
00108     SmartPtr<const Vector> prev_x = stored_iterates_[iter_wanted]->x();
00109     SmartPtr<const Vector> prev_s = stored_iterates_[iter_wanted]->s();
00110     SmartPtr<const Vector> prev_z_L = stored_iterates_[iter_wanted]->z_L();
00111     SmartPtr<const Vector> prev_z_U = stored_iterates_[iter_wanted]->z_U();
00112     SmartPtr<const Vector> prev_y_c = stored_iterates_[iter_wanted]->y_c();
00113     SmartPtr<const Vector> prev_y_d = stored_iterates_[iter_wanted]->y_d();
00114     SmartPtr<const Vector> prev_v_L = stored_iterates_[iter_wanted]->v_L();
00115     SmartPtr<const Vector> prev_v_U = stored_iterates_[iter_wanted]->v_U();
00116 
00117     const DenseVector* d_x = dynamic_cast<const DenseVector*> (GetRawPtr(prev_x));
00118     const DenseVector* d_s = dynamic_cast<const DenseVector*> (GetRawPtr(prev_s));
00119     const DenseVector* d_z_L = dynamic_cast<const DenseVector*> (GetRawPtr(prev_z_L));
00120     const DenseVector* d_z_U = dynamic_cast<const DenseVector*> (GetRawPtr(prev_z_U));
00121     const DenseVector* d_y_c = dynamic_cast<const DenseVector*> (GetRawPtr(prev_y_c));
00122     const DenseVector* d_y_d = dynamic_cast<const DenseVector*> (GetRawPtr(prev_y_d));
00123     const DenseVector* d_v_L = dynamic_cast<const DenseVector*> (GetRawPtr(prev_v_L));
00124     const DenseVector* d_v_U = dynamic_cast<const DenseVector*> (GetRawPtr(prev_v_U));
00125 
00126     const Number* x_vals_prev = d_x->Values();
00127     const Number* s_vals_prev = d_s->Values();
00128     const Number* z_L_vals_prev = d_z_L->Values();
00129     const Number* z_U_vals_prev = d_z_U->Values();
00130     const Number* y_c_vals_prev = d_y_c->Values();
00131     const Number* y_d_vals_prev = d_y_d->Values();
00132     const Number* v_L_vals_prev = d_v_L->Values();
00133     const Number* v_U_vals_prev = d_v_U->Values();
00134 
00135     DenseVector* d_x_new = dynamic_cast<DenseVector*> (GetRawPtr(warm_start_iterate.x_NonConst()));
00136     DenseVector* d_s_new = dynamic_cast<DenseVector*> (GetRawPtr(warm_start_iterate.s_NonConst()));
00137     DenseVector* d_z_L_new = dynamic_cast<DenseVector*> (GetRawPtr(warm_start_iterate.z_L_NonConst()));
00138     DenseVector* d_z_U_new = dynamic_cast<DenseVector*> (GetRawPtr(warm_start_iterate.z_U_NonConst()));
00139     DenseVector* d_y_c_new = dynamic_cast<DenseVector*> (GetRawPtr(warm_start_iterate.y_c_NonConst()));
00140     DenseVector* d_y_d_new = dynamic_cast<DenseVector*> (GetRawPtr(warm_start_iterate.y_d_NonConst()));
00141     DenseVector* d_v_L_new = dynamic_cast<DenseVector*> (GetRawPtr(warm_start_iterate.v_L_NonConst()));
00142     DenseVector* d_v_U_new = dynamic_cast<DenseVector*> (GetRawPtr(warm_start_iterate.v_U_NonConst()));
00143 
00144     Number* x_vals_new = d_x_new->Values();
00145     Number* s_vals_new = d_s_new->Values();
00146     Number* z_L_vals_new = d_z_L_new->Values();
00147     Number* z_U_vals_new = d_z_U_new->Values();
00148     Number* y_c_vals_new = d_y_c_new->Values();
00149     Number* y_d_vals_new = d_y_d_new->Values();
00150     Number* v_L_vals_new = d_v_L_new->Values();
00151     Number* v_U_vals_new = d_v_U_new->Values();
00152 
00153     // Now copy the primal variables from the old to the new problem;
00154     // make sure that we take care of the fixed variables
00155     Index ix_prev = 0;
00156     Index ix_new = 0;
00157     Index izL_prev = 0;
00158     Index izL_new = 0;
00159     Index izU_prev = 0;
00160     Index izU_new = 0;
00161     for (Index i=0; i<n_; i++) {
00162       if (x_l_new[i]<x_u_new[i]) {
00163         DBG_ASSERT(x_l_prev_[i]<x_u_prev_[i]);
00164         x_vals_new[ix_new] = x_vals_prev[ix_prev];
00165         ix_new++;
00166         ix_prev++;
00167         if (x_l_new[i]>nlp_lower_bound_inf_) {
00168           DBG_ASSERT(x_l_prev_[i]>nlp_lower_bound_inf_);
00169           z_L_vals_new[izL_new] = z_L_vals_prev[izL_prev];
00170           izL_new++;
00171           izL_prev++;
00172         }
00173         if (x_u_new[i]<nlp_upper_bound_inf_) {
00174           DBG_ASSERT(x_u_prev_[i]<nlp_upper_bound_inf_);
00175           z_U_vals_new[izU_new] = z_U_vals_prev[izU_prev];
00176           izU_new++;
00177           izU_prev++;
00178         }
00179       }
00180       else if (x_l_prev_[i]<x_u_prev_[i]) {
00181         ix_prev++;
00182         izL_prev++;
00183         izU_prev++;
00184       }
00185     }
00186     DBG_ASSERT(ix_prev==prev_x->Dim());
00187     DBG_ASSERT(izL_prev==prev_z_L->Dim());
00188     DBG_ASSERT(izU_prev==prev_z_U->Dim());
00189     DBG_ASSERT(ix_new==warm_start_iterate.x()->Dim());
00190     DBG_ASSERT(izL_new==warm_start_iterate.z_L()->Dim());
00191     DBG_ASSERT(izU_new==warm_start_iterate.z_U()->Dim());
00192 
00193     // Now copy all the values for the iterates that don't change in dimension
00194     DBG_ASSERT(prev_s->Dim()==warm_start_iterate.s()->Dim());
00195     DBG_ASSERT(prev_y_d->Dim()==warm_start_iterate.s()->Dim());
00196     DBG_ASSERT(prev_y_d->Dim()==warm_start_iterate.y_d()->Dim());
00197     for (Index i=0; i<prev_s->Dim(); i++) {
00198       s_vals_new[i] = s_vals_prev[i];
00199       y_d_vals_new[i] = y_d_vals_prev[i];
00200     }
00201     DBG_ASSERT(prev_y_c->Dim()==warm_start_iterate.y_c()->Dim());
00202     for (Index i=0; i<prev_y_c->Dim(); i++) {
00203       y_c_vals_new[i] = y_c_vals_prev[i];
00204     }
00205     DBG_ASSERT(prev_v_L->Dim()==warm_start_iterate.v_L()->Dim());
00206     for (Index i=0; i<prev_v_L->Dim(); i++) {
00207       v_L_vals_new[i] = v_L_vals_prev[i];
00208     }
00209     DBG_ASSERT(prev_v_U->Dim()==warm_start_iterate.v_U()->Dim());
00210     for (Index i=0; i<prev_v_U->Dim(); i++) {
00211       v_U_vals_new[i] = v_U_vals_prev[i];
00212     }
00213 
00214     return true;
00215   }
00216 }
00217 

Generated on Thu Aug 5 03:02:55 2010 by  doxygen 1.4.7