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

Generated on Thu Nov 10 03:05:42 2011 by  doxygen 1.4.7