source: branches/devel/Bonmin/src/Interfaces/Ipopt/BonIpoptSolver.cpp @ 96

Last change on this file since 96 was 96, checked in by pbonami, 13 years ago

Resolve small problems in unitTest

File size: 9.3 KB
RevLine 
[55]1// (C) Copyright International Business Machines (IBM) 2005
2// All Rights Reserved.
3// This code is published under the Common Public License.
4//
5// Authors :
6// Pierre Bonami, IBM
7//
8// Date : 26/09/2006
9
10
[58]11#include "BonIpoptSolver.hpp"
[55]12#include "IpSolveStatistics.hpp"
13#include "CoinError.hpp"
14
[67]15#include "BonIpoptInteriorWarmStarter.hpp"
16#include "BonIpoptWarmStart.hpp"
17
[55]18namespace Bonmin{
[81]19
20  std::string IpoptSolver::solverName_ = "Ipopt";
21
22
[55]23  IpoptSolver::~IpoptSolver(){}
24
25  ///virtual constructor
26  TNLPSolver * 
27  IpoptSolver::createNew()
28  { return new IpoptSolver();}
29
30
31  void
32  IpoptSolver::Initialize(std::string params_file)
33  {
34    app_.Initialize(params_file);
[67]35    app_.Options()->GetEnumValue("warm_start",warmStartStrategy_,"bonmin.");
[55]36    setMinlpDefaults(app_.Options());
37  }
38
39  void
40  IpoptSolver::Initialize(std::istream &is)
41  {
42    app_.Initialize(is);
[67]43    app_.Options()->GetEnumValue("warm_start",warmStartStrategy_,"bonmin.");
[64]44    setMinlpDefaults(app_.Options());
[55]45  }
46
47  TNLPSolver::ReturnStatus
48  IpoptSolver::OptimizeTNLP(const Ipopt::SmartPtr<Ipopt::TNLP> &tnlp)
49  {
50    TNLPSolver::ReturnStatus ret_status;
51    if(!zeroDimension(tnlp, ret_status))
52      {
53        optimizationStatus_ = app_.OptimizeTNLP(tnlp);
54      }
55    else
56      {
57        if(ret_status == solvedOptimal)
58          optimizationStatus_ = Ipopt::Solve_Succeeded;
59        else if(ret_status == provenInfeasible)
60          optimizationStatus_ = Ipopt::Infeasible_Problem_Detected;
61      }
[67]62
63
64
[55]65    return solverReturnStatus(optimizationStatus_);
66  }
67
68
69  TNLPSolver::ReturnStatus
70  IpoptSolver::ReOptimizeTNLP(const Ipopt::SmartPtr<Ipopt::TNLP> &tnlp)
71  {
72    TNLPSolver::ReturnStatus ret_status;
73    if(!zeroDimension(tnlp, ret_status))
74      {
75        optimizationStatus_ = app_.ReOptimizeTNLP(tnlp);
76      }
77    else
78      {
79        if(ret_status == solvedOptimal)
80          optimizationStatus_ = Ipopt::Solve_Succeeded;
81        else if(ret_status == provenInfeasible)
82          optimizationStatus_ = Ipopt::Infeasible_Problem_Detected;
83      }
[67]84      return solverReturnStatus(optimizationStatus_);
[55]85  }
86
[81]87  Ipopt::SmartPtr<Ipopt::Journalist>
88  IpoptSolver::Jnlst()
89  {return app_.Jnlst();}
90
[55]91  Ipopt::SmartPtr<Ipopt::RegisteredOptions>
92  IpoptSolver::RegOptions()
93  {
94    return app_.RegOptions();
95  }
96
97  Ipopt::SmartPtr<const Ipopt::OptionsList>
98  IpoptSolver::Options() const
99  {
100    return app_.Options();
101  }
102
103  Ipopt::SmartPtr<Ipopt::OptionsList>
104  IpoptSolver::Options()
105  {
106    return app_.Options();
107  }
108
109  /// Get the CpuTime of the last optimization.
110  double 
111  IpoptSolver::CPUTime()
112  {
113    const Ipopt::SmartPtr<Ipopt::SolveStatistics>  stats = app_.Statistics();
114    if(IsValid(stats))
115      {
116        return stats->TotalCPUTime();
117      }
118    else
119      {
120        throw CoinError("No statistics available from Ipopt","CPUTime","Bonmin::IpoptSolver");
121      }
122  }
123
124  /// Get the iteration count of the last optimization.
125  int
126  IpoptSolver::IterationCount()
127  {
128    const Ipopt::SmartPtr<Ipopt::SolveStatistics>  stats = app_.Statistics();
129    if(IsValid(stats))
130      {
131        return stats->IterationCount();
132      }
133    else
134      {
135        throw CoinError("No statistics available from Ipopt","IterationCount","Bonmin::IpoptSolver");
136      }
137  }
138
139
140  void 
141  IpoptSolver::setMinlpDefaults(Ipopt::SmartPtr<Ipopt::OptionsList> Options){
142    Options->SetNumericValue("gamma_phi", 1e-8, true, true);
143    Options->SetNumericValue("gamma_theta", 1e-4, true, true);
144    Options->SetNumericValue("required_infeasibility_reduction", 0.1, true, true);
145    Options->SetStringValue("expect_infeasible_problem","yes", true, true);
146    Options->SetStringValue("mu_strategy", "adaptive", true, true);
147    Options->SetStringValue("mu_oracle","probing", true, true);
148    Options->SetIntegerValue("print_level",1, true, true);
149  }
150
151
152  ////////////////////////////////////////////////////////////////////
153  // Methods returning info on how the solution process terminated  //
154  ////////////////////////////////////////////////////////////////////
155  /// Are there a numerical difficulties?
156  TNLPSolver::ReturnStatus IpoptSolver::solverReturnStatus(Ipopt::ApplicationReturnStatus optimization_status) const
157  {
158 
159    switch(optimization_status){
160    case Ipopt::Maximum_Iterations_Exceeded:
161    case Ipopt::User_Requested_Stop:
162      return iterationLimit;
163    case Ipopt::Restoration_Failed:
164    case Ipopt::Error_In_Step_Computation:
165    case Ipopt::Unrecoverable_Exception:
166      return computationError;
167    case Ipopt::Not_Enough_Degrees_Of_Freedom:
168    case Ipopt::Invalid_Problem_Definition:
169      return illDefinedProblem;
170    case Ipopt::Invalid_Option:
171    case Ipopt::Invalid_Number_Detected:
172      return illegalOption;
173    case Ipopt::NonIpopt_Exception_Thrown:
174      return externalException;
175    case Ipopt::Insufficient_Memory:
176    case Ipopt::Internal_Error:
177      return exception;
178    case Ipopt::Solve_Succeeded:
179      return solvedOptimal;
180    case Ipopt::Search_Direction_Becomes_Too_Small:
181      std::cerr<<"Warning : need to verify that Search_Direction_Becomes_Too_Small is indeed Ok"<<std::endl;
182    case Ipopt::Solved_To_Acceptable_Level:
183      return solvedOptimalTol;
184    case Ipopt::Infeasible_Problem_Detected:
185      return provenInfeasible;
186    case Ipopt::Diverging_Iterates:
187      return unbounded;
188    default:
189      return exception;
190    }
191  }
[67]192
193/// Get warmstarting information
194CoinWarmStart*
195IpoptSolver::getWarmStart(Ipopt::SmartPtr<TMINLP2TNLP> tnlp) const
196{
197  if(warmStartStrategy_) {
198    if(warmStartStrategy_==2) {
199        Ipopt::SmartPtr<IpoptInteriorWarmStarter> warm_starter =
200        Ipopt::SmartPtr<IpoptInteriorWarmStarter>(tnlp->GetWarmStarter());
201        return new IpoptWarmStart(tnlp, warm_starter);
202    }
203    else  return new IpoptWarmStart(tnlp, NULL);
204  }
205  else
206     return new IpoptWarmStart(tnlp->num_variables(), tnlp->num_constraints());
[55]207}
[67]208
209
210bool
211IpoptSolver::setWarmStart(const CoinWarmStart* warmstart,
212                          Ipopt::SmartPtr<TMINLP2TNLP> tnlp)
213{
[96]214  if(!warmstart && warmStartStrategy_)
[67]215    return 0;
216  const IpoptWarmStart * ws = dynamic_cast<const IpoptWarmStart*> (warmstart);
217  if(ws->empty())//reset initial point and leave
218  {
219    disableWarmStart();
220    return 1;
221  }
222  enableWarmStart();
223  int numcols = tnlp->num_variables();
224  int numrows = tnlp->num_constraints();
225  const double * colLow = tnlp->x_l();
226  const double * colUp = tnlp->x_u();
227  for(int i = 0; i < numcols ; i++) {
228    CoinWarmStartBasis::Status status = ws->getStructStatus(i);
229    if(status == CoinWarmStartBasis::atLowerBound) {
230      tnlp->setxInit(i,colLow[i]);
231      tnlp->setDualInit(i + numcols + numrows,0.);
232    }
233    else if(status == CoinWarmStartBasis::atUpperBound) {
234      tnlp->setxInit(i,colUp[i]);
235      tnlp->setDualInit(i + numrows,0.);
236    }
237    else {
238      tnlp->setDualInit(i + numrows,0.);
239      tnlp->setDualInit(i + numcols + numrows, 0.);
240    }
241  }
242  for(int i = 0; i < numrows ; i++) {
243    CoinWarmStartBasis::Status status = ws->getArtifStatus(i);
244    if(status == CoinWarmStartBasis::atLowerBound) {
245      tnlp->setDualInit(i,0.);
246    }
247  }
248  int nElem = ws->values()->getNumElements();
249  const int * inds = ws->values()->getIndices();
250  const double * elems = ws->values()->getElements();
251
252  for(int i = 0 ; i < nElem ; i++) {
253    tnlp->setxInit(inds[i],elems[i]);
254  }
255
256  if(IsValid(ws->warm_starter()))
257    tnlp->SetWarmStarter(ws->warm_starter());
258  return 1;
259}
260
261
262CoinWarmStart * 
263IpoptSolver::getEmptyWarmStart() const
264{return new IpoptWarmStart(1);}
265
266  void 
267  IpoptSolver::enableWarmStart()
268  {
269    Options()->SetStringValue("warm_start_init_point", "yes");
270  }
271
272  void 
273  IpoptSolver::disableWarmStart()
274  {
275    Options()->SetStringValue("warm_start_init_point", "no");
276  }
277
278
279  void
280  IpoptSolver::turnOffOutput(){
281  }
282
283
284  void
285  IpoptSolver::turnOnOutput(){
286  }
287
288
289/*******************************************************************************/
290// Class for throwing errors reported from Ipopt
291/******************************************************************************/
292
293std::string
294IpoptSolver::UnsolvedIpoptError::errorNames[17] ={"Solve succeeded",
295    "Solved to acceptable level",
296    "Infeasible problem detected",
297    "Search direction becomes too small",
298    "Diverging iterates",
299    "User requested stop",
300    "Maximum iterations exceeded",
301    "Restoration failed",
302    "Error in step computation",
303    "Not enough degrees of freedom",
304    "Invalid problem definition",
305    "Invalid option",
306    "Invalid number detected",
307    "Unrecoverable exception",
308    "NonIpopt exception thrown",
309    "Insufficient memory",
310    "Internal error"};
311
312const std::string &
313IpoptSolver::UnsolvedIpoptError::errorName() const
314{
315  if(errorNum() >=0)
316    return errorNames[errorNum()];
317  if(errorNum() == -1) return errorNames[6];
318  else if(errorNum() == -2) return errorNames[7];
319  else if(errorNum() == -3) return errorNames[8];
320  else if(errorNum() == -10) return errorNames[9];
321  else if(errorNum() == -11) return errorNames[10];
322  else if(errorNum() == -12) return errorNames[11];
323  else if(errorNum() == -13) return errorNames[12];
324  else if(errorNum() == -100) return errorNames[13];
325  else if(errorNum() == -101) return errorNames[14];
326  else if(errorNum() == -102) return errorNames[15];
327  else if(errorNum() == -199) return errorNames[16];
328  throw CoinError("UnsolvedError", "UnsolvedError::errorName()","Unrecognized optimization status in ipopt.");
329}
330
331std::string IpoptSolver::UnsolvedIpoptError::solverName_ = "Ipopt";
332
333const std::string &
334IpoptSolver::UnsolvedIpoptError::solverName() const
335{
336   return solverName_;
337}
338
339
340
341
342}//end namespace Bonmin
Note: See TracBrowser for help on using the repository browser.