source: trunk/Bonmin/test/InterfaceTest.cpp @ 1

Last change on this file since 1 was 1, checked in by andreasw, 13 years ago

imported initial code

  • Property svn:eol-style set to native
  • Property svn:keywords set to "Author Date Id Revision"
File size: 12.3 KB
Line 
1// (C) Copyright Carnegie Mellon University 2005
2// All Rights Reserved.
3// This code is published under the Common Public License.
4//
5// Authors :
6// P. Bonami, Carnegie Mellon University
7//
8// Date :  07/01/2005
9
10#include "BonminAmplInterface.hpp"
11#include "OsiClpSolverInterface.hpp"
12#include "TMINLP.hpp"
13#include "AmplTMINLP.hpp"
14#include "IpIpoptApplication.hpp"
15/** Test function for the Osi interface to Ipopt (or any nlp solver). <br>
16    If Solver passes all the test then it should have everything needed to be integrated into bonmin. */
17
18void testGetMethods(IpoptInterface &si)
19{
20    CoinRelFltEq eq;// to test equality of doubles   
21    std::cout<<"Checking get functions"<<std::endl;
22      // Problem size
23      assert(si.getNumCols()==4);
24      assert(si.getNumRows()==3);
25     
26      //Check bounds on columns
27      const double * colLow = si.getColLower();
28      assert(eq(colLow[0],0.));
29      assert(eq(colLow[1],0.));
30      assert(eq(colLow[2],0.));
31      assert(eq(colLow[3],0.));
32     
33      const double * colUp = si.getColUpper();
34      assert(colUp[0]>si.getInfinity());
35      assert(colUp[1]>si.getInfinity());
36      assert(eq(colUp[2],1.));
37      assert(eq(colUp[3],5.));     
38      //Check bounds on rows
39      const double * rowLow = si.getRowLower();
40      assert(rowLow[0]<= -si.getInfinity());
41      assert(rowLow[1]<= -si.getInfinity());
42      assert(rowLow[2]<= -si.getInfinity());
43                 
44      const double * rowUp = si.getRowUpper();
45      assert(eq(rowUp[0], 1./4.));
46      assert(eq(rowUp[1], 0.));
47      assert(eq(rowUp[2], 2.));
48
49      //check objective sense
50      assert(si.getObjSense()==1);
51     
52      // check variables types
53      assert(si.isInteger(0)==0);
54      assert(si.isInteger(1)==0);
55      assert(si.isInteger(2)==1);
56      assert(si.isInteger(3)==1);
57     
58      assert(si.isContinuous(0)==1);
59      assert(si.isContinuous(1)==1);
60      assert(si.isContinuous(2)==0);
61      assert(si.isContinuous(3)==0);
62     
63      assert(si.isBinary(0)==0);
64      assert(si.isBinary(1)==0);
65      assert(si.isBinary(2)==1);
66      assert(si.isBinary(3)==0);
67     
68      assert(si.isIntegerNonBinary(0)==0);
69      assert(si.isIntegerNonBinary(1)==0);
70      assert(si.isIntegerNonBinary(2)==0);
71      assert(si.isIntegerNonBinary(3)==1);
72     
73      assert(si.isFreeBinary(2)==1);
74      si.setColLower(2,1.);
75      assert(si.isFreeBinary(2)==0);
76      si.setColLower(2,0.);
77     
78      assert(si.getInfinity()>1e50);
79      std::cout<<"Test passed"<<std::endl;                 
80}
81void testOptimAndSolutionQuery(IpoptInterface &si)
82{
83    CoinRelFltEq eq(1e-07);// to test equality of doubles   
84    std::cout<<"Testing optimization methods and solution query"<<std::endl;
85    si.initialSolve();
86   
87    assert(si.isProvenOptimal());
88    assert(si.nCallOptimizeTNLP()==1);
89    assert(si.getIterationCount()>0);
90    // Optimum of the problem is -( 3/2 + sqrt(5)/2)
91    // with x = (1/2 + sqrt(5) y[1]=x and y[2] = 1/2 + sqrt(5)/2
92    // (can easily be computed since constraint x-y[1]<=0 imply x = y[1] and the resulting problem has dimension 2
93    if(!eq(si.getObjValue(),-( (3./2.) + sqrt(5.)/2.)))
94        std::cout<<"Error in objective : "<<fabs(si.getObjValue()+( (3./2.) + sqrt(5.)/2.))<<std::endl;
95   
96    //Test validity of primal solution
97    const double * colsol = si.getColSolution();
98    if(!eq(colsol[0],( (1./2.) + 1/sqrt(5.))))
99        std::cout<<"Error for y[1]  : "<<fabs(colsol[0]-( (1./2.) + 1/sqrt(5.)))<<std::endl;
100    if(!eq(colsol[1],( (1./2.) + 1/(2.*sqrt(5.)))))
101        std::cout<<"Error for y[2]  : "<<fabs(colsol[1]-( (1./2.) + 1/(2*sqrt(5.))))<<std::endl;
102    if(!eq(colsol[2],( (1./2.) + 1/sqrt(5.))))
103        std::cout<<"Error for x  : "<<fabs(colsol[2]-( (1./2.) + 1/sqrt(5.)))<<std::endl;
104    //value of z is not tested
105
106    //Test for row activity
107    const double * rowAct = si.getRowActivity();
108    if(!eq(rowAct[0],1./4.))
109        std::cout<<"Error for row activity of c1 : "<<fabs(rowAct[0]-1./4.)<<std::endl;
110    if(!eq(rowAct[1],0.))
111        std::cout<<"Error for row activity of c2 : "<<fabs(rowAct[1])<<std::endl;
112       
113     //Check dual values dual for c1 = sqrt(5) c2=1 c3 not tested
114     const double * duals = si.getRowPrice();
115     if(!eq(duals[0],sqrt(5)))
116             std::cout<<"Error dual of c1 : "<<fabs(duals[0]-sqrt(5.))<<std::endl;
117     if(!eq(duals[1],1.))
118             std::cout<<"Error dual of c2 : "<<fabs(duals[0]-1.)<<std::endl;
119             
120     std::cout<<"Test passed successfully"<<std::endl;
121}
122
123///Test set methods
124void testSetMethods(IpoptInterface &si)
125{
126    CoinRelFltEq eq(1e-07);// to test equality of doubles   
127    si.setColLower(2,1.);
128    assert(si.getColLower()[2]==1.);
129    si.initialSolve();   
130    assert(si.isProvenOptimal());
131    assert(eq(si.getColSolution()[2],1));
132
133    CoinWarmStart * ws = si.getWarmStart();
134   
135   
136    si.setColLower(2,0.);
137   
138    si.setColUpper(2,0.);
139    assert(si.getColUpper()[2]==0.);
140    si.setWarmStart(ws);
141
142    si.resolve();   
143    assert(si.isProvenOptimal());
144    assert(eq(si.getColSolution()[2],0.));
145   
146    si.setColUpper(2,1.);
147    delete ws;
148}
149
150void testOa(BonminAmplInterface &si)
151{
152        CoinRelFltEq eq(1e-07);// to test equality of doubles   
153    OsiClpSolverInterface lp;
154    si.extractLinearRelaxation(lp);
155    lp.writeMps("toy");
156     assert(lp.getNumCols()==5);
157      assert(lp.getNumRows()==4);
158      //Check bounds on columns
159      const double * colLow = lp.getColLower();
160      assert(eq(colLow[0],0.));
161      assert(eq(colLow[1],0.));
162      assert(eq(colLow[2],0.));
163      assert(eq(colLow[3],0.));
164     
165      const double * colUp = lp.getColUpper();
166      assert(colUp[0]>=lp.getInfinity());
167      assert(colUp[1]>=lp.getInfinity());
168      assert(eq(colUp[2],1.));
169      assert(eq(colUp[3],5.));     
170      //Check bounds on rows
171      const double * rowLow = lp.getRowLower();
172      assert(rowLow[0]<= -lp.getInfinity());
173      assert(rowLow[1]<= -lp.getInfinity());
174      assert(rowLow[2]<= -lp.getInfinity());
175                 
176      const double * rowUp = lp.getRowUpper();
177      assert(eq(rowUp[0], 1./2. + 3./(2 * sqrt(5))));
178      assert(eq(rowUp[1], 0.));
179      assert(eq(rowUp[2], 2.));
180      assert(eq(rowUp[3], 0.));
181     
182
183      //check objective sense
184      assert(si.getObjSense()==1);
185     
186      // check variables types
187      assert(si.isInteger(0)==0);
188      assert(si.isInteger(1)==0);
189      assert(si.isInteger(2)==1);
190      assert(si.isInteger(3)==1);
191   
192       //Now check the full matrix
193       const CoinPackedMatrix * mat = lp.getMatrixByCol();
194       int  inds[11] = {0, 1, 3, 0, 2, 3, 1, 2, 3, 2, 3};
195       double vals[11] = {2. / sqrt(5) , -1., -1., 1./sqrt(5), 1. , -1. , 1. , 1., -1.,1.,-1.};
196       assert(mat->getNumElements()==11);
197       int k=0;
198       for(int i = 0 ; i < si.getNumCols() ; i++)
199       {
200        for(int j = mat->getVectorStarts()[i] ; j < mat->getVectorStarts()[i] + mat->getVectorLengths()[i] ; j++)
201        {
202        assert(inds[k]==mat->getIndices()[j]);
203        assert(eq(vals[k],mat->getElements()[j]));
204          k++;
205        }
206       }
207}
208
209void testFp(BonminAmplInterface &si)
210{
211        CoinRelFltEq eq(1e-07);// to test equality of doubles
212        OsiCuts cuts;
213        double x[1] = {0.};
214        int ind[1]={1};
215        si.getFeasibilityOuterApproximation(1,x,ind,cuts);
216        std::cout<<si.getColSolution()[0]<<std::endl;
217         std::cout<<si.getColSolution()[1]<<std::endl;
218       assert(eq(si.getColSolution()[1],(1./2.)));
219}
220void interfaceTest()
221{
222  /**********************************************************************************/
223  /*   Test constructors                                                                                                              */
224  /**********************************************************************************/
225  std::cout<<"Test IpoptInterface"<<std::endl;
226  // Test usefull constructor
227  {
228        //read a toy problem and do various tests
229//        var x binary;
230//        var z integer >= 0 <= 5;
231//        var y{1..2} >=0;
232//       
233//       
234//        minimize cost:
235//            - x - y[1] - y[2] ;
236//           
237//        subject to
238//            c1: ( y[1] - 1/2 )^2 + (y[2] - 1/2)^2 <= 1/4 ;
239//            c2: x - y[1] <= 0 ;
240//            c3: x + y[2] + z <= 2;
241       
242        //Setup Ipopt should be replaced if solver is changed
243        using namespace Ipopt;
244      SmartPtr<Ipopt::IpoptApplication> app = new Ipopt::IpoptApplication();
245       const char * args[3] ={"name","mytoy",NULL}; //Ugly, but I don't know how to do differently
246       const char ** argv = args;
247      SmartPtr<Ipopt::TMINLP> ampl_tminlp = new Ipopt::AmplTMINLP(ConstPtr(app->Jnlst()), app->Options(), const_cast<char**&>(argv));
248      IpoptInterface si(ampl_tminlp);
249    std::cout<<"---------------------------------------------------------------------------------------------------------------------------------------------------------"
250    <<std::endl<<"Testing usefull constructor"<<std::endl
251    <<"---------------------------------------------------------------------------------------------------------------------------------------------------------"<<std::endl;
252      //Start of real tests
253      testGetMethods(si);
254      testOptimAndSolutionQuery(si);
255      testSetMethods(si);
256  }
257  // Test copy constructor
258  {
259        //read a toy problem and do various tests
260//        var x binary;
261//        var z integer >= 0 <= 5;
262//        var y{1..2} >=0;
263//       
264//       
265//        minimize cost:
266//            - x - y[1] - y[2] ;
267//           
268//        subject to
269//            c1: ( y[1] - 1/2 )^2 + (y[2] - 1/2)^2 <= 1/4 ;
270//            c2: x - y[1] <= 0 ;
271//            c3: x + y[2] + z <= 2;
272       
273        //Setup Ipopt should be replaced if solver is changed
274        using namespace Ipopt;
275      SmartPtr<Ipopt::IpoptApplication> app = new Ipopt::IpoptApplication();
276      const char * args[3] ={"name","mytoy",NULL}; //Ugly, but I don't know how to do differently
277      const char ** argv = args;
278      SmartPtr<Ipopt::TMINLP> ampl_tminlp = new Ipopt::AmplTMINLP(ConstPtr(app->Jnlst()),  app->Options(), const_cast<char**&>(argv));
279      IpoptInterface si1(ampl_tminlp);
280     
281      IpoptInterface si(si1);
282    std::cout<<"---------------------------------------------------------------------------------------------------------------------------------------------------------"
283    <<std::endl<<"Testing copy constructor"<<std::endl
284    <<"---------------------------------------------------------------------------------------------------------------------------------------------------------"<<std::endl;
285      //Start of real tests
286      testGetMethods(si);
287      testOptimAndSolutionQuery(si);
288      testSetMethods(si);
289  }
290 
291    // Test outer approximation methods
292  {
293        //Setup Ipopt should be replaced if solver is changed
294        using namespace Ipopt;
295        const char * args[3] ={"name","mytoy",NULL}; //Ugly, but I don't know how to do differently
296        const char ** argv = args;
297      BonminAmplInterface si(const_cast<char**&>(argv));
298      std::cout<<"---------------------------------------------------------------------------------------------------------------------------------------------------------"
299               <<std::endl<<"Testing outer approximations related methods"<<std::endl
300               <<"---------------------------------------------------------------------------------------------------------------------------------------------------------"<<std::endl;
301      testOa(si);
302  }
303 
304  // Test Feasibility Pump methods
305//  {
306//    //Setup Ipopt should be replaced if solver is changed
307//    using namespace Ipopt;
308//    SmartPtr<Ipopt::IpoptApplication> app = new Ipopt::IpoptApplication();
309//    char * args[3] ={"name","toy3",NULL}; //Ugly, but I don't know how to do differently
310//    char ** argv = args;
311//    SmartPtr<Ipopt::TMINLP> ampl_tminlp = new Ipopt::AmplTMINLP(ConstPtr(app->Jnlst()),  app->Options(), argv);
312//    BonminAmplInterface si(ampl_tminlp);
313//    std::cout<<"---------------------------------------------------------------------------------------------------------------------------------------------------------"
314//           <<std::endl<<"Testing optimization of some distance over feasible set"<<std::endl
315//           <<"---------------------------------------------------------------------------------------------------------------------------------------------------------"<<std::endl;
316 //   testFp(si);
317//  }
318  std::cout<<"All test passed successfully"<<std::endl;
319} 
320
321int main()
322{
323    interfaceTest();
324    return 0;
325}
Note: See TracBrowser for help on using the repository browser.