InterfaceTest.cpp
Go to the documentation of this file.
1 // (C) Copyright Carnegie Mellon University 2005, 2007
2 // All Rights Reserved.
3 // This code is published under the Eclipse Public License.
4 //
5 // Authors :
6 // P. Bonami, Carnegie Mellon University
7 //
8 // Date : 07/01/2005
9 
10 #include "BonminConfig.h"
11 #include "BonAmplInterface.hpp"
12 #include "OsiClpSolverInterface.hpp"
13 #include "BonTMINLP.hpp"
14 #include "IpIpoptApplication.hpp"
15 #ifdef COIN_HAS_ASL
16 #include "BonAmplTMINLP.hpp"
17 #include "BonAmplSetup.hpp"
18 #endif
19 
20 #include "BonIpoptSolver.hpp"
21 #include "BonminConfig.h"
22 
23 #ifdef COIN_HAS_FILTERSQP
24 #include "BonFilterSolver.hpp"
25 #endif
26 
27 #include "CoinError.hpp"
28 
29 #include <string>
30 #include <cmath>
31 using namespace Bonmin;
32 
33 void MyAssertFunc(bool c, const std::string &s, const std::string& file, unsigned int line){
34  if(c != true){
35  fprintf(stderr, "Failed MyAssertion: %s in %s line %i.\n", s.c_str(), file.c_str(), line);
36  exit(1);
37  }
38 }
39 
40 void DblEqAssertFunc(const double& a, const std::string &a_s, const double&b, const std::string& b_s,
41  const std::string& file, unsigned int line){
42  CoinRelFltEq eq;
43  if(!eq(a,b)){
44  fprintf(stderr, "Failed comparison: %s = %f != %s =%f in %s line %i.\n", a_s.c_str(),
45  a, b_s.c_str(), b, file.c_str(), line);
46  exit(1);
47  }
48 }
49 
50 #define MAKE_STRING(exp) std::string(#exp)
51 #define MyAssert(exp) MyAssertFunc(exp, MAKE_STRING(exp), __FILE__, __LINE__);
52 #define DblEqAssert(a,b) DblEqAssertFunc(a,MAKE_STRING(a),b,MAKE_STRING(b), __FILE__, __LINE__);
53 
54 
55 
60 {
61  CoinRelFltEq eq;// to test equality of doubles
62  std::cout<<"Checking get functions"<<std::endl;
63  // Problem size
64  MyAssert(si.getNumCols()==4);
65  MyAssert(si.getNumRows()==3);
66 
67  //Check bounds on columns
68  const double * colLow = si.getColLower();
69  DblEqAssert(colLow[0],0.);
70  DblEqAssert(colLow[1],0.);
71  DblEqAssert(colLow[2],0.);
72  DblEqAssert(colLow[3],0.);
73 
74  const double * colUp = si.getColUpper();
75  MyAssert(colUp[0]>si.getInfinity());
76  MyAssert(colUp[1]>si.getInfinity());
77  DblEqAssert(colUp[2],1.);
78  DblEqAssert(colUp[3],5.);
79  //Check bounds on rows
80  const double * rowLow = si.getRowLower();
81  MyAssert(rowLow[0]<= -si.getInfinity());
82  MyAssert(rowLow[1]<= -si.getInfinity());
83  MyAssert(rowLow[2]<= -si.getInfinity());
84 
85  const double * rowUp = si.getRowUpper();
86  DblEqAssert(rowUp[0], 1./4.);
87  DblEqAssert(rowUp[1], 0.);
88  DblEqAssert(rowUp[2], 2.);
89 
90  //check objective sense
91  MyAssert(si.getObjSense()==1);
92 
93  // check variables types
94  MyAssert(si.isInteger(0)==0);
95  MyAssert(si.isInteger(1)==0);
96  MyAssert(si.isInteger(2)==1);
97  MyAssert(si.isInteger(3)==1);
98 
99  MyAssert(si.isContinuous(0)==1);
100  MyAssert(si.isContinuous(1)==1);
101  MyAssert(si.isContinuous(2)==0);
102  MyAssert(si.isContinuous(3)==0);
103 
104  MyAssert(si.isBinary(0)==0);
105  MyAssert(si.isBinary(1)==0);
106  MyAssert(si.isBinary(2)==1);
107  MyAssert(si.isBinary(3)==0);
108 
109  MyAssert(si.isIntegerNonBinary(0)==0);
110  MyAssert(si.isIntegerNonBinary(1)==0);
111  MyAssert(si.isIntegerNonBinary(2)==0);
112  MyAssert(si.isIntegerNonBinary(3)==1);
113 
114  MyAssert(si.isFreeBinary(2)==1);
115  si.setColLower(2,1.);
116  MyAssert(si.isFreeBinary(2)==0);
117  si.setColLower(2,0.);
118 
119  //MyAssert(si.getInfinity()>1e50);
120  std::cout<<"Test passed"<<std::endl;
121 }
123 {
124  CoinRelFltEq eq(1e-07);// to test equality of doubles
125  std::cout<<"Testing optimization methods and solution query"<<std::endl;
126  si.initialSolve();
127 
129 // MyAssert(si.nCallOptimizeTNLP()==1);
130  MyAssert(si.getIterationCount()>0);
131  // Optimum of the problem is -( 3/2 + sqrt(5)/2)
132  // with x = (1/2 + sqrt(5) y[1]=x and y[2] = 1/2 + sqrt(5)/2
133  // (can easily be computed since constraint x-y[1]<=0 imply x = y[1] and the resulting problem has dimension 2
134  if(!eq(si.getObjValue(),-( (3./2.) + sqrt(5.)/2.)))
135  std::cout<<"Error in objective : "<<fabs(si.getObjValue()+( (3./2.) + sqrt(5.0)/2.))<<std::endl;
136 
137  //Test validity of primal solution
138  const double * colsol = si.getColSolution();
139  if(!eq(colsol[0],( (1./2.) + 1/sqrt(5.0))))
140  std::cout<<"Error for y[1] : "<<fabs(colsol[0]-( (1./2.) + 1/sqrt(5.0)))<<std::endl;
141  if(!eq(colsol[1],( (1./2.) + 1/(2.*sqrt(5.0)))))
142  std::cout<<"Error for y[2] : "<<fabs(colsol[1]-( (1./2.) + 1/(2*sqrt(5.0))))<<std::endl;
143  if(!eq(colsol[2],( (1./2.) + 1/sqrt(5.))))
144  std::cout<<"Error for x : "<<fabs(colsol[2]-( (1./2.) + 1/sqrt(5.0)))<<std::endl;
145  //value of z is not tested
146 
147  //Test for row activity
148  const double * rowAct = si.getRowActivity();
149  if(!eq(rowAct[0],1./4.))
150  std::cout<<"Error for row activity of c1 : "<<fabs(rowAct[0]-1./4.)<<std::endl;
151  if(!eq(rowAct[1],0.))
152  std::cout<<"Error for row activity of c2 : "<<fabs(rowAct[1])<<std::endl;
153 
154  //Check dual values dual for c1 = sqrt(5) c2=1 c3 not tested
155  const double * duals = si.getRowPrice();
156  if(!eq(duals[0],sqrt(5.0)))
157  std::cout<<"Error dual of c1 : "<<fabs(duals[0]-sqrt(5.))<<std::endl;
158  if(!eq(duals[1],1.))
159  std::cout<<"Error dual of c2 : "<<fabs(duals[0]-1.)<<std::endl;
160 
161  std::cout<<"Test passed successfully"<<std::endl;
162 }
163 
166 {
167  CoinRelFltEq eq(1e-07);// to test equality of doubles
168  si.setColLower(2,1.);
169  DblEqAssert(si.getColLower()[2],1.);
170  si.initialSolve();
172  DblEqAssert(si.getColSolution()[2],1.);
173 
174  CoinWarmStart * ws = si.getWarmStart();
175 
176 
177  si.setColLower(2,0.);
178 
179  si.setColUpper(2,0.);
180  DblEqAssert(si.getColUpper()[2],0.);
181  si.setWarmStart(ws);
182 
183  si.resolve();
185  DblEqAssert(si.getColSolution()[2],0.);
186 
187  si.setColUpper(2,1.);
188  delete ws;
189 }
190 
192 {
193  CoinRelFltEq eq(1e-07);// to test equality of doubles
194  OsiClpSolverInterface lp;
196 
197  //get tolerances
198  double tiny, very_tiny, rhs_relax, infty;
199  si.get_tolerances(tiny, very_tiny, rhs_relax, infty);
200 
201 // lp.writeMps("toy");
202  MyAssert(lp.getNumCols()==4);
203  MyAssert(lp.getNumRows()==3);
204  //Check bounds on columns
205  const double * colLow = lp.getColLower();
206  DblEqAssert(colLow[0],0.);
207  DblEqAssert(colLow[1],0.);
208  DblEqAssert(colLow[2],0.);
209  DblEqAssert(colLow[3],0.);
210 
211  const double * colUp = lp.getColUpper();
212  MyAssert(colUp[0]>=lp.getInfinity());
213  MyAssert(colUp[1]>=lp.getInfinity());
214  DblEqAssert(colUp[2],1.);
215  DblEqAssert(colUp[3],5.);
216  //Check bounds on rows
217  const double * rowLow = lp.getRowLower();
218  std::cout<<rowLow[0]<<"\t"<<lp.getInfinity()<<std::endl;
219  MyAssert(rowLow[0]<= -lp.getInfinity());
220  MyAssert(rowLow[1]<= -lp.getInfinity());
221  MyAssert(rowLow[2]<= -lp.getInfinity());
222 
223  const double * rowUp = lp.getRowUpper();
224  double sqrt5 = sqrt(5.);
225  if(!eq(rowUp[0], 1./2. + 3./(2 * sqrt5))){
226  double error = fabs(rowUp[0] - 1./2. - 3./(2 * sqrt5));
227  std::cout<<"Error in OA for rowUp[0]: "
228  <<error<<std::endl;
229  }
230  DblEqAssert(rowUp[1], 0. + rhs_relax);
231  DblEqAssert(rowUp[2], 2. * (1 + rhs_relax));
232  //DblEqAssert(rowUp[3], 0.);
233 
234 
235  //check objective sense
236  MyAssert(si.getObjSense()==1);
237 
238  // check variables types
239  MyAssert(si.isInteger(0)==0);
240  MyAssert(si.isInteger(1)==0);
241  MyAssert(si.isInteger(2)==1);
242  MyAssert(si.isInteger(3)==1);
243 
244  //Now check the full matrix
245  const CoinPackedMatrix * mat = lp.getMatrixByCol();
246  int inds[7] = {0, 1, 0, 2, 1, 2, 2};
247  double vals[7] = {2. / sqrt(5.) , -1., 1./sqrt(5.), 1. , 1. , 1., 1.};
248  MyAssert(mat->getNumElements()==7);
249  int k=0;
250  for(int i = 0 ; i < si.getNumCols() ; i++)
251  {
252  for(int j = mat->getVectorStarts()[i] ; j < mat->getVectorStarts()[i] + mat->getVectorLengths()[i] ; j++)
253  {
254  MyAssert(inds[k]==mat->getIndices()[j]);
255  if(!eq(vals[k],mat->getElements()[j])){
256  double error = fabs(vals[k] - mat->getElements()[j]);
257  std::cout<<"Error in OA for element of constraint matrix "<<k<<": "
258  <<error<<std::endl;
259  if(error > 1e-06) throw -1;
260  }
261  k++;
262  }
263  }
264 }
265 
267 {
268  CoinRelFltEq eq(1e-07);// to test equality of doubles
269  double x[1] = {0.};
270  int ind[1]={1};
271  si.solveFeasibilityProblem(1,x,ind, 0, 1);
272  std::cout<<si.getColSolution()[0]<<std::endl;
273  std::cout<<si.getColSolution()[1]<<std::endl;
274  DblEqAssert(si.getColSolution()[1],(1./2.));
275 }
277 {
278  /**********************************************************************************/
279  /* Test constructors */
280  /**********************************************************************************/
281  std::cout<<"Test OsiTMINLPInterface with "
282  <<solver->solverName()<<" solver"<<std::endl;
283  // Test usefull constructor
284 #ifdef COIN_HAS_ASL
285  {
286  //read a toy problem and do various tests
287 // var x binary;
288 // var z integer >= 0 <= 5;
289 // var y{1..2} >=0;
290 //
291 //
292 // minimize cost:
293 // - x - y[1] - y[2] ;
294 //
295 // subject to
296 // c1: ( y[1] - 1/2 )^2 + (y[2] - 1/2)^2 <= 1/4 ;
297 // c2: x - y[1] <= 0 ;
298 // c3: x + y[2] + z <= 2;
299 
300  //Setup Ipopt should be replaced if solver is changed
301  const char * args[3] ={"name","mytoy",NULL}; //Ugly, but I don't know how to do differently
302  const char ** argv = args;
303  AmplInterface amplSi;
304  amplSi.setSolver(solver);
305  BonminSetup::registerAllOptions(solver->roptions());
306  BonminAmplSetup bonmin;
307  bonmin.initialize(amplSi,const_cast<char **&>(argv));
308  OsiTMINLPInterface& si = *bonmin.nonlinearSolver();
309  si.setWarmStartMode(2);
310  std::cout<<"---------------------------------------------------------------------------------------------------------------------------------------------------------"
311  <<std::endl<<"Testing useful constructor"<<std::endl
312  <<"---------------------------------------------------------------------------------------------------------------------------------------------------------"<<std::endl;
313  //Start of real tests
314  testGetMethods(si);
316  testSetMethods(si);
317 
318  }
319  // Test copy constructor
320  {
321  //read a toy problem and do various tests
322 // var x binary;
323 // var z integer >= 0 <= 5;
324 // var y{1..2} >=0;
325 //
326 //
327 // minimize cost:
328 // - x - y[1] - y[2] ;
329 //
330 // subject to
331 // c1: ( y[1] - 1/2 )^2 + (y[2] - 1/2)^2 <= 1/4 ;
332 // c2: x - y[1] <= 0 ;
333 // c3: x + y[2] + z <= 2;
334 
335  //Setup should be replaced if solver is changed
336  const char * args[3] ={"name","mytoy",NULL}; //Ugly, but I don't know how to do differently
337  const char ** argv = args;
338  AmplInterface amplSi;
339  amplSi.setSolver(solver);
340  BonminAmplSetup bonmin;
341  bonmin.initialize(amplSi,const_cast<char **&>(argv));
342  OsiTMINLPInterface& si1 = *bonmin.nonlinearSolver();
343  si1.setWarmStartMode(2);
344 
345  OsiTMINLPInterface si(si1);
346  std::cout<<"---------------------------------------------------------------------------------------------------------------------------------------------------------"
347  <<std::endl<<"Testing copy constructor"<<std::endl
348  <<"---------------------------------------------------------------------------------------------------------------------------------------------------------"<<std::endl;
349  //Start of real tests
350  testGetMethods(si);
352  testSetMethods(si);
353  }
354 
355  // Test outer approximation methods
356  {
357  //Setup Ipopt should be replaced if solver is changed
358  const char * args[3] ={"name","mytoy",NULL}; //Ugly, but I don't know how to do differently
359  const char ** argv = args;
360  AmplInterface amplSi;
361  amplSi.setSolver(solver);
362  BonminAmplSetup bonmin;
363  bonmin.initialize(amplSi,const_cast<char **&>(argv));
364  OsiTMINLPInterface& si = *bonmin.nonlinearSolver();
365  si.setWarmStartMode(2);
366  std::cout<<"---------------------------------------------------------------------------------------------------------------------------------------------------------"
367  <<std::endl<<"Testing outer approximations related methods"<<std::endl
368  <<"---------------------------------------------------------------------------------------------------------------------------------------------------------"<<std::endl;
369  testOa(si);
370  }
371 
372  // Test Feasibility Pump methods
373 // {
374 // //Setup Ipopt should be replaced if solver is changed
375 // using namespace Ipopt;
376 // SmartPtr<Ipopt::IpoptApplication> app = new Ipopt::IpoptApplication();
377 // char * args[3] ={"name","toy3",NULL}; //Ugly, but I don't know how to do differently
378 // char ** argv = args;
379 // SmartPtr<TMINLP> ampl_tminlp = new AmplTMINLP(ConstPtr(app->Jnlst()), app->Options(), argv);
380 // Bonmin::AmplInterface si(ampl_tminlp);
381 // std::cout<<"---------------------------------------------------------------------------------------------------------------------------------------------------------"
382 // <<std::endl<<"Testing optimization of some distance over feasible set"<<std::endl
383 // <<"---------------------------------------------------------------------------------------------------------------------------------------------------------"<<std::endl;
384  // testFp(si);
385 // }
386 #endif // COIN_HAS_ASL
387  std::cout<<"All test passed successfully"<<std::endl;
388 }
389 
390 int main()
391 {
392  WindowsErrorPopupBlocker();
393 
394  Ipopt::SmartPtr<IpoptSolver> ipopt_solver = new IpoptSolver;
395  interfaceTest(GetRawPtr(ipopt_solver));
396 
397 #ifdef COIN_HAS_FILTERSQP
398  Ipopt::SmartPtr<FilterSolver> filter_solver = new FilterSolver;
399  interfaceTest(GetRawPtr(filter_solver));
400 #endif
401  return 0;
402 }
void initialize(char **&argv)
initialize bonmin with ampl model using the command line arguments.
virtual double getInfinity() const
Get solver&#39;s value for infinity.
virtual const double * getColLower() const
Get pointer to array[getNumCols()] of column lower bounds.
void testSetMethods(OsiTMINLPInterface &si)
Test set methods.
int main(int argc, char *argv[])
Definition: BB_tm.cpp:32
This is class provides an Osi interface for a Mixed Integer Linear Program expressed as a TMINLP (so ...
virtual bool isInteger(int columnNumber) const
Return true if column is integer.
void fint fint fint real * a
virtual int getNumRows() const
Get number of rows.
void MyAssertFunc(bool c, const std::string &s, const std::string &file, unsigned int line)
void testOptimAndSolutionQuery(OsiTMINLPInterface &si)
virtual int getNumCols() const
Get number of columns.
virtual bool isProvenOptimal() const
Is optimality proven?
virtual void initialSolve()
Solve initial continuous relaxation.
virtual double getObjValue() const
Get objective function value (can&#39;t use default)
static char * j
Definition: OSdtoa.cpp:3622
void DblEqAssertFunc(const double &a, const std::string &a_s, const double &b, const std::string &b_s, const std::string &file, unsigned int line)
void testFp(Bonmin::AmplInterface &si)
Class for providing an Osi interface to Ipopt with an ampl nl file as input.
double solveFeasibilityProblem(size_t n, const double *x_bar, const int *ind, double a, double s, int L)
Given a point x_bar this solves the problem of finding the point which minimize a convex combination ...
virtual const double * getColSolution() const
Get pointer to array[getNumCols()] of primal solution vector.
void fint fint fint real fint real real real real real real real real real * e
virtual void setColUpper(int elementIndex, double elementValue)
Set a single column upper bound.
virtual double getObjSense() const
Get objective function sense (1 for min (default), -1 for max) Always minimizes.
#define DblEqAssert(a, b)
static void registerAllOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Register all bonmin type executable options.
void fint fint fint real fint real real real real real real real real real fint real fint * lp
virtual void resolve()
Resolve the continuous relaxation after problem modification.
void setSolver(Ipopt::SmartPtr< TNLPSolver > app)
Set the solver to be used by interface.
void testGetMethods(OsiTMINLPInterface &si)
Test function for the Osi interface to Ipopt (or any nlp solver).
virtual bool isFreeBinary(int columnNumber) const
Return true if column is binary and not fixed at either bound.
void fint fint * k
virtual const double * getRowUpper() const
Get pointer to array[getNumRows()] of row upper bounds.
void fint fint fint fint fint fint fint fint fint fint real real real real real real real real * s
void testOa(Bonmin::OsiTMINLPInterface &si)
void setWarmStartMode(int mode)
Get an empty warm start object.
U * GetRawPtr(const OSSmartPtr< U > &smart_ptr)
Definition: OSSmartPtr.hpp:452
void fint fint fint real fint real real real real real real real real real fint real fint fint fint real * ws
virtual bool isContinuous(int colNumber) const
Return true if column is continuous.
void interfaceTest(Ipopt::SmartPtr< TNLPSolver > solver)
virtual int getIterationCount() const
Get how many iterations it took to solve the problem (whatever &quot;iteration&quot; mean to the solver...
#define MyAssert(exp)
virtual bool isIntegerNonBinary(int columnNumber) const
Return true if column is general integer.
virtual CoinWarmStart * getWarmStart() const
Get warmstarting information.
virtual const double * getRowPrice() const
Get pointer to array[getNumRows()] of dual prices.
virtual const double * getRowActivity() const
Get pointer to array[getNumRows()] of row activity levels (constraint matrix times the solution vecto...
virtual const double * getColUpper() const
Get pointer to array[getNumCols()] of column upper bounds.
OsiTMINLPInterface * nonlinearSolver()
Pointer to the non-linear solver used.
virtual const double * getRowLower() const
Get pointer to array[getNumRows()] of row lower bounds.
virtual bool isBinary(int columnNumber) const
Return true if column is binary.
virtual bool setWarmStart(const CoinWarmStart *warmstart)
Set warmstarting information.
virtual void setColLower(int elementIndex, double elementValue)
Set a single column lower bound.
virtual void extractLinearRelaxation(OsiSolverInterface &si, const double *x, bool getObj=1)
Extract a linear relaxation of the MINLP.
return b
Definition: OSdtoa.cpp:1719
real c
real infty
void fint fint fint real fint real * x