Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

OsiSolverInterfaceTest.cpp

00001 // Copyright (C) 2000, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
00003 #if defined(_MSC_VER)
00004 // Turn off compiler warning about long names
00005 #  pragma warning(disable:4786)
00006 #endif
00007  
00008 #ifdef NDEBUG
00009 #undef NDEBUG
00010 #endif
00011 #include "CoinTime.hpp"
00012 #include <cstdlib>
00013 #include <cassert>
00014 #include <vector>
00015 #include <iostream>
00016 #include <sstream>
00017 #include <cstdio>
00018 
00019 #include "OsiSolverInterface.hpp"
00020 #ifdef COIN_USE_VOL
00021 #include "OsiVolSolverInterface.hpp"
00022 #endif
00023 #ifdef COIN_USE_DYLP
00024 #include "OsiDylpSolverInterface.hpp"
00025 #endif
00026 #ifdef COIN_USE_GLPK
00027 #include "OsiGlpkSolverInterface.hpp"
00028 #endif
00029 #ifdef COIN_USE_XPR
00030 #include "OsiXprSolverInterface.hpp"
00031 #endif
00032 #ifdef COIN_USE_CPX
00033 #include "OsiCpxSolverInterface.hpp"
00034 #endif
00035 #ifdef COIN_USE_SPX
00036 #include "OsiSpxSolverInterface.hpp"
00037 #endif
00038 #ifdef COIN_USE_OSL
00039 #include "OsiOslSolverInterface.hpp"
00040 #endif
00041 #ifdef COIN_USE_CLP
00042 #include "OsiClpSolverInterface.hpp"
00043 #endif
00044 #include "CoinFloatEqual.hpp"
00045 #include "CoinPackedVector.hpp"
00046 #include "CoinPackedMatrix.hpp"
00047 #include "OsiRowCut.hpp"
00048 #include "OsiCuts.hpp"
00049 #include "OsiPresolve.hpp"
00050 
00051 //--------------------------------------------------------------------------
00052 // A helper function to write out a message about a test failure
00053 static void
00054 failureMessage(
00055                const std::string & solverName,
00056                const std::string & message )
00057 {
00058   std::string messageText;
00059   messageText = "*** ";
00060   messageText += solverName + "SolverInterface testing issue: ";
00061   messageText += message;
00062   std::cerr <<messageText.c_str() <<std::endl;
00063 }
00064 
00065 static void
00066 failureMessage(
00067                const OsiSolverInterface & si,
00068                const std::string & message )
00069 {
00070   std::string solverName;
00071   si.getStrParam(OsiSolverName,solverName);
00072   failureMessage(solverName,message);
00073 }
00074 
00075 //--------------------------------------------------------------------------
00076 // A helper function to compare the equivalence of two vectors 
00077 static bool
00078 equivalentVectors(const OsiSolverInterface * si1,
00079                   const OsiSolverInterface * si2,
00080                   double tol,
00081                   const double * v1,
00082                   const double * v2,
00083                   int size)
00084 {
00085   bool retVal = true;
00086   CoinRelFltEq eq(tol);
00087   int i;
00088   for ( i=0; i<size; i++ ) {
00089     
00090     // If both are equal to infinity then iterate
00091     if ( fabs(v1[i])==si1->getInfinity() && fabs(v2[i])==si2->getInfinity() )
00092        continue;
00093     
00094     // Test to see if equal
00095     if ( !eq(v1[i],v2[i]) ) {
00096       std::cerr <<"eq " <<i <<" " <<v1[i] <<" " <<v2[i] <<std::endl;
00097       //const OsiOslSolverInterface * oslSi = dynamic_cast<const OsiOslSolverInterface*>(si1);
00098       //assert(oslSi != NULL);
00099       //EKKModel * m = ((OsiOslSolverInterface*)oslSi)->modelPtr();
00100       //ekk_printSolution(m);
00101       retVal = false;
00102       break;
00103     }
00104 
00105   }
00106   return retVal;
00107 }
00108 
00109 //--------------------------------------------------------------------------
00110 bool test1VivianDeSmedt(OsiSolverInterface *s)
00111 {
00112         bool ret = true;
00113 
00114         double inf = s->getInfinity();
00115 
00116         CoinPackedMatrix m;
00117 
00118         m.transpose();
00119 
00120         CoinPackedVector r0;
00121         r0.insert(0, 2);
00122         r0.insert(1, 1);
00123         m.appendRow(r0);
00124 
00125         CoinPackedVector r1;
00126         r1.insert(0, 1);
00127         r1.insert(1, 3);
00128         m.appendRow(r1);
00129 
00130         int numcol = 2;
00131 
00132         double *obj = new double[numcol];
00133         obj[0] = 3;
00134         obj[1] = 1;
00135 
00136         double *collb = new double[numcol];
00137         collb[0] = 0;
00138         collb[1] = 0;
00139 
00140         double *colub = new double[numcol];
00141         colub[0] = inf;
00142         colub[1] = inf;
00143 
00144         int numrow = 2;
00145 
00146         double *rowlb = new double[numrow];
00147         rowlb[0] = -inf;
00148         rowlb[1] = -inf;
00149 
00150         double *rowub = new double[numrow];
00151         rowub[0] = 10;
00152         rowub[1] = 15;
00153 
00154         s->loadProblem(m, collb, colub, obj, rowlb, rowub);
00155 
00156         delete [] obj;
00157         delete [] collb;
00158         delete [] colub;
00159 
00160         delete [] rowlb;
00161         delete [] rowub;
00162 
00163         s->setObjSense(-1);
00164 
00165         s->initialSolve();
00166 
00167         ret = ret && s->isProvenOptimal();
00168         ret = ret && !s->isProvenPrimalInfeasible();
00169         ret = ret && !s->isProvenDualInfeasible();
00170 
00171         const double solution1[] = {5, 0};
00172         ret = ret && equivalentVectors(s,s,0.0001, s->getColSolution(), solution1, 2);
00173 
00174         const double activity1[] = {10, 5};
00175         ret = ret && equivalentVectors(s,s,0.0001, s->getRowActivity(), activity1, 2);
00176 
00177         s->setObjCoeff(0, 1);
00178         s->setObjCoeff(1, 1);
00179 
00180         s->resolve();
00181 
00182         ret = ret && s->isProvenOptimal();
00183         ret = ret && !s->isProvenPrimalInfeasible();
00184         ret = ret && !s->isProvenDualInfeasible();
00185 
00186         const double solution2[] = {3, 4};
00187         ret = ret && equivalentVectors(s,s,0.0001, s->getColSolution(), solution2, 2);
00188 
00189         const double activity2[] = {10, 15};
00190         ret = ret && equivalentVectors(s,s,0.0001, s->getRowActivity(), activity2, 2);
00191 
00192         return ret;
00193 }
00194 
00195 //--------------------------------------------------------------------------
00196 bool test2VivianDeSmedt(OsiSolverInterface *s)
00197 {
00198         bool ret = true;
00199 
00200         double inf = s->getInfinity();
00201 
00202         CoinPackedMatrix m;
00203 
00204         m.transpose();
00205 
00206         CoinPackedVector r0;
00207         r0.insert(0, 2);
00208         r0.insert(1, 1);
00209         m.appendRow(r0);
00210 
00211         CoinPackedVector r1;
00212         r1.insert(0, 1);
00213         r1.insert(1, 3);
00214         m.appendRow(r1);
00215 
00216         CoinPackedVector r2;
00217         r2.insert(0, 1);
00218         r2.insert(1, 1);
00219         m.appendRow(r2);
00220 
00221         int numcol = 2;
00222 
00223         double *obj = new double[numcol];
00224         obj[0] = 3;
00225         obj[1] = 1;
00226 
00227         double *collb = new double[numcol];
00228         collb[0] = 0;
00229         collb[1] = 0;
00230 
00231         double *colub = new double[numcol];
00232         colub[0] = inf;
00233         colub[1] = inf;
00234 
00235         int numrow = 3;
00236 
00237         double *rowlb = new double[numrow];
00238         rowlb[0] = -inf;
00239         rowlb[1] = -inf;
00240         rowlb[2] = 1;
00241 
00242         double *rowub = new double[numrow];
00243         rowub[0] = 10;
00244         rowub[1] = 15;
00245         rowub[2] = inf;
00246 
00247         s->loadProblem(m, collb, colub, obj, rowlb, rowub);
00248 
00249         delete [] obj;
00250         delete [] collb;
00251         delete [] colub;
00252 
00253         delete [] rowlb;
00254         delete [] rowub;
00255 
00256         s->setObjSense(-1);
00257 
00258         s->initialSolve();
00259 
00260         ret = ret && s->isProvenOptimal();
00261         ret = ret && !s->isProvenPrimalInfeasible();
00262         ret = ret && !s->isProvenDualInfeasible();
00263 
00264         const double solution1[] = {5, 0};
00265         ret = ret && equivalentVectors(s,s,0.0001, s->getColSolution(), solution1, 2);
00266 
00267         const double activity1[] = {10, 5, 5};
00268         ret = ret && equivalentVectors(s,s,0.0001, s->getRowActivity(), activity1, 3);
00269 
00270         s->setObjCoeff(0, 1);
00271         s->setObjCoeff(1, 1);
00272 
00273         s->resolve();
00274 
00275         ret = ret && s->isProvenOptimal();
00276         ret = ret && !s->isProvenPrimalInfeasible();
00277         ret = ret && !s->isProvenDualInfeasible();
00278 
00279         const double solution2[] = {3, 4};
00280         ret = ret && equivalentVectors(s,s,0.0001, s->getColSolution(), solution2, 2);
00281 
00282         const double activity2[] = {10, 15, 7};
00283         ret = ret && equivalentVectors(s,s,0.0001, s->getRowActivity(), activity2, 3);
00284 
00285   return ret;
00286 }
00287 
00288 
00289 //--------------------------------------------------------------------------
00290 bool test3VivianDeSmedt(OsiSolverInterface *s)
00291 {
00292         bool ret = true;
00293 
00294         //double inf = s->getInfinity();
00295 
00296         CoinPackedVector empty;
00297 
00298         s->addCol(empty, 0, 10, 3);
00299         s->addCol(empty, 0, 10, 1);
00300 
00301         CoinPackedVector r0;
00302         r0.insert(0, 2);
00303         r0.insert(1, 1);
00304         s->addRow(r0, 0, 10);
00305 
00306         CoinPackedVector r1;
00307         r1.insert(0, 1);
00308         r1.insert(1, 3);
00309         s->addRow(r1, 0, 15);
00310 
00311         s->setObjSense(-1);
00312 
00313         s->writeMps("test");
00314 
00315         s->initialSolve();
00316 
00317         ret = ret && s->isProvenOptimal();
00318         ret = ret && !s->isProvenPrimalInfeasible();
00319         ret = ret && !s->isProvenDualInfeasible();
00320 
00321         const double solution1[] = {5, 0};
00322         ret = ret && equivalentVectors(s,s,0.0001,s->getColSolution(), solution1, 2);
00323 
00324         const double activity1[] = {10, 5};
00325         ret = ret && equivalentVectors(s,s,0.0001,s->getRowActivity(), activity1, 2);
00326 
00327         s->setObjCoeff(0, 1);
00328         s->setObjCoeff(1, 1);
00329 
00330         s->resolve();
00331 
00332         ret = ret && s->isProvenOptimal();
00333         ret = ret && !s->isProvenPrimalInfeasible();
00334         ret = ret && !s->isProvenDualInfeasible();
00335 
00336         const double solution2[] = {3, 4};
00337         ret = ret && equivalentVectors(s,s,0.0001,s->getColSolution(), solution2, 2);
00338 
00339         const double activity2[] = {10, 15};
00340         ret = ret && equivalentVectors(s,s,0.0001,s->getRowActivity(), activity2, 2);
00341 
00342         return ret;
00343 }
00344 
00345 //--------------------------------------------------------------------------
00346 bool test4VivianDeSmedt(OsiSolverInterface *s)
00347 {
00348         bool ret = true;
00349 
00350         double inf = s->getInfinity();
00351 
00352         CoinPackedVector empty;
00353 
00354         s->addCol(empty, 0, inf, 3);
00355         s->addCol(empty, 0, inf, 1);
00356 
00357         CoinPackedVector r0;
00358         r0.insert(0, 2);
00359         r0.insert(1, 1);
00360         s->addRow(r0, -inf, 10);
00361 
00362         CoinPackedVector r1;
00363         r1.insert(0, 1);
00364         r1.insert(1, 3);
00365         s->addRow(r1, -inf, 15);
00366 
00367         s->setObjSense(-1);
00368 
00369         s->writeMps("test");
00370 
00371         s->initialSolve();
00372 
00373         ret = ret && s->isProvenOptimal();
00374         ret = ret && !s->isProvenPrimalInfeasible();
00375         ret = ret && !s->isProvenDualInfeasible();
00376 
00377         const double solution1[] = {5, 0};
00378         ret = ret && equivalentVectors(s,s,0.0001,s->getColSolution(), solution1, 2);
00379 
00380         const double activity1[] = {10, 5};
00381         ret = ret && equivalentVectors(s,s,0.0001,s->getRowActivity(), activity1, 2);
00382 
00383         s->setObjCoeff(0, 1);
00384         s->setObjCoeff(1, 1);
00385 
00386         s->resolve();
00387 
00388         ret = ret && s->isProvenOptimal();
00389         ret = ret && !s->isProvenPrimalInfeasible();
00390         ret = ret && !s->isProvenDualInfeasible();
00391 
00392         const double solution2[] = {3, 4};
00393         ret = ret && equivalentVectors(s,s,0.0001,s->getColSolution(), solution2, 2);
00394 
00395         const double activity2[] = {10, 15};
00396         ret = ret && equivalentVectors(s,s,0.0001,s->getRowActivity(), activity2, 2);
00397 
00398         return ret;
00399 }
00400 
00401 //--------------------------------------------------------------------------
00402 
00403 /*
00404   Constructs the system
00405 
00406      max    3x1 +  x2
00407 
00408     -inf <= 2x1 +  x2 <= 10
00409     -inf <=  x1 + 3x2 <= 15
00410 
00411   The optimal solution is unbounded. Objective is then changed to
00412 
00413      max     x1 +  x2
00414 
00415   which has a bounded optimum at x1 = 3, x2 = 4.
00416 */
00417 
00418 bool test5VivianDeSmedt(OsiSolverInterface *s)
00419 {
00420         bool ret = true;
00421 
00422         double inf = s->getInfinity();
00423 
00424         CoinPackedVector empty;
00425 
00426         s->addCol(empty, -inf, inf, 3);
00427         s->addCol(empty, -inf, inf, 1);
00428 
00429         CoinPackedVector r0;
00430         r0.insert(0, 2);
00431         r0.insert(1, 1);
00432         s->addRow(r0, -inf, 10);
00433 
00434         CoinPackedVector r1;
00435         r1.insert(0, 1);
00436         r1.insert(1, 3);
00437         s->addRow(r1, -inf, 15);
00438 
00439         s->setObjSense(-1);
00440 
00441         s->writeMps("test");
00442 /*
00443   Clp problem here --- if the call to initialSolve() is changed to resolve(),
00444   Clp comes up with the correct answer.
00445 
00446   #ifdef COIN_USE_CLP
00447     bool ClpSolverInterface = false ;
00448     const OsiClpSolverInterface * si =
00449       dynamic_cast<const OsiClpSolverInterface *>(s);
00450     if ( si != NULL ) ClpSolverInterface = true;
00451   #endif
00452 
00453         if (ClpSolverInterface)
00454           s->resolve() ;
00455         else
00456 */
00457           s->initialSolve();
00458 
00459         ret = ret && !s->isProvenOptimal();
00460         ret = ret && !s->isProvenPrimalInfeasible();
00461         ret = ret && s->isProvenDualInfeasible();
00462 
00463         s->setObjCoeff(0, 1);
00464         s->setObjCoeff(1, 1);
00465 
00466         s->resolve();
00467 
00468         ret = ret && s->isProvenOptimal();
00469         ret = ret && !s->isProvenPrimalInfeasible();
00470         ret = ret && !s->isProvenDualInfeasible();
00471 
00472         const double solution2[] = {3, 4};
00473         ret = ret && equivalentVectors(s,s,0.0001,s->getColSolution(), solution2, 2);
00474 
00475         const double activity2[] = {10, 15};
00476         ret = ret && equivalentVectors(s,s,0.0001,s->getRowActivity(), activity2, 2);
00477 
00478         return ret;
00479 }
00480 
00481 //--------------------------------------------------------------------------
00482 
00483 
00484 bool test6VivianDeSmedt(OsiSolverInterface *s)
00485 {
00486         bool ret = true;
00487 
00488         double inf = s->getInfinity();
00489 
00490         CoinPackedVector empty;
00491 
00492         s->addCol(empty, 0, inf, 3);
00493         s->addCol(empty, 0, inf, 1);
00494 
00495         CoinPackedVector r0;
00496         r0.insert(0, 2);
00497         r0.insert(1, 1);
00498         s->addRow(r0, 0, 10);
00499 
00500         CoinPackedVector r1;
00501         r1.insert(0, 1);
00502         r1.insert(1, 3);
00503         s->addRow(r1, 0, 15);
00504 
00505         s->setObjSense(-1);
00506 
00507         s->writeMps("test");
00508 
00509         s->initialSolve();
00510 
00511         ret = ret && s->isProvenOptimal();
00512         ret = ret && !s->isProvenPrimalInfeasible();
00513         ret = ret && !s->isProvenDualInfeasible();
00514 
00515         const double solution1[] = {5, 0};
00516         ret = ret && equivalentVectors(s,s,0.0001,s->getColSolution(), solution1, 2);
00517 
00518         const double activity1[] = {10, 5};
00519         ret = ret && equivalentVectors(s,s,0.0001,s->getRowActivity(), activity1, 2);
00520 
00521         s->setObjCoeff(0, 1);
00522         s->setObjCoeff(1, 1);
00523 
00524         s->resolve();
00525 
00526         ret = ret && s->isProvenOptimal();
00527         ret = ret && !s->isProvenPrimalInfeasible();
00528         ret = ret && !s->isProvenDualInfeasible();
00529 
00530         const double solution2[] = {3, 4};
00531         ret = ret && equivalentVectors(s,s,0.0001,s->getColSolution(), solution2, 2);
00532 
00533         const double activity2[] = {10, 15};
00534         ret = ret && equivalentVectors(s,s,0.0001,s->getRowActivity(), activity2, 2);
00535 
00536         return ret;
00537 }
00538 
00539 //--------------------------------------------------------------------------
00540 
00541 
00542 bool test7VivianDeSmedt(OsiSolverInterface *s)
00543 {
00544         bool ret = true;
00545 
00546         double inf = s->getInfinity();
00547 
00548         CoinPackedVector empty;
00549 
00550         s->addCol(empty, 4, inf, 3);
00551         s->addCol(empty, 3, inf, 1);
00552 
00553         CoinPackedVector r0;
00554         r0.insert(0, 2);
00555         r0.insert(1, 1);
00556         s->addRow(r0, 0, 10);
00557 
00558         CoinPackedVector r1;
00559         r1.insert(0, 1);
00560         r1.insert(1, 3);
00561         s->addRow(r1, 0, 15);
00562 
00563         s->setObjSense(-1);
00564 
00565         s->writeMps("test");
00566 
00567         s->initialSolve();
00568 
00569         ret = ret && !s->isProvenOptimal();
00570         ret = ret && s->isProvenPrimalInfeasible();
00571 
00572         s->setObjCoeff(0, 1);
00573         s->setObjCoeff(1, 1);
00574 
00575         s->resolve();
00576 
00577         ret = ret && !s->isProvenOptimal();
00578         ret = ret && s->isProvenPrimalInfeasible();
00579 
00580         return ret;
00581 }
00582 
00583 //--------------------------------------------------------------------------
00584 
00585 bool test8VivianDeSmedt(OsiSolverInterface *s)
00586 {
00587         bool ret = true;
00588 
00589         double inf = s->getInfinity();
00590 
00591         CoinPackedVector empty;
00592 
00593         s->addCol(empty, -inf, inf, 3);
00594         s->addCol(empty, -inf, inf, 1);
00595 
00596         CoinPackedVector r0;
00597         r0.insert(0, 2);
00598         r0.insert(1, 1);
00599         s->addRow(r0, 0, 10);
00600 
00601         CoinPackedVector r1;
00602         r1.insert(0, 1);
00603         r1.insert(1, 3);
00604         s->addRow(r1, 0, 15);
00605 
00606         s->setObjSense(-1);
00607 
00608         s->writeMps("test");
00609 
00610         s->initialSolve();
00611 
00612         ret = ret && s->isProvenOptimal();
00613         ret = ret && !s->isProvenPrimalInfeasible();
00614         ret = ret && !s->isProvenDualInfeasible();
00615 
00616         const double solution1[] = {6, -2};
00617         ret = ret && equivalentVectors(s,s,0.0001,s->getColSolution(), solution1, 2);
00618 
00619         const double activity1[] = {10, 0};
00620         ret = ret && equivalentVectors(s,s,0.0001,s->getRowActivity(), activity1, 2);
00621 
00622         s->setObjCoeff(0, 1);
00623         s->setObjCoeff(1, 1);
00624 
00625         s->resolve();
00626 
00627         ret = ret && s->isProvenOptimal();
00628         ret = ret && !s->isProvenPrimalInfeasible();
00629         ret = ret && !s->isProvenDualInfeasible();
00630 
00631         const double solution2[] = {3, 4};
00632         ret = ret && equivalentVectors(s,s,0.0001,s->getColSolution(), solution2, 2);
00633 
00634         const double activity2[] = {10, 15};
00635         ret = ret && equivalentVectors(s,s,0.0001,s->getRowActivity(), activity2, 2);
00636 
00637         return ret;
00638 }
00639 
00640 //--------------------------------------------------------------------------
00641 
00642 bool test9VivianDeSmedt(OsiSolverInterface *s)
00643 {
00644         bool ret = true;
00645 
00646         double inf = s->getInfinity();
00647 
00648         CoinPackedVector empty;
00649 
00650         s->addCol(empty, -inf, inf, 3);
00651         s->addCol(empty, -inf, inf, 1);
00652 
00653         CoinPackedVector r0;
00654         r0.insert(0, 2);
00655         r0.insert(1, 1);
00656         s->addRow(r0, 0, 10);
00657 
00658         CoinPackedVector r1;
00659         r1.insert(0, 1);
00660         r1.insert(1, 3);
00661         s->addRow(r1, 0, 15);
00662 
00663         CoinPackedVector r2;
00664         r2.insert(0, 1);
00665         r2.insert(1, 4);
00666         s->addRow(r2, 12, inf);
00667 
00668         s->setObjSense(-1);
00669 
00670         s->writeMps("test");
00671 
00672         s->initialSolve();
00673 
00674         ret = ret && s->isProvenOptimal();
00675         ret = ret && !s->isProvenPrimalInfeasible();
00676         ret = ret && !s->isProvenDualInfeasible();
00677 
00678         const double solution1[] = {4, 2};
00679         ret = ret && equivalentVectors(s,s,0.0001,s->getColSolution(), solution1, 2);
00680 
00681         const double activity1[] = {10, 10, 12};
00682         ret = ret && equivalentVectors(s,s,0.0001,s->getRowActivity(), activity1, 3);
00683 
00684         s->setObjCoeff(0, 1);
00685         s->setObjCoeff(1, 1);
00686 
00687         s->resolve();
00688 
00689         ret = ret && s->isProvenOptimal();
00690         ret = ret && !s->isProvenPrimalInfeasible();
00691         ret = ret && !s->isProvenDualInfeasible();
00692 
00693         const double solution2[] = {3, 4};
00694         ret = ret && equivalentVectors(s,s,0.0001,s->getColSolution(), solution2, 2);
00695 
00696         const double activity2[] = {10, 15, 19};
00697         ret = ret && equivalentVectors(s,s,0.0001,s->getRowActivity(), activity2, 3);
00698 
00699         return ret;
00700 }
00701 
00702 //--------------------------------------------------------------------------
00703 
00704 bool test10VivianDeSmedt(OsiSolverInterface *s)
00705 {
00706         bool ret = true;
00707 
00708         double inf = s->getInfinity();
00709 
00710         int numcols = 2;
00711         int numrows = 2;
00712         const int start[] = {0, 2, 4};
00713         const int index[] = {0, 1, 0, 1};
00714         const double value[] = {4, 1, 2, 3};
00715         const double collb[] = {0, 0};
00716         const double colub[] = {inf, inf};
00717         double obj[] = {3, 1};
00718         char rowsen[] = {'R', 'R'};
00719         double rowrhs[] = {20, 15};
00720         double rowrng[] = {20, 15};
00721 
00722         s->loadProblem(numcols, numrows, start, index, value, collb, colub, obj, rowsen, rowrhs, rowrng);
00723 
00724         s->setObjSense(-1);
00725 
00726         s->writeMps("test");
00727 
00728         s->initialSolve();
00729 
00730         ret = ret && s->isProvenOptimal();
00731         ret = ret && !s->isProvenPrimalInfeasible();
00732         ret = ret && !s->isProvenDualInfeasible();
00733 
00734         const double solution1[] = {5, 0};
00735         ret = ret && equivalentVectors(s,s,0.0001,s->getColSolution(), solution1, 2);
00736 
00737         const double activity1[] = {20, 5};
00738         ret = ret && equivalentVectors(s,s,0.0001,s->getRowActivity(), activity1, 2);
00739 
00740         s->setObjCoeff(0, 1);
00741         s->setObjCoeff(1, 1);
00742 
00743         s->resolve();
00744 
00745         ret = ret && s->isProvenOptimal();
00746         ret = ret && !s->isProvenPrimalInfeasible();
00747         ret = ret && !s->isProvenDualInfeasible();
00748 
00749         const double solution2[] = {3, 4};
00750         ret = ret && equivalentVectors(s,s,0.0001,s->getColSolution(), solution2, 2);
00751 
00752         const double activity2[] = {20, 15};
00753         ret = ret && equivalentVectors(s,s,0.0001,s->getRowActivity(), activity2, 2);
00754 
00755         return ret;
00756 }
00757 
00758 //--------------------------------------------------------------------------
00759 bool test11VivianDeSmedt(OsiSolverInterface *s)
00760 {
00761         bool ret = true;
00762 
00763         double inf = s->getInfinity();
00764 
00765         int numcols = 2;
00766         int numrows = 2;
00767         const int start[] = {0, 2, 4};
00768         const int index[] = {0, 1, 0, 1};
00769         const double value[] = {4, 1, 2, 3};
00770         const double collb[] = {0, 0};
00771         const double colub[] = {inf, inf};
00772         double obj[] = {3, 1};
00773         double rowlb[] = {0, 0};
00774         double rowub[] = {20, 15};
00775 
00776         s->loadProblem(numcols, numrows, start, index, value, collb, colub, obj, rowlb, rowub);
00777 
00778         s->setObjSense(-1);
00779 
00780         s->writeMps("test");
00781 
00782         s->initialSolve();
00783 
00784         ret = ret && s->isProvenOptimal();
00785         ret = ret && !s->isProvenPrimalInfeasible();
00786         ret = ret && !s->isProvenDualInfeasible();
00787 
00788         const double solution1[] = {5, 0};
00789         ret = ret && equivalentVectors(s,s,0.0001,s->getColSolution(), solution1, 2);
00790 
00791         const double activity1[] = {20, 5};
00792         ret = ret && equivalentVectors(s,s,0.0001,s->getRowActivity(), activity1, 2);
00793 
00794         s->setObjCoeff(0, 1);
00795         s->setObjCoeff(1, 1);
00796 
00797         s->resolve();
00798 
00799         ret = ret && s->isProvenOptimal();
00800         ret = ret && !s->isProvenPrimalInfeasible();
00801         ret = ret && !s->isProvenDualInfeasible();
00802 
00803         const double solution2[] = {3, 4};
00804         ret = ret && equivalentVectors(s,s,0.0001,s->getColSolution(), solution2, 2);
00805 
00806         const double activity2[] = {20, 15};
00807         ret = ret && equivalentVectors(s,s,0.0001,s->getRowActivity(), activity2, 2);
00808 
00809         return ret;
00810 }
00811 
00812 //--------------------------------------------------------------------------
00813 
00814 bool test12VivianDeSmedt(OsiSolverInterface *s)
00815 {
00816         bool ret = true;
00817 
00818         double inf = s->getInfinity();
00819 
00820         CoinPackedMatrix m;
00821 
00822         m.transpose();
00823 
00824         CoinPackedVector r0;
00825         r0.insert(0, 4);
00826         r0.insert(1, 2);
00827         m.appendRow(r0);
00828 
00829         CoinPackedVector r1;
00830         r1.insert(0, 1);
00831         r1.insert(1, 3);
00832         m.appendRow(r1);
00833 
00834         int numcol = 2;
00835 
00836         double *obj = new double[numcol];
00837         obj[0] = 3;
00838         obj[1] = 1;
00839 
00840         double *collb = new double[numcol];
00841         collb[0] = 0;
00842         collb[1] = 0;
00843 
00844         double *colub = new double[numcol];
00845         colub[0] = inf;
00846         colub[1] = inf;
00847 
00848         int numrow = 2;
00849 
00850         double *rowlb = new double[numrow];
00851         rowlb[0] = 0;
00852         rowlb[1] = 0;
00853 
00854         double *rowub = new double[numrow];
00855         rowub[0] = 20;
00856         rowub[1] = 15;
00857 
00858         s->loadProblem(m, collb, colub, obj, rowlb, rowub);
00859 
00860         delete [] obj;
00861         delete [] collb;
00862         delete [] colub;
00863 
00864         delete [] rowlb;
00865         delete [] rowub;
00866 
00867         s->setObjSense(-1);
00868 
00869         s->initialSolve();
00870 
00871         ret = ret && s->isProvenOptimal();
00872         ret = ret && !s->isProvenPrimalInfeasible();
00873         ret = ret && !s->isProvenDualInfeasible();
00874 
00875         const double solution1[] = {5, 0};
00876         ret = ret && equivalentVectors(s,s,0.0001,s->getColSolution(), solution1, 2);
00877 
00878         const double activity1[] = {20, 5};
00879         ret = ret && equivalentVectors(s,s,0.0001,s->getRowActivity(), activity1, 2);
00880 
00881         s->setObjCoeff(0, 1);
00882         s->setObjCoeff(1, 1);
00883 
00884         s->resolve();
00885 
00886         ret = ret && s->isProvenOptimal();
00887         ret = ret && !s->isProvenPrimalInfeasible();
00888         ret = ret && !s->isProvenDualInfeasible();
00889 
00890         const double solution2[] = {3, 4};
00891         ret = ret && equivalentVectors(s,s,0.0001,s->getColSolution(), solution2, 2);
00892 
00893         const double activity2[] = {20, 15};
00894         ret = ret && equivalentVectors(s,s,0.0001,s->getRowActivity(), activity2, 2);
00895 
00896         return ret;
00897 }
00898 
00899 //--------------------------------------------------------------------------
00900 
00901 bool test13VivianDeSmedt(OsiSolverInterface *s)
00902 {
00903         bool ret = true;
00904 
00905         double inf = s->getInfinity();
00906 
00907         CoinPackedMatrix m;
00908 
00909         CoinPackedVector c0;
00910         c0.insert(0, 4);
00911         c0.insert(1, 1);
00912         m.appendCol(c0);
00913 
00914         CoinPackedVector c1;
00915         c1.insert(0, 2);
00916         c1.insert(1, 3);
00917         m.appendCol(c1);
00918 
00919         int numcol = 2;
00920 
00921         double *obj = new double[numcol];
00922         obj[0] = 3;
00923         obj[1] = 1;
00924 
00925         double *collb = new double[numcol];
00926         collb[0] = 0;
00927         collb[1] = 0;
00928 
00929         double *colub = new double[numcol];
00930         colub[0] = inf;
00931         colub[1] = inf;
00932 
00933         int numrow = 2;
00934 
00935         double *rowlb = new double[numrow];
00936         rowlb[0] = 0;
00937         rowlb[1] = 0;
00938 
00939         double *rowub = new double[numrow];
00940         rowub[0] = 20;
00941         rowub[1] = 15;
00942 
00943         s->loadProblem(m, collb, colub, obj, rowlb, rowub);
00944 
00945         delete [] obj;
00946         delete [] collb;
00947         delete [] colub;
00948 
00949         delete [] rowlb;
00950         delete [] rowub;
00951 
00952         s->setObjSense(-1);
00953 
00954         s->initialSolve();
00955 
00956         ret = ret && s->isProvenOptimal();
00957         ret = ret && !s->isProvenPrimalInfeasible();
00958         ret = ret && !s->isProvenDualInfeasible();
00959 
00960         const double solution1[] = {5, 0};
00961         ret = ret && equivalentVectors(s,s,0.0001,s->getColSolution(), solution1, 2);
00962 
00963         const double activity1[] = {20, 5};
00964         ret = ret && equivalentVectors(s,s,0.0001,s->getRowActivity(), activity1, 2);
00965 
00966         s->setObjCoeff(0, 1);
00967         s->setObjCoeff(1, 1);
00968 
00969         s->resolve();
00970 
00971         ret = ret && s->isProvenOptimal();
00972         ret = ret && !s->isProvenPrimalInfeasible();
00973         ret = ret && !s->isProvenDualInfeasible();
00974 
00975         const double solution2[] = {3, 4};
00976         ret = ret && equivalentVectors(s,s,0.0001,s->getColSolution(), solution2, 2);
00977 
00978         const double activity2[] = {20, 15};
00979         ret = ret && equivalentVectors(s,s,0.0001,s->getRowActivity(), activity2, 2);
00980 
00981         return ret;
00982 }
00983 
00984 //--------------------------------------------------------------------------
00985 
00986 bool test14VivianDeSmedt(OsiSolverInterface *s)
00987 {
00988         bool ret = true;
00989 
00990         double inf = s->getInfinity();
00991 
00992         CoinPackedVector empty;
00993 
00994         s->addCol(empty, 0, inf, 3);
00995         s->addCol(empty, 0, inf, 1);
00996 
00997         CoinPackedVector r0;
00998         r0.insert(0, 4);
00999         r0.insert(1, 2);
01000         s->addRow(r0, 0, 20);
01001 
01002         CoinPackedVector r1;
01003         r1.insert(0, 1);
01004         r1.insert(1, 3);
01005         s->addRow(r1, 0, 15);
01006 
01007         s->setObjSense(-1);
01008 
01009         s->writeMps("test");
01010 
01011         s->initialSolve();
01012 
01013         ret = ret && s->isProvenOptimal();
01014         ret = ret && !s->isProvenPrimalInfeasible();
01015         ret = ret && !s->isProvenDualInfeasible();
01016 
01017         const double solution1[] = {5, 0};
01018         ret = ret && equivalentVectors(s,s,0.0001,s->getColSolution(), solution1, 2);
01019 
01020         const double activity1[] = {20, 5};
01021         ret = ret && equivalentVectors(s,s,0.0001,s->getRowActivity(), activity1, 2);
01022 
01023         s->setObjCoeff(0, 1);
01024         s->setObjCoeff(1, 1);
01025 
01026         s->resolve();
01027 
01028         ret = ret && s->isProvenOptimal();
01029         ret = ret && !s->isProvenPrimalInfeasible();
01030         ret = ret && !s->isProvenDualInfeasible();
01031 
01032         const double solution2[] = {3, 4};
01033         ret = ret && equivalentVectors(s,s,0.0001,s->getColSolution(), solution2, 2);
01034 
01035         const double activity2[] = {20, 15};
01036         ret = ret && equivalentVectors(s,s,0.0001,s->getRowActivity(), activity2, 2);
01037 
01038         return ret;
01039 }
01040 
01041 //--------------------------------------------------------------------------
01042 
01043 bool test15VivianDeSmedt(OsiSolverInterface *s)
01044 {
01045         bool ret = true;
01046 
01047         double inf = s->getInfinity();
01048 
01049         CoinPackedVector empty;
01050 
01051         s->addRow(empty, 0, 20);
01052         s->addRow(empty, 0, 15);
01053 
01054         CoinPackedVector c0;
01055         c0.insert(0, 4);
01056         c0.insert(1, 1);
01057         s->addCol(c0, 0, inf, 3);
01058 
01059         CoinPackedVector c1;
01060         c1.insert(0, 2);
01061         c1.insert(1, 3);
01062         s->addCol(c1, 0, inf, 1);
01063 
01064         s->setObjSense(-1);
01065 
01066         s->writeMps("test");
01067 
01068         s->initialSolve();
01069 
01070         ret = ret && s->isProvenOptimal();
01071         ret = ret && !s->isProvenPrimalInfeasible();
01072         ret = ret && !s->isProvenDualInfeasible();
01073 
01074         const double solution1[] = {5, 0};
01075         ret = ret && equivalentVectors(s,s,0.0001,s->getColSolution(), solution1, 2);
01076 
01077         const double activity1[] = {20, 5};
01078         ret = ret && equivalentVectors(s,s,0.0001,s->getRowActivity(), activity1, 2);
01079 
01080         s->setObjCoeff(0, 1);
01081         s->setObjCoeff(1, 1);
01082 
01083         s->resolve();
01084 
01085         ret = ret && s->isProvenOptimal();
01086         ret = ret && !s->isProvenPrimalInfeasible();
01087         ret = ret && !s->isProvenDualInfeasible();
01088 
01089         const double solution2[] = {3, 4};
01090         ret = ret && equivalentVectors(s,s,0.0001,s->getColSolution(), solution2, 2);
01091 
01092         const double activity2[] = {20, 15};
01093         ret = ret && equivalentVectors(s,s,0.0001,s->getRowActivity(), activity2, 2);
01094 
01095         return ret;
01096 }
01097 
01098 //--------------------------------------------------------------------------
01099 
01100 
01115 void OsiSolverInterfaceMpsUnitTest
01116   (const std::vector<OsiSolverInterface*> & vecEmptySiP,
01117    const std::string & mpsDir)
01118 
01119 { int i ;
01120   unsigned int m ;
01121 
01122 /*
01123   Vectors to hold test problem names and characteristics. The objective value
01124   after optimization (objValue) must agree to the specified tolerance
01125   (objValueTol).
01126 */
01127   std::vector<std::string> mpsName ;
01128   std::vector<bool> min ;
01129   std::vector<int> nRows ;
01130   std::vector<int> nCols ;
01131   std::vector<double> objValue ;
01132   std::vector<double> objValueTol ;
01133 /*
01134   And a macro to make the vector creation marginally readable.
01135 */
01136 #define PUSH_MPS(zz_mpsName_zz,zz_min_zz,\
01137                  zz_nRows_zz,zz_nCols_zz,zz_objValue_zz,zz_objValueTol_zz) \
01138   mpsName.push_back(zz_mpsName_zz) ; \
01139   min.push_back(zz_min_zz) ; \
01140   nRows.push_back(zz_nRows_zz) ; \
01141   nCols.push_back(zz_nCols_zz) ; \
01142   objValueTol.push_back(zz_objValueTol_zz) ; \
01143   objValue.push_back(zz_objValue_zz) ;
01144 
01145 /*
01146   Load up the problem vector. Note that the row counts here include the
01147   objective function.
01148 */
01149   PUSH_MPS("25fv47",true,822,1571,5.5018458883E+03,1.0e-10)
01150   PUSH_MPS("80bau3b",true,2263,9799,9.8722419241E+05,1.e-10)
01151   PUSH_MPS("adlittle",true,57,97,2.2549496316e+05,1.e-10)
01152   PUSH_MPS("afiro",true,28,32,-4.6475314286e+02,1.e-10)
01153   PUSH_MPS("agg",true,489,163,-3.5991767287e+07,1.e-10)
01154   PUSH_MPS("agg2",true,517,302,-2.0239252356e+07,1.e-10)
01155   PUSH_MPS("agg3",true,517,302,1.0312115935e+07,1.e-10)
01156   PUSH_MPS("bandm",true,306,472,-1.5862801845e+02,1.e-10)
01157   PUSH_MPS("beaconfd",true,174,262,3.3592485807e+04,1.e-10)
01158   PUSH_MPS("blend",true,75,83,-3.0812149846e+01,1.e-10)
01159   PUSH_MPS("bnl1",true,644,1175,1.9776295615E+03,1.e-10)
01160   PUSH_MPS("bnl2",true,2325,3489,1.8112365404e+03,1.e-10)
01161   PUSH_MPS("boeing1",true,/*351*/352,384,-3.3521356751e+02,1.e-10)
01162   PUSH_MPS("boeing2",true,167,143,-3.1501872802e+02,1.e-10)
01163   PUSH_MPS("bore3d",true,234,315,1.3730803942e+03,1.e-10)
01164   PUSH_MPS("brandy",true,221,249,1.5185098965e+03,1.e-10)
01165   PUSH_MPS("capri",true,272,353,2.6900129138e+03,1.e-10)
01166   PUSH_MPS("cycle",true,1904,2857,-5.2263930249e+00,1.e-9)
01167   PUSH_MPS("czprob",true,930,3523,2.1851966989e+06,1.e-10)
01168   PUSH_MPS("d2q06c",true,2172,5167,122784.21557456,1.e-7)
01169   PUSH_MPS("d6cube",true,416,6184,3.1549166667e+02,1.e-8)
01170   PUSH_MPS("degen2",true,445,534,-1.4351780000e+03,1.e-10)
01171   PUSH_MPS("degen3",true,1504,1818,-9.8729400000e+02,1.e-10)
01172   PUSH_MPS("dfl001",true,6072,12230,1.1266396047E+07,1.e-5)
01173   PUSH_MPS("e226",true,224,282,(-18.751929066+7.113),1.e-10) // NOTE: Objective function has constant of 7.113
01174   PUSH_MPS("etamacro",true,401,688,-7.5571521774e+02 ,1.e-6)
01175   PUSH_MPS("fffff800",true,525,854,5.5567961165e+05,1.e-6)
01176   PUSH_MPS("finnis",true,498,614,1.7279096547e+05,1.e-6)
01177   PUSH_MPS("fit1d",true,25,1026,-9.1463780924e+03,1.e-10)
01178   PUSH_MPS("fit1p",true,628,1677,9.1463780924e+03,1.e-10)
01179   PUSH_MPS("fit2d",true,26,10500,-6.8464293294e+04,1.e-10)
01180   PUSH_MPS("fit2p",true,3001,13525,6.8464293232e+04,1.e-9)
01181   PUSH_MPS("forplan",true,162,421,-6.6421873953e+02,1.e-6)
01182   PUSH_MPS("ganges",true,1310,1681,-1.0958636356e+05,1.e-5)
01183   PUSH_MPS("gfrd-pnc",true,617,1092,6.9022359995e+06,1.e-10)
01184   PUSH_MPS("greenbea",true,2393,5405,/*-7.2462405908e+07*/-72555248.129846,1.e-10)
01185   PUSH_MPS("greenbeb",true,2393,5405,/*-4.3021476065e+06*/-4302260.2612066,1.e-10)
01186   PUSH_MPS("grow15",true,301,645,-1.0687094129e+08,1.e-10)
01187   PUSH_MPS("grow22",true,441,946,-1.6083433648e+08,1.e-10)
01188   PUSH_MPS("grow7",true,141,301,-4.7787811815e+07,1.e-10)
01189   PUSH_MPS("israel",true,175,142,-8.9664482186e+05,1.e-10)
01190   PUSH_MPS("kb2",true,44,41,-1.7499001299e+03,1.e-10)
01191   PUSH_MPS("lotfi",true,154,308,-2.5264706062e+01,1.e-10)
01192   PUSH_MPS("maros",true,847,1443,-5.8063743701e+04,1.e-10)
01193   PUSH_MPS("maros-r7",true,3137,9408,1.4971851665e+06,1.e-10)
01194   PUSH_MPS("modszk1",true,688,1620,3.2061972906e+02,1.e-10)
01195   PUSH_MPS("nesm",true,663,2923,1.4076073035e+07,1.e-5)
01196   PUSH_MPS("perold",true,626,1376,-9.3807580773e+03,1.e-6)
01197   PUSH_MPS("pilot",true,1442,3652,/*-5.5740430007e+02*/-557.48972927292,5.e-5)
01198   PUSH_MPS("pilot4",true,411,1000,-2.5811392641e+03,1.e-6)
01199   PUSH_MPS("pilot87",true,2031,4883,3.0171072827e+02,1.e-4)
01200   PUSH_MPS("pilotnov",true,976,2172,-4.4972761882e+03,1.e-10)
01201   // ?? PUSH_MPS("qap8",true,913,1632,2.0350000000e+02,1.e-10)
01202   // ?? PUSH_MPS("qap12",true,3193,8856,5.2289435056e+02,1.e-10)
01203   // ?? PUSH_MPS("qap15",true,6331,22275,1.0409940410e+03,1.e-10)
01204   PUSH_MPS("recipe",true,92,180,-2.6661600000e+02,1.e-10)
01205   PUSH_MPS("sc105",true,106,103,-5.2202061212e+01,1.e-10)
01206   PUSH_MPS("sc205",true,206,203,-5.2202061212e+01,1.e-10)
01207   PUSH_MPS("sc50a",true,51,48,-6.4575077059e+01,1.e-10)
01208   PUSH_MPS("sc50b",true,51,48,-7.0000000000e+01,1.e-10)
01209   PUSH_MPS("scagr25",true,472,500,-1.4753433061e+07,1.e-10)
01210   PUSH_MPS("scagr7",true,130,140,-2.3313892548e+06,1.e-6)
01211   PUSH_MPS("scfxm1",true,331,457,1.8416759028e+04,1.e-10)
01212   PUSH_MPS("scfxm2",true,661,914,3.6660261565e+04,1.e-10)
01213   PUSH_MPS("scfxm3",true,991,1371,5.4901254550e+04,1.e-10)
01214   PUSH_MPS("scorpion",true,389,358,1.8781248227e+03,1.e-10)
01215   PUSH_MPS("scrs8",true,491,1169,9.0429998619e+02,1.e-5)
01216   PUSH_MPS("scsd1",true,78,760,8.6666666743e+00,1.e-10)
01217   PUSH_MPS("scsd6",true,148,1350,5.0500000078e+01,1.e-10)
01218   PUSH_MPS("scsd8",true,398,2750,9.0499999993e+02,1.e-8)
01219   PUSH_MPS("sctap1",true,301,480,1.4122500000e+03,1.e-10)
01220   PUSH_MPS("sctap2",true,1091,1880,1.7248071429e+03,1.e-10)
01221   PUSH_MPS("sctap3",true,1481,2480,1.4240000000e+03,1.e-10)
01222   PUSH_MPS("seba",true,516,1028,1.5711600000e+04,1.e-10)
01223   PUSH_MPS("share1b",true,118,225,-7.6589318579e+04,1.e-10)
01224   PUSH_MPS("share2b",true,97,79,-4.1573224074e+02,1.e-10)
01225   PUSH_MPS("shell",true,537,1775,1.2088253460e+09,1.e-10)
01226   PUSH_MPS("ship04l",true,403,2118,1.7933245380e+06,1.e-10)
01227   PUSH_MPS("ship04s",true,403,1458,1.7987147004e+06,1.e-10)
01228   PUSH_MPS("ship08l",true,779,4283,1.9090552114e+06,1.e-10)
01229   PUSH_MPS("ship08s",true,779,2387,1.9200982105e+06,1.e-10)
01230   PUSH_MPS("ship12l",true,1152,5427,1.4701879193e+06,1.e-10)
01231   PUSH_MPS("ship12s",true,1152,2763,1.4892361344e+06,1.e-10)
01232   PUSH_MPS("sierra",true,1228,2036,1.5394362184e+07,1.e-10)
01233   PUSH_MPS("stair",true,357,467,-2.5126695119e+02,1.e-10)
01234   PUSH_MPS("standata",true,360,1075,1.2576995000e+03,1.e-10)
01235   // GUB PUSH_MPS("standgub",true,362,1184,1257.6995,1.e-10) 
01236   PUSH_MPS("standmps",true,468,1075,1.4060175000E+03,1.e-10) 
01237   PUSH_MPS("stocfor1",true,118,111,-4.1131976219E+04,1.e-10)
01238   PUSH_MPS("stocfor2",true,2158,2031,-3.9024408538e+04,1.e-10)
01239   // ?? PUSH_MPS("stocfor3",true,16676,15695,-3.9976661576e+04,1.e-10)
01240   // ?? PUSH_MPS("truss",true,1001,8806,4.5881584719e+05,1.e-10)
01241   PUSH_MPS("tuff",true,334,587,2.9214776509e-01,1.e-10)
01242   PUSH_MPS("vtpbase",true,199,203,1.2983146246e+05,1.e-10)
01243   PUSH_MPS("wood1p",true,245,2594,1.4429024116e+00,5.e-5)
01244   PUSH_MPS("woodw",true,1099,8405,1.3044763331E+00,1.e-10)
01245 
01246 #undef PUSH_MPS
01247 
01248 /*
01249   Create a vector of solver interfaces that we can use to run the test
01250   problems. The strategy is to create a fresh clone of the `empty' solvers
01251   from vecEmptySiP for each problem, then proceed in stages: read the MPS
01252   file, solve the problem, check the solution. If there are multiple
01253   solvers in vecSiP, the results of each solver are compared with its
01254   neighbors in the vector.
01255 */
01256   std::vector<OsiSolverInterface*> vecSiP(vecEmptySiP.size()) ;
01257 
01258   // Create vector to store a name for each solver interface
01259   // and a count on the number of problems the solver intface solved.
01260   std::vector<std::string> siName;
01261   std::vector<int> numProbSolved;
01262   std::vector<double> timeTaken;
01263   const int vecsize = vecSiP.size();
01264   for ( i=0; i<vecsize; i++ ) {
01265     siName.push_back("unknown");
01266     numProbSolved.push_back(0);
01267     timeTaken.push_back(0.0);
01268   }
01269   
01270   
01271   //Open the main loop to step through the MPS problems.
01272   for (m = 0 ; m < mpsName.size() ; m++) { 
01273     std::cerr << "  processing mps file: " << mpsName[m] 
01274       << " (" << m+1 << " out of " << mpsName.size() << ")" << std::endl ;
01275     bool allSolversReadMpsFile = true;
01276     
01277     
01278     //Stage 1: Read the MPS file into each solver interface.
01279     //Fill vecSiP with fresh clones of the solvers and read in the MPS file. As
01280     //a basic check, make sure the size of the constraint matrix is correct.
01281     for (i = vecSiP.size()-1 ; i >= 0 ; --i) { 
01282       vecSiP[i] = vecEmptySiP[i]->clone() ;
01283       
01284       vecSiP[i]->getStrParam(OsiSolverName,siName[i]);
01285 /* 
01286   REMOVE ME
01287 
01288   #     ifdef COIN_USE_DYLP
01289       { 
01290         OsiDylpSolverInterface * si =
01291           dynamic_cast<OsiDylpSolverInterface *>(vecSiP[i]) ;
01292         if (si != NULL )  { 
01293           // Solver is DYLP.
01294           // Skip over netlib cases that DYLP struggles with.
01295           // Does not read forplan mps file
01296           if ( mpsName[m]=="forplan" ) {
01297             failureMessage(siName[i],"mps reader will not read forplan");
01298             allSolversReadMpsFile = false;
01299             continue;
01300           }
01301         }
01302       }
01303   #     endif
01304 */
01305       
01306       std::string fn = mpsDir+mpsName[m] ;
01307       vecSiP[i]->readMps(fn.c_str(),"mps") ;
01308       
01309       if (min[m])
01310         vecSiP[i]->setObjSense(1.0) ;
01311       else
01312         vecSiP[i]->setObjSense(-1.0) ;
01313       
01314       int nr = vecSiP[i]->getNumRows() ;
01315       int nc = vecSiP[i]->getNumCols() ;
01316       assert(nr == nRows[m]-1) ;
01317       assert(nc == nCols[m]) ; 
01318     } 
01319     
01320     //If we have multiple solvers, compare the representations.
01321     if ( allSolversReadMpsFile )
01322       for (i = vecSiP.size()-1 ; i > 0 ; --i) { 
01323         CoinPackedVector vim1,vi ;
01324         
01325         // Compare col lowerbounds
01326         assert(
01327           equivalentVectors(vecSiP[i-1],vecSiP[i], 1.e-10,
01328           vecSiP[i-1]->getColLower(),vecSiP[i  ]->getColLower(),
01329           vecSiP[i  ]->getNumCols() )
01330           ) ;
01331         
01332         // Compare col upperbounds
01333         assert(
01334           equivalentVectors(vecSiP[i-1],vecSiP[i], 1.e-10,
01335           vecSiP[i-1]->getColUpper(),vecSiP[i  ]->getColUpper(),
01336           vecSiP[i  ]->getNumCols() )
01337           ) ;
01338         
01339         // Compare row lowerbounds
01340         assert(
01341           equivalentVectors(vecSiP[i-1],vecSiP[i], 1.e-10,
01342           vecSiP[i-1]->getRowLower(),vecSiP[i  ]->getRowLower(),
01343           vecSiP[i  ]->getNumRows() )
01344           ) ;
01345         
01346         // Compare row upperbounds
01347         assert( 
01348           equivalentVectors(vecSiP[i-1],vecSiP[i], 1.e-10,
01349           vecSiP[i-1]->getRowUpper(),vecSiP[i  ]->getRowUpper(),
01350           vecSiP[i  ]->getNumRows() )
01351           ) ;
01352         
01353         // Compare row sense
01354         {
01355           const char * rsm1 = vecSiP[i-1]->getRowSense() ;
01356           const char * rs   = vecSiP[i  ]->getRowSense() ;
01357           int nr = vecSiP[i]->getNumRows() ;
01358           int r ;
01359           for (r = 0 ; r < nr ; r++) assert (rsm1[r] == rs[r]) ;
01360         }
01361         
01362         // Compare rhs
01363         assert( 
01364           equivalentVectors(vecSiP[i-1],vecSiP[i], 1.e-10,
01365           vecSiP[i-1]->getRightHandSide(),vecSiP[i  ]->getRightHandSide(),
01366           vecSiP[i  ]->getNumRows() )
01367           ) ;
01368         
01369         // Compare range
01370         assert( 
01371           equivalentVectors(vecSiP[i-1],vecSiP[i], 1.e-10,
01372           vecSiP[i-1]->getRowRange(),vecSiP[i  ]->getRowRange(),
01373           vecSiP[i  ]->getNumRows() )
01374           ) ;
01375         
01376         // Compare objective sense
01377         assert( vecSiP[i-1]->getObjSense() == vecSiP[i  ]->getObjSense() ) ;
01378         
01379         // Compare objective coefficients
01380         assert( 
01381           equivalentVectors(vecSiP[i-1],vecSiP[i], 1.e-10,
01382           vecSiP[i-1]->getObjCoefficients(),vecSiP[i  ]->getObjCoefficients(),
01383           vecSiP[i  ]->getNumCols() )
01384           ) ;
01385         
01386         // Compare number of elements
01387         assert( vecSiP[i-1]->getNumElements() == vecSiP[i]->getNumElements() ) ;
01388         
01389         // Compare constraint matrix
01390         { 
01391           const CoinPackedMatrix * rmm1=vecSiP[i-1]->getMatrixByRow() ;
01392           const CoinPackedMatrix * rm  =vecSiP[i  ]->getMatrixByRow() ;
01393           assert( rmm1->isEquivalent(*rm) ) ;
01394           
01395           const CoinPackedMatrix * cmm1=vecSiP[i-1]->getMatrixByCol() ;
01396           const CoinPackedMatrix * cm  =vecSiP[i  ]->getMatrixByCol() ;
01397           assert( cmm1->isEquivalent(*cm) ) ; 
01398         } 
01399       }
01400       
01401       //If we have multiple solvers, compare the variable type information      
01402       if ( allSolversReadMpsFile )
01403         for (i = vecSiP.size()-1 ; i > 0 ; --i){ 
01404           CoinPackedVector vim1,vi ;
01405           int c ;
01406           
01407           { 
01408             OsiVectorInt sm1 = vecSiP[i-1]->getFractionalIndices() ;
01409             OsiVectorInt s   = vecSiP[i  ]->getFractionalIndices() ;
01410             assert( sm1.size() == s.size() ) ;
01411             for (c = s.size()-1 ; c >= 0 ; --c) assert( sm1[c] == s[c] ) ; 
01412           }
01413           
01414           { 
01415             int nc = vecSiP[i]->getNumCols() ;
01416             for (c = 0 ; c < nc ; c++){ 
01417               assert(
01418                 vecSiP[i-1]->isContinuous(c) == vecSiP[i]->isContinuous(c)
01419                 ) ;
01420               assert(
01421                 vecSiP[i-1]->isBinary(c) == vecSiP[i]->isBinary(c)
01422                 ) ;
01423               assert(
01424                 vecSiP[i-1]->isIntegerNonBinary(c) ==
01425                 vecSiP[i  ]->isIntegerNonBinary(c)
01426                 ) ;
01427               assert(
01428                 vecSiP[i-1]->isFreeBinary(c) == vecSiP[i]->isFreeBinary(c)
01429                 ) ;
01430               assert(
01431                 vecSiP[i-1]->isInteger(c) == vecSiP[i]->isInteger(c)
01432                 ) ; 
01433             } 
01434           } 
01435         }
01436         
01437       //Stage 2: Call each solver to solve the problem.
01438       //
01439       // We call each solver, then check the return code and objective.
01440       //  
01441       //    Note that the volume solver can't handle the Netlib cases. The strategy is
01442       //    to require that it be the last solver in vecSiP and then break out of the
01443       //    loop. This ensures that all previous solvers are run and compared to one
01444       //    another.      
01445       for (i = 0 ; i < static_cast<int>(vecSiP.size()) ; ++i) {
01446         double startTime = CoinCpuTime();
01447         
01448 #     ifdef COIN_USE_VOL
01449         { 
01450           OsiVolSolverInterface * si =
01451             dynamic_cast<OsiVolSolverInterface *>(vecSiP[i]) ;
01452           if (si != NULL )  { 
01453             // VOL does not solve netlib cases so don't bother trying to solve
01454             break ; 
01455           }
01456         }
01457 #     endif
01458 
01459 /*
01460   #     ifdef COIN_USE_DYLP
01461         { 
01462           OsiDylpSolverInterface * si =
01463             dynamic_cast<OsiDylpSolverInterface *>(vecSiP[i]) ;
01464           if (si != NULL )  { 
01465             // Solver is DYLP.
01466             // Skip over netlib cases that DYLP struggles with
01467             if ( mpsName[m]=="forplan" ) { continue; }
01468             // Does not converge to solution after many hours run time for pilot
01469             if ( mpsName[m]=="pilot" ) {
01470               failureMessage(siName[i],"skipping pilot. does not solve after many hours on windows");
01471               continue;
01472             }
01473             // Does not converge to solution after many hours run time for pilot
01474             if ( mpsName[m]=="pilot87" ) {
01475               failureMessage(siName[i],"skipping pilot. does not solve after an hour cpu time on windows");
01476               continue;
01477             }
01478           }
01479         }
01480   #     endif
01481 */
01482         
01483         vecSiP[i]->initialSolve() ;
01484         
01485         double timeOfSolution = CoinCpuTime()-startTime;
01486         if (vecSiP[i]->isProvenOptimal()) { 
01487           double soln = vecSiP[i]->getObjValue();       
01488           CoinRelFltEq eq(objValueTol[m]) ;
01489           if (eq(soln,objValue[m])) { 
01490             std::cerr 
01491               <<siName[i]<<"SolverInterface "
01492               << soln << " = " << objValue[m] << " ; okay";
01493             numProbSolved[i]++;
01494           } else  { 
01495             std::cerr <<siName[i] <<" " <<soln << " != " <<objValue[m] << "; error=" ;
01496             std::cerr <<fabs(objValue[m] - soln); 
01497           }
01498         } else {
01499           if (vecSiP[i]->isProvenPrimalInfeasible())  
01500             std::cerr << "error; primal infeasible" ;
01501           else if (vecSiP[i]->isProvenDualInfeasible())  
01502             std::cerr << "error; dual infeasible" ;
01503           else if (vecSiP[i]->isIterationLimitReached()) 
01504             std::cerr << "error; iteration limit" ;
01505           else if (vecSiP[i]->isAbandoned()) 
01506             std::cerr << "error; abandoned" ;
01507           else  
01508             std::cerr << "error; unknown" ;
01509         }
01510         std::cerr<<" - took " <<timeOfSolution<<" seconds."<<std::endl; 
01511         timeTaken[i] += timeOfSolution;
01512       }
01513       /*
01514       Delete the used solver interfaces so we can reload fresh clones for the
01515       next problem.
01516       */
01517       for (i = vecSiP.size()-1 ; i >= 0 ; --i) delete vecSiP[i] ;
01518   }
01519 
01520   const int siName_size = siName.size();
01521   for ( i=0; i<siName_size; i++ ) {
01522     std::cerr 
01523       <<siName[i] 
01524       <<" solved " 
01525       <<numProbSolved[i]
01526       <<" out of "
01527       <<objValue.size()
01528       <<" and took "
01529       <<timeTaken[i]
01530       <<" seconds."
01531       <<std::endl;
01532   } 
01533 }
01534 
01535 
01536 //#############################################################################
01537 //#############################################################################
01538 
01539 static bool testIntParam(OsiSolverInterface * si, int k, int val)
01540 {
01541   int i = 123456789, orig = 123456789;
01542   bool ret;
01543   OsiIntParam key = static_cast<OsiIntParam>(k);
01544   si->getIntParam(key, orig);
01545   if (si->setIntParam(key, val)) {
01546     ret = (si->getIntParam(key, i) == true) && (i == val);
01547   } else {
01548     ret = (si->getIntParam(key, i) == true) && (i == orig);
01549   }
01550   return ret;
01551 }
01552 static bool testDblParam(OsiSolverInterface * si, int k, double val)
01553 {
01554   double d = 123456789.0, orig = 123456789.0;
01555   bool ret;
01556   OsiDblParam key = static_cast<OsiDblParam>(k);
01557   si->getDblParam(key, orig);
01558   if (si->setDblParam(key, val)) {
01559     ret = (si->getDblParam(key, d) == true) && (d == val);
01560   } else {
01561     ret = (si->getDblParam(key, d) == true) && (d == orig);
01562   }
01563   return ret;
01564 }
01565 
01566 /*
01567   Original model
01568 
01569 static bool testHintParam(OsiSolverInterface * si, int k, bool val,
01570                           OsiHintStrength strength)
01571 {
01572   bool i = true, orig = true;
01573   OsiHintStrength i2 = OsiHintDo, orig2 = OsiHintDo;
01574   bool ret;
01575   OsiHintParam key = static_cast<OsiHintParam>(k);
01576   si->getHintParam(key, orig, orig2);
01577   if (si->setHintParam(key, val, strength)) {
01578     ret = (si->getHintParam(key, i, i2) == true) && (i2 == strength);
01579   } else {
01580     ret = (si->getHintParam(key, i, i2) == true) && (i2 == orig2);
01581   }
01582   return ret;
01583 }
01584 */
01585 
01586 static bool testHintParam(OsiSolverInterface * si, int k, bool sense,
01587                           OsiHintStrength strength, int *throws)
01588 /*
01589   Tests for proper behaviour of [set,get]HintParam methods. The initial get
01590   tests the return value to see if the hint is implemented; the values
01591   returned for sense and strength are not checked.
01592   
01593   If the hint is implemented, a pair of set/get calls is performed at the
01594   strength specified by the parameter. The set can return true or, at
01595   strength OsiForceDo, throw an exception if the solver cannot comply. The
01596   rationale would be that only OsiForceDo must be obeyed, so anything else
01597   should return true regardless of whether the solver followed the hint.
01598 
01599   The test checks that the value and strength returned by getHintParam matches
01600   the previous call to setHintParam. This is arguably wrong --- one can argue
01601   that it should reflect the solver's ability to comply with the hint. But
01602   that's how the OSI interface standard has evolved up to now.
01603 
01604   If the hint is not implemented, attempting to set the hint should return
01605   false, or throw an exception at strength OsiForceDo.
01606 
01607   The testing code which calls testHintParam is set up so that a successful
01608   return is defined as true if the hint is implemented, false if it is not.
01609   Information printing is suppressed; uncomment and recompile if you want it.
01610 */
01611 { bool post_sense ;
01612   OsiHintStrength post_strength ;
01613   bool ret ;
01614   OsiHintParam key = static_cast<OsiHintParam>(k) ;
01615 
01616   if (si->getHintParam(key,post_sense,post_strength))
01617   { ret = false ;
01618     try
01619     { if (si->setHintParam(key,sense,strength))
01620       { ret = (si->getHintParam(key,post_sense,post_strength) == true) &&
01621               (post_strength == strength) && (post_sense == sense) ; } }
01622     catch (CoinError &thrownErr)
01623     { // std::ostringstream msg ;
01624       // msg << "setHintParam throw for hint " << key << " sense " << sense <<
01625       //      " strength " << strength ;
01626       // failureMessage(*si,msg.str()) ;
01627       // std::cerr << thrownErr.className() << "::" << thrownErr.methodName() <<
01628       //        ": " << thrownErr.message() << std::endl ;
01629       (*throws)++ ;
01630       ret = (strength == OsiForceDo) ; } }
01631   else
01632   { ret = true ;
01633     try
01634     { ret = si->setHintParam(key,sense,strength) ; }
01635     catch (CoinError &thrownErr)
01636     { // std::ostringstream msg ;
01637       // msg << "setHintParam throw for hint " << key << " sense " << sense <<
01638       //      " strength " << strength ;
01639       // failureMessage(*si,msg.str()) ;
01640       // std::cerr << thrownErr.className() << "::" << thrownErr.methodName() <<
01641       //        ": " << thrownErr.message() << std::endl ;
01642       (*throws)++ ;
01643       ret = !(strength == OsiForceDo) ; } }
01644   
01645   return ret ; }
01646 
01647 //#############################################################################
01648 //#############################################################################
01649 
01650 CoinPackedMatrix &BuildExmip1Mtx ()
01651 /*
01652   Simple function to build a packed matrix for the exmip1 example used in
01653   tests. The function exists solely to hide the intermediate variables.
01654   Probably could be written as an initialised declaration.
01655   See COIN/Mps/Sample/exmip1.mps for a human-readable presentation.
01656 
01657   Ordered triples seem easiest. They're listed in row-major order.
01658 */
01659 
01660 { int rowndxs[] = { 0, 0, 0, 0, 0,
01661                     1, 1,
01662                     2, 2,
01663                     3, 3,
01664                     4, 4, 4 } ;
01665   int colndxs[] = { 0, 1, 3, 4, 7,
01666                     1, 2,
01667                     2, 5,
01668                     3, 6,
01669                     0, 4, 7 } ;
01670   double coeffs[] = { 3.0, 1.0, -2.0, -1.0, -1.0,
01671                       2.0, 1.1,
01672                       1.0, 1.0,
01673                       2.8, -1.2,
01674                       5.6, 1.0, 1.9 } ;
01675 
01676   static CoinPackedMatrix exmip1mtx =
01677     CoinPackedMatrix(true,&rowndxs[0],&colndxs[0],&coeffs[0],14) ;
01678 
01679   return (exmip1mtx) ; }
01680 
01681 
01682 void
01683 OsiSolverInterfaceCommonUnitTest(const OsiSolverInterface* emptySi,
01684                                  const std::string & mpsDir, 
01685          const std::string & netlibDir)
01686 {
01687   
01688   int i;
01689   CoinRelFltEq eq;
01690 
01691   std::string fn = mpsDir+"exmip1";
01692   OsiSolverInterface * exmip1Si = emptySi->clone(); 
01693   exmip1Si->readMps(fn.c_str(),"mps");
01694 
01695   // Test that solverInterface knows its name.
01696   // The name is used for displaying messages when testing
01697   std::string solverName;
01698   {
01699     OsiSolverInterface * si = emptySi->clone();
01700     bool supportsSolverName = si->getStrParam(OsiSolverName,solverName);
01701     assert( supportsSolverName );
01702     assert( solverName != "Unknown Solver" );
01703     delete si;
01704   }
01705 
01706   // Determine if this is the emptySi is an OsiVolSolverInterface
01707   bool volSolverInterface = false;
01708   {
01709 #ifdef COIN_USE_VOL
01710     const OsiVolSolverInterface * si =
01711       dynamic_cast<const OsiVolSolverInterface *>(emptySi);
01712     if ( si != NULL ) volSolverInterface = true;
01713 #endif
01714   }
01715 
01716   // Determine if this is the emptySi is an OsiOslSolverInterface
01717 #ifdef COIN_USE_OSL
01718   bool oslSolverInterface = false;
01719 #endif
01720   {
01721 #ifdef COIN_USE_OSL
01722     const OsiOslSolverInterface * si =
01723       dynamic_cast<const OsiOslSolverInterface *>(emptySi);
01724     if ( si != NULL ) oslSolverInterface = true;
01725 #endif
01726   }
01727 
01728   // Determine if this is the emptySi is an OsiDylpSolverInterface
01729 #ifdef COIN_USE_DYLP
01730   bool dylpSolverInterface = false;
01731   {
01732     const OsiDylpSolverInterface * si =
01733       dynamic_cast<const OsiDylpSolverInterface *>(emptySi);
01734     if ( si != NULL ) dylpSolverInterface = true;
01735   }
01736 #endif
01737 
01738   // Determine if this is the emptySi is an OsiGlpkSolverInterface
01739   bool glpkSolverInterface = false;
01740   {
01741 #ifdef COIN_USE_GLPK
01742     const OsiGlpkSolverInterface * si =
01743       dynamic_cast<const OsiGlpkSolverInterface *>(emptySi);
01744     if ( si != NULL ) glpkSolverInterface = true;
01745 #endif
01746   }
01747 
01748   // Test that solverInterface knows about constants
01749   // in objective function.
01750   // Do not perform test if Vol solver, because it
01751   // requires problems of a special form and can not
01752   // solve netlib e226.
01753   if ( !volSolverInterface ) {
01754     OsiSolverInterface * si = emptySi->clone();
01755     std::string fn = netlibDir+"e226";
01756     si->readMps(fn.c_str(),"mps");
01757     si->initialSolve();
01758     double objValue = si->getObjValue(); 
01759     if( !eq(objValue,-18.751929066+7.113) )
01760       failureMessage(solverName,"getObjValue with constant in objective function");
01761     delete si;
01762   }
01763 
01764   // Test that values returned from an empty solverInterface
01765   {
01766     OsiSolverInterface * si = emptySi->clone();
01767     if( si->getNumRows()!=0 )
01768       failureMessage(solverName,"getNumRows with empty solverInterface");
01769     if( si->getNumCols()!=0 )
01770       failureMessage(solverName,"getNumCols with empty solverInterface");
01771     if( si->getNumElements()!=0 )
01772       failureMessage(solverName,"getNumElements with empty solverInterface");
01773     if( si->getColLower()!=NULL )
01774       failureMessage(solverName,"getColLower with empty solverInterface");
01775     if( si->getColUpper()!=NULL )
01776       failureMessage(solverName,"getColUpper with empty solverInterface");
01777     if( si->getColSolution()!=NULL )
01778       failureMessage(solverName,"getColSolution with empty solverInterface");
01779     if( si->getObjCoefficients()!=NULL )
01780       failureMessage(solverName,"getObjCoefficients with empty solverInterface");
01781     if( si->getRowRange()!=NULL )
01782       failureMessage(solverName,"getRowRange with empty solverInterface");
01783     if( si->getRightHandSide()!=NULL )
01784       failureMessage(solverName,"getRightHandSide with empty solverInterface");
01785     if( si->getRowSense()!=NULL )
01786       failureMessage(solverName,"getRowSense with empty solverInterface");
01787     if( si->getRowLower()!=NULL )
01788       failureMessage(solverName,"getRowLower with empty solverInterface");
01789     if( si->getRowUpper()!=NULL )
01790       failureMessage(solverName,"getRowUpper with empty solverInterface");
01791     delete si;
01792   }
01793   
01794   
01795   // Test that problem was loaded correctly
01796 
01797   { const char   * exmip1Sirs  = exmip1Si->getRowSense();
01798 
01799     assert( exmip1Sirs[0]=='G' );
01800     assert( exmip1Sirs[1]=='L' );
01801     assert( exmip1Sirs[2]=='E' );
01802     assert( exmip1Sirs[3]=='R' );
01803     assert( exmip1Sirs[4]=='R' );
01804     
01805     const double * exmip1Sirhs = exmip1Si->getRightHandSide();
01806     assert( eq(exmip1Sirhs[0],2.5) );
01807     assert( eq(exmip1Sirhs[1],2.1) );
01808     assert( eq(exmip1Sirhs[2],4.0) );
01809     assert( eq(exmip1Sirhs[3],5.0) );
01810     assert( eq(exmip1Sirhs[4],15.) ); 
01811     
01812     const double * exmip1Sirr  = exmip1Si->getRowRange();
01813     assert( eq(exmip1Sirr[0],0.0) );
01814     assert( eq(exmip1Sirr[1],0.0) );
01815     assert( eq(exmip1Sirr[2],0.0) );
01816     assert( eq(exmip1Sirr[3],5.0-1.8) );
01817     assert( eq(exmip1Sirr[4],15.0-3.0) );
01818 
01819     CoinPackedMatrix goldmtx ;
01820     goldmtx.reverseOrderedCopyOf(BuildExmip1Mtx()) ;
01821     CoinPackedMatrix pm;
01822     pm.setExtraGap(0.0);
01823     pm.setExtraMajor(0.0);
01824     pm = *exmip1Si->getMatrixByRow();
01825     pm.removeGaps();
01826     assert(goldmtx.isEquivalent(pm)) ;
01827     
01828     int nc = exmip1Si->getNumCols();
01829     int nr = exmip1Si->getNumRows();
01830     const double * cl = exmip1Si->getColLower();
01831     const double * cu = exmip1Si->getColUpper();
01832     const double * rl = exmip1Si->getRowLower();
01833     const double * ru = exmip1Si->getRowUpper();
01834     assert( nc == 8 );
01835     assert( nr == 5 );
01836     assert( eq(cl[0],2.5) );
01837     assert( eq(cl[1],0.0) );
01838     assert( eq(cl[2],0.0) );
01839     assert( eq(cl[3],0.0) );
01840     assert( eq(cl[4],0.5) );
01841     assert( eq(cl[5],0.0) );
01842     assert( eq(cl[6],0.0) );
01843     assert( eq(cl[7],0.0) );
01844     assert( eq(cu[0],exmip1Si->getInfinity()) );
01845     assert( eq(cu[1],4.1) );
01846     assert( eq(cu[2],1.0) );
01847     assert( eq(cu[3],1.0) );
01848     assert( eq(cu[4],4.0) );
01849     assert( eq(cu[5],exmip1Si->getInfinity()) );
01850     assert( eq(cu[6],exmip1Si->getInfinity()) );
01851     assert( eq(cu[7],4.3) );
01852 
01853     assert( eq(rl[0],2.5) );
01854     assert( eq(rl[1],-exmip1Si->getInfinity()) );
01855     assert( eq(rl[2],4.0) );
01856     assert( eq(rl[3],1.8) );
01857     assert( eq(rl[4],3.0) );
01858     assert( eq(ru[0],exmip1Si->getInfinity()) );
01859     assert( eq(ru[1],2.1) );
01860     assert( eq(ru[2],4.0) );
01861     assert( eq(ru[3],5.0) );
01862     assert( eq(ru[4],15.0) );
01863     
01864     // make sure col solution is something reasonable,
01865     // that is between upper and lower bounds
01866     const double * cs = exmip1Si->getColSolution();
01867     int c;
01868     bool okColSol=true;
01869     //double inf = exmip1Si->getInfinity();
01870     for ( c=0; c<nc; c++ ) {
01871       // if colSol is not between column bounds then 
01872       // colSol is unreasonable.
01873       if( !(cl[c]<=cs[c] && cs[c]<=cu[c]) ) okColSol=false;
01874       // if at least one column bound is not infinite,
01875       // then it is unreasonable to have colSol as infinite
01876       // FIXME: temporarily commented out pending some group thought on the
01877       //        semantics of this test. -- lh, 03.04.29 --
01878       // if ( (cl[c]<inf || cu[c]<inf) && cs[c]>=inf ) okColSol=false;
01879     }
01880     if( !okColSol )
01881       failureMessage(solverName,"getColSolution before solve");
01882     
01883     // Test value of objective function coefficients
01884     const double * objCoef = exmip1Si->getObjCoefficients();
01885     assert( eq( objCoef[0],  1.0) );
01886     assert( eq( objCoef[1],  0.0) );
01887     assert( eq( objCoef[2],  0.0) );
01888     assert( eq( objCoef[3],  0.0) );
01889     assert( eq( objCoef[4],  2.0) );
01890     assert( eq( objCoef[5],  0.0) );
01891     assert( eq( objCoef[6],  0.0) );
01892     assert( eq( objCoef[7], -1.0) );
01893 
01894     // Test that objective value is correct
01895     double correctObjValue = CoinPackedVector(nc,objCoef).dotProduct(cs);
01896     double siObjValue = exmip1Si->getObjValue();
01897     if( !eq(correctObjValue,siObjValue) ) {
01898        // FIXME: the test checks the primal value. vol fails this, because vol
01899        // considers the dual value to be the objective value
01900        failureMessage(solverName,"getObjValue before solve (OK for vol)");
01901     }
01902 
01903 
01904   }
01905   
01906   
01907   // Test matrixByCol method
01908   {
01909     CoinPackedMatrix &goldmtx = BuildExmip1Mtx() ;
01910     OsiSolverInterface & si = *exmip1Si->clone();
01911     CoinPackedMatrix sm = *si.getMatrixByCol();
01912     sm.removeGaps();
01913     bool getByColOK = goldmtx.isEquivalent(sm) ;
01914 
01915     if (!getByColOK)
01916       failureMessage(solverName,"getMatrixByCol()") ;
01917     
01918     // Test getting and setting of objective offset
01919     double objOffset;
01920     bool supportOsiObjOffset = si.getDblParam(OsiObjOffset,objOffset);
01921     assert( supportOsiObjOffset );
01922     assert( eq( objOffset, 0.0 ) );
01923     supportOsiObjOffset = si.setDblParam(OsiObjOffset, 3.21);
01924     assert( supportOsiObjOffset );
01925     si.getDblParam(OsiObjOffset,objOffset);
01926     assert( eq( objOffset, 3.21 ) );
01927     
01928     delete &si;
01929   }
01930    
01931   // Test clone
01932   {
01933     OsiSolverInterface * si2;  
01934     int ad = 13579;
01935     {
01936       OsiSolverInterface * si1 = exmip1Si->clone(); 
01937       int ad = 13579;
01938       si1->setApplicationData(&ad);
01939       assert( *((int *)(si1->getApplicationData())) == ad );
01940       si2 = si1->clone();
01941       delete si1;
01942     }
01943     
01944     if( *((int *)(si2->getApplicationData())) != ad )
01945       failureMessage(solverName,"getApplicationData on cloned solverInterface");
01946 
01947     const char   * exmip1Sirs  = si2->getRowSense();
01948     assert( exmip1Sirs[0]=='G' );
01949     assert( exmip1Sirs[1]=='L' );
01950     assert( exmip1Sirs[2]=='E' );
01951     assert( exmip1Sirs[3]=='R' );
01952     assert( exmip1Sirs[4]=='R' );
01953     
01954     const double * exmip1Sirhs = si2->getRightHandSide();
01955     assert( eq(exmip1Sirhs[0],2.5) );
01956     assert( eq(exmip1Sirhs[1],2.1) );
01957     assert( eq(exmip1Sirhs[2],4.0) );
01958     assert( eq(exmip1Sirhs[3],5.0) );
01959     assert( eq(exmip1Sirhs[4],15.) ); 
01960     
01961     const double * exmip1Sirr  = si2->getRowRange();
01962     assert( eq(exmip1Sirr[0],0.0) );
01963     assert( eq(exmip1Sirr[1],0.0) );
01964     assert( eq(exmip1Sirr[2],0.0) );
01965     assert( eq(exmip1Sirr[3],5.0-1.8) );
01966     assert( eq(exmip1Sirr[4],15.0-3.0) );
01967     
01968     CoinPackedMatrix goldmtx ;
01969     goldmtx.reverseOrderedCopyOf(BuildExmip1Mtx()) ;
01970     CoinPackedMatrix pm;
01971     pm.setExtraGap(0.0);
01972     pm.setExtraMajor(0.0);
01973     pm = *si2->getMatrixByRow();
01974     assert(goldmtx.isEquivalent(pm)) ;
01975     
01976     int nc = si2->getNumCols();
01977     int nr = si2->getNumRows();
01978     const double * cl = si2->getColLower();
01979     const double * cu = si2->getColUpper();
01980     const double * rl = si2->getRowLower();
01981     const double * ru = si2->getRowUpper();
01982     assert( nc == 8 );
01983     assert( nr == 5 );
01984     assert( eq(cl[0],2.5) );
01985     assert( eq(cl[1],0.0) );
01986     assert( eq(cl[2],0.0) );
01987     assert( eq(cl[3],0.0) );
01988     assert( eq(cl[4],0.5) );
01989     assert( eq(cl[5],0.0) );
01990     assert( eq(cl[6],0.0) );
01991     assert( eq(cl[7],0.0) );
01992     assert( eq(cu[0],si2->getInfinity()) );
01993     assert( eq(cu[1],4.1) );
01994     assert( eq(cu[2],1.0) );
01995     assert( eq(cu[3],1.0) );
01996     assert( eq(cu[4],4.0) );
01997     assert( eq(cu[5],si2->getInfinity()) );
01998     assert( eq(cu[6],si2->getInfinity()) );
01999     assert( eq(cu[7],4.3) );
02000 
02001     assert( eq(rl[0],2.5) );
02002     assert( eq(rl[1],-si2->getInfinity()) );
02003     assert( eq(rl[2],4.0) );
02004     assert( eq(rl[3],1.8) );
02005     assert( eq(rl[4],3.0) );
02006     assert( eq(ru[0],si2->getInfinity()) );
02007     assert( eq(ru[1],2.1) );
02008     assert( eq(ru[2],4.0) );
02009     assert( eq(ru[3],5.0) );
02010     assert( eq(ru[4],15.0) );
02011         
02012     // make sure col solution is something reasonable,
02013     // that is between upper and lower bounds
02014     const double * cs = exmip1Si->getColSolution();
02015     int c;
02016     bool okColSol=true;
02017     //double inf = exmip1Si->getInfinity();
02018     for ( c=0; c<nc; c++ ) {
02019       // if colSol is not between column bounds then 
02020       // colSol is unreasonable.
02021       if( !(cl[c]<=cs[c] && cs[c]<=cu[c]) ) okColSol=false;
02022       // if at least one column bound is not infinite,
02023       // then it is unreasonable to have colSol as infinite
02024       // FIXME: temporarily commented out pending some group thought on the
02025       //        semantics of this test. -- lh, 03.04.29 --
02026       // if ( (cl[c]<inf || cu[c]<inf) && cs[c]>=inf ) okColSol=false;
02027     }
02028     if( !okColSol )
02029       failureMessage(solverName,"getColSolution before solve on cloned solverInterface");
02030     
02031     assert( eq( si2->getObjCoefficients()[0],  1.0) );
02032     assert( eq( si2->getObjCoefficients()[1],  0.0) );
02033     assert( eq( si2->getObjCoefficients()[2],  0.0) );
02034     assert( eq( si2->getObjCoefficients()[3],  0.0) );
02035     assert( eq( si2->getObjCoefficients()[4],  2.0) );
02036     assert( eq( si2->getObjCoefficients()[5],  0.0) );
02037     assert( eq( si2->getObjCoefficients()[6],  0.0) );
02038     assert( eq( si2->getObjCoefficients()[7], -1.0) );
02039     
02040     // Test getting and setting of objective offset
02041     double objOffset;
02042     bool supported = si2->getDblParam(OsiObjOffset,objOffset);
02043     assert( supported );
02044     if( !eq( objOffset, 0.0 ) )
02045       failureMessage(solverName,"getDblParam OsiObjOffset on cloned solverInterface");
02046     delete si2;
02047   }
02048   // end of clone testing
02049   
02050   // Test apply cuts method
02051   {      
02052     OsiSolverInterface & im = *(exmip1Si->clone()); 
02053     OsiCuts cuts;
02054     
02055     // Generate some cuts 
02056     {
02057       // Get number of rows and columns in model
02058       int nr=im.getNumRows();
02059       int nc=im.getNumCols();
02060       assert( nr == 5 );
02061       assert( nc == 8 );
02062       
02063       // Generate a valid row cut from thin air
02064       int c;
02065       {
02066         int *inx = new int[nc];
02067         for (c=0;c<nc;c++) inx[c]=c;
02068         double *el = new double[nc];
02069         for (c=0;c<nc;c++) el[c]=((double)c)*((double)c);
02070         
02071         OsiRowCut rc;
02072         rc.setRow(nc,inx,el);
02073         rc.setLb(-100.);
02074         rc.setUb(100.);
02075         rc.setEffectiveness(22);
02076         
02077         cuts.insert(rc);
02078         delete[]el;
02079         delete[]inx;
02080       }
02081       
02082       // Generate valid col cut from thin air
02083       {
02084         const double * oslColLB = im.getColLower();
02085         const double * oslColUB = im.getColUpper();
02086         int *inx = new int[nc];
02087         for (c=0;c<nc;c++) inx[c]=c;
02088         double *lb = new double[nc];
02089         double *ub = new double[nc];
02090         for (c=0;c<nc;c++) lb[c]=oslColLB[c]+0.001;
02091         for (c=0;c<nc;c++) ub[c]=oslColUB[c]-0.001;
02092         
02093         OsiColCut cc;
02094         cc.setLbs(nc,inx,lb);
02095         cc.setUbs(nc,inx,ub);
02096         
02097         cuts.insert(cc);
02098         delete [] ub;
02099         delete [] lb;
02100         delete [] inx;
02101       }
02102       
02103       {
02104         // Generate a row and column cut which are ineffective
02105         OsiRowCut * rcP= new OsiRowCut;
02106         rcP->setEffectiveness(-1.);
02107         cuts.insert(rcP);
02108         assert(rcP==NULL);
02109         
02110         OsiColCut * ccP= new OsiColCut;
02111         ccP->setEffectiveness(-12.);
02112         cuts.insert(ccP);
02113         assert(ccP==NULL);
02114       }
02115       {
02116         //Generate inconsistent Row cut
02117         OsiRowCut rc;
02118         const int ne=1;
02119         int inx[ne]={-10};
02120         double el[ne]={2.5};
02121         rc.setRow(ne,inx,el);
02122         rc.setLb(3.);
02123         rc.setUb(4.);
02124         assert(!rc.consistent());
02125         cuts.insert(rc);
02126       }
02127       {
02128         //Generate inconsistent col cut
02129         OsiColCut cc;
02130         const int ne=1;
02131         int inx[ne]={-10};
02132         double el[ne]={2.5};
02133         cc.setUbs(ne,inx,el);
02134         assert(!cc.consistent());
02135         cuts.insert(cc);
02136       }
02137       {
02138         // Generate row cut which is inconsistent for model m
02139         OsiRowCut rc;
02140         const int ne=1;
02141         int inx[ne]={10};
02142         double el[ne]={2.5};
02143         rc.setRow(ne,inx,el);
02144         assert(rc.consistent());
02145         assert(!rc.consistent(im));
02146         cuts.insert(rc);
02147       }
02148       {
02149         // Generate col cut which is inconsistent for model m
02150         OsiColCut cc;
02151         const int ne=1;
02152         int inx[ne]={30};
02153         double el[ne]={2.0};
02154         cc.setLbs(ne,inx,el);
02155         assert(cc.consistent());
02156         assert(!cc.consistent(im));
02157         cuts.insert(cc);
02158       }
02159       {
02160         // Generate col cut which is infeasible
02161         OsiColCut cc;
02162         const int ne=1;
02163         int inx[ne]={0};
02164         double el[ne]={2.0};
02165         cc.setUbs(ne,inx,el);
02166         cc.setEffectiveness(1000.);
02167         assert(cc.consistent());
02168         assert(cc.consistent(im));
02169         assert(cc.infeasible(im));
02170         cuts.insert(cc);
02171       }
02172     }
02173     assert(cuts.sizeRowCuts()==4);
02174     assert(cuts.sizeColCuts()==5);
02175 
02176    {  
02177       OsiSolverInterface::ApplyCutsReturnCode rc = im.applyCuts(cuts);
02178       assert( rc.getNumIneffective() == 2 );
02179       assert( rc.getNumApplied() == 2 );
02180       assert( rc.getNumInfeasible() == 1 );
02181       assert( rc.getNumInconsistentWrtIntegerModel() == 2 );
02182       assert( rc.getNumInconsistent() == 2 );
02183       assert( cuts.sizeCuts() == rc.getNumIneffective() +
02184         rc.getNumApplied() +
02185         rc.getNumInfeasible() +
02186         rc.getNumInconsistentWrtIntegerModel() +
02187         rc.getNumInconsistent() );
02188     }
02189 
02190     delete &im;
02191   }
02192   // end of apply cut method testing
02193     
02194 
02195   // Test setting solution
02196 
02197   {
02198     OsiSolverInterface & m1 = *(exmip1Si->clone());
02199     int i;
02200     
02201     double * cs = new double[m1.getNumCols()];
02202     for ( i = 0;  i < m1.getNumCols();  i++ ) 
02203       cs[i] = i + .5;
02204     m1.setColSolution(cs);
02205     for ( i = 0;  i < m1.getNumCols();  i++ ) 
02206       assert(m1.getColSolution()[i] == i + .5);
02207     
02208     double * rs = new double[m1.getNumRows()];
02209     for ( i = 0;  i < m1.getNumRows();  i++ ) 
02210       rs[i] = i - .5;
02211     m1.setRowPrice(rs);
02212     for ( i = 0;  i < m1.getNumRows();  i++ ) 
02213       assert(m1.getRowPrice()[i] == i - .5);
02214     
02215     delete [] cs;
02216     delete [] rs;
02217     delete &m1;
02218   }
02219 
02220   // Test column type methods
02221 
02222   if ( volSolverInterface ) {
02223      // Test for vol since it does not support this function
02224      failureMessage(solverName,"column type methods all report continuous (OK for vol)");
02225   }
02226   else {
02227     OsiSolverInterface & fim = *(emptySi->clone());
02228     std::string fn = mpsDir+"exmip1";
02229     fim.readMps(fn.c_str(),"mps");
02230     // exmip1.mps has 2 integer variables with index 2 & 3
02231     assert(  fim.isContinuous(0) );
02232     assert(  fim.isContinuous(1) );
02233     assert( !fim.isContinuous(2) );
02234     assert( !fim.isContinuous(3) );
02235     assert(  fim.isContinuous(4) );
02236     
02237     assert( !fim.isInteger(0) );
02238     assert( !fim.isInteger(1) );
02239     assert(  fim.isInteger(2) );
02240     assert(  fim.isInteger(3) );
02241     assert( !fim.isInteger(4) );
02242     
02243     assert( !fim.isBinary(0) );
02244     assert( !fim.isBinary(1) );
02245     assert(  fim.isBinary(2) );
02246     assert(  fim.isBinary(3) );
02247     assert( !fim.isBinary(4) );
02248     
02249     assert( !fim.isIntegerNonBinary(0) );
02250     assert( !fim.isIntegerNonBinary(1) );
02251     assert( !fim.isIntegerNonBinary(2) );
02252     assert( !fim.isIntegerNonBinary(3) );
02253     assert( !fim.isIntegerNonBinary(4) );
02254     
02255     // Test fractionalIndices
02256 
02257     {
02258       double sol[]={1.0, 2.0, 2.9, 3.0, 4.0,0.0,0.0,0.0};
02259       fim.setColSolution(sol);
02260       OsiVectorInt fi = fim.getFractionalIndices(1e-5);
02261       assert( fi.size() == 1 );
02262       assert( fi[0]==2 );
02263       
02264       // Set integer variables very close to integer values
02265       sol[2]=5 + .00001/2.;
02266       sol[3]=8 - .00001/2.;
02267       fim.setColSolution(sol);
02268       fi = fim.getFractionalIndices(1e-5);
02269       assert( fi.size() == 0 );
02270       
02271       // Set integer variables close, but beyond tolerances
02272       sol[2]=5 + .00001*2.;
02273       sol[3]=8 - .00001*2.;
02274       fim.setColSolution(sol);
02275       fi = fim.getFractionalIndices(1e-5);
02276       assert( fi.size() == 2 );
02277       assert( fi[0]==2 );
02278       assert( fi[1]==3 );
02279     }
02280     
02281     // Change data so column 2 & 3 are integerNonBinary
02282     fim.setColUpper(2,5.0);
02283     assert( eq(fim.getColUpper()[2],5.0) );
02284     fim.setColUpper(3,6.0);
02285     assert( eq(fim.getColUpper()[3],6.0) );
02286     assert( !fim.isBinary(0) );
02287     assert( !fim.isBinary(1) );
02288     if( fim.isBinary(2) )
02289       failureMessage(solverName,"isBinary or setColUpper");
02290     if( fim.isBinary(3) )
02291       failureMessage(solverName,"isBinary or setColUpper");
02292     assert( !fim.isBinary(4) );
02293     
02294     assert( !fim.isIntegerNonBinary(0) );
02295     assert( !fim.isIntegerNonBinary(1) );
02296     if( !fim.isIntegerNonBinary(2) )
02297       failureMessage(solverName,"isIntegerNonBinary or setColUpper");
02298     if( !fim.isIntegerNonBinary(3) )
02299       failureMessage(solverName,"isIntegerNonBinary or setColUpper");
02300     assert( !fim.isIntegerNonBinary(4) );
02301     
02302     delete &fim;
02303   }
02304 
02305     
02306   // Test load and assign problem
02307   {
02308     {   
02309       OsiSolverInterface * base = exmip1Si->clone();
02310       OsiSolverInterface *  si1 = emptySi->clone(); 
02311       OsiSolverInterface *  si2 = emptySi->clone(); 
02312       OsiSolverInterface *  si3 = emptySi->clone(); 
02313       OsiSolverInterface *  si4 = emptySi->clone();  
02314       OsiSolverInterface *  si5 = emptySi->clone();  
02315       OsiSolverInterface *  si6 = emptySi->clone(); 
02316       OsiSolverInterface *  si7 = emptySi->clone();  
02317       OsiSolverInterface *  si8 = emptySi->clone(); 
02318         
02319       si1->loadProblem(*base->getMatrixByCol(),
02320                        base->getColLower(),base->getColUpper(),
02321                        base->getObjCoefficients(),
02322                        base->getRowSense(),base->getRightHandSide(),
02323                        base->getRowRange());
02324       si2->loadProblem(*base->getMatrixByRow(),
02325                        base->getColLower(),base->getColUpper(),
02326                        base->getObjCoefficients(),
02327                        base->getRowSense(),base->getRightHandSide(),
02328                        base->getRowRange());
02329       si3->loadProblem(*base->getMatrixByCol(),
02330                        base->getColLower(),base->getColUpper(),
02331                        base->getObjCoefficients(),
02332                        base->getRowLower(),base->getRowUpper() );
02333       si4->loadProblem(*base->getMatrixByCol(),
02334                        base->getColLower(),base->getColUpper(),
02335                        base->getObjCoefficients(),
02336                        base->getRowLower(),base->getRowUpper() );
02337       {
02338         double objOffset;
02339         base->getDblParam(OsiObjOffset,objOffset);
02340         si1->setDblParam(OsiObjOffset,objOffset);
02341         si2->setDblParam(OsiObjOffset,objOffset);
02342         si3->setDblParam(OsiObjOffset,objOffset);
02343         si4->setDblParam(OsiObjOffset,objOffset);
02344         si5->setDblParam(OsiObjOffset,objOffset);
02345         si6->setDblParam(OsiObjOffset,objOffset);
02346         si7->setDblParam(OsiObjOffset,objOffset);
02347         si8->setDblParam(OsiObjOffset,objOffset);
02348       }
02349       CoinPackedMatrix * pm = new CoinPackedMatrix(*base->getMatrixByCol());
02350       double * clb = new double[base->getNumCols()];
02351       std::copy(base->getColLower(),
02352                 base->getColLower()+base->getNumCols(),clb);
02353       double * cub = new double[base->getNumCols()];
02354       std::copy(base->getColUpper(),
02355                 base->getColUpper()+base->getNumCols(),cub);
02356       double * objc = new double[base->getNumCols()];
02357       std::copy(base->getObjCoefficients(),
02358                 base->getObjCoefficients()+base->getNumCols(),objc);
02359       double * rlb = new double[base->getNumRows()];
02360       std::copy(base->getRowLower(),
02361                 base->getRowLower()+base->getNumRows(),rlb);
02362       double * rub = new double[base->getNumRows()];
02363       std::copy(base->getRowUpper(),
02364                 base->getRowUpper()+base->getNumRows(),rub);
02365       si5->assignProblem(pm,clb,cub,objc,rlb,rub);
02366       assert(pm==NULL);
02367       assert(clb==NULL);
02368       assert(cub==NULL);
02369       assert(objc==NULL);
02370       assert(rlb==NULL);
02371       assert(rub==NULL);
02372         
02373       pm = new CoinPackedMatrix(*base->getMatrixByRow());
02374       clb = new double[base->getNumCols()];
02375       std::copy(base->getColLower(),
02376                 base->getColLower()+base->getNumCols(),clb);
02377       cub = new double[base->getNumCols()];
02378       std::copy(base->getColUpper(),
02379                 base->getColUpper()+base->getNumCols(),cub);
02380       objc = new double[base->getNumCols()];
02381       std::copy(base->getObjCoefficients(),
02382                 base->getObjCoefficients()+base->getNumCols(),objc);
02383       rlb = new double[base->getNumRows()];
02384       std::copy(base->getRowLower(),
02385                 base->getRowLower()+base->getNumRows(),rlb);
02386       rub = new double[base->getNumRows()];
02387       std::copy(base->getRowUpper(),
02388                 base->getRowUpper()+base->getNumRows(),rub);
02389       si6->assignProblem(pm,clb,cub,objc,rlb,rub);
02390       assert(pm==NULL);
02391       assert(clb==NULL);
02392       assert(cub==NULL);
02393       assert(objc==NULL);
02394       assert(rlb==NULL);
02395       assert(rub==NULL);      
02396         
02397       pm = new CoinPackedMatrix(*base->getMatrixByCol());
02398       clb = new double[base->getNumCols()];
02399       std::copy(base->getColLower(),
02400                 base->getColLower()+base->getNumCols(),clb);
02401       cub = new double[base->getNumCols()];
02402       std::copy(base->getColUpper(),
02403                 base->getColUpper()+base->getNumCols(),cub);
02404       objc = new double[base->getNumCols()];
02405       std::copy(base->getObjCoefficients(),
02406                 base->getObjCoefficients()+base->getNumCols(),objc);
02407       char * rsen = new char[base->getNumRows()];
02408       std::copy(base->getRowSense(),
02409                 base->getRowSense()+base->getNumRows(),rsen);
02410       double * rhs = new double[base->getNumRows()];
02411       std::copy(base->getRightHandSide(),
02412                 base->getRightHandSide()+base->getNumRows(),rhs);
02413       double * rng = new double[base->getNumRows()];
02414       std::copy(base->getRowRange(),
02415                 base->getRowRange()+base->getNumRows(),rng);
02416       si7->assignProblem(pm,clb,cub,objc,rsen,rhs,rng);
02417       assert(pm==NULL);
02418       assert(clb==NULL);
02419       assert(cub==NULL);
02420       assert(objc==NULL);
02421       assert(rsen==NULL);
02422       assert(rhs==NULL);
02423       assert(rng==NULL);
02424         
02425       pm = new CoinPackedMatrix(*base->getMatrixByCol());
02426       clb = new double[base->getNumCols()];
02427       std::copy(base->getColLower(),
02428                 base->getColLower()+base->getNumCols(),clb);
02429       cub = new double[base->getNumCols()];
02430       std::copy(base->getColUpper(),
02431                 base->getColUpper()+base->getNumCols(),cub);
02432       objc = new double[base->getNumCols()];
02433       std::copy(base->getObjCoefficients(),
02434                 base->getObjCoefficients()+base->getNumCols(),objc);
02435       rsen = new char[base->getNumRows()];
02436       std::copy(base->getRowSense(),
02437                 base->getRowSense()+base->getNumRows(),rsen);
02438       rhs = new double[base->getNumRows()];
02439       std::copy(base->getRightHandSide(),
02440                 base->getRightHandSide()+base->getNumRows(),rhs);
02441       rng = new double[base->getNumRows()];
02442       std::copy(base->getRowRange(),
02443                 base->getRowRange()+base->getNumRows(),rng);
02444       si8->assignProblem(pm,clb,cub,objc,rsen,rhs,rng);
02445       assert(pm==NULL);
02446       assert(clb==NULL);
02447       assert(cub==NULL);
02448       assert(objc==NULL);
02449       assert(rsen==NULL);
02450       assert(rhs==NULL);
02451       assert(rng==NULL);
02452      
02453         
02454       // Create an indices vector        
02455       CoinPackedVector basePv,pv;
02456       assert(base->getNumCols()<10);
02457       assert(base->getNumRows()<10);
02458       int indices[10];
02459       int i;
02460       for (i=0; i<10; i++) indices[i]=i;
02461         
02462       // Test solve methods.
02463       try {
02464         base->initialSolve();
02465         si1->initialSolve();
02466         si2->initialSolve();
02467         si3->initialSolve();
02468         si4->initialSolve();
02469         si5->initialSolve();
02470         si6->initialSolve();
02471         si7->initialSolve();
02472         si8->initialSolve();
02473       }        
02474       catch (CoinError e) {
02475 #ifdef COIN_USE_VOL
02476         // Vol solver interface is expected to throw
02477         // an error if the data has a ranged row.
02478           
02479         // Check that using Vol SI
02480         OsiVolSolverInterface * vsi =
02481           dynamic_cast<OsiVolSolverInterface *>(base);
02482         assert( vsi != NULL );        
02483           
02484         // Test that there is non-zero range
02485         basePv.setFull(base->getNumRows(),base->getRowRange());
02486         pv.setConstant( base->getNumRows(), indices, 0.0 );
02487         assert(!basePv.isEquivalent(pv)); 
02488 #else
02489         assert(0==1);
02490 #endif
02491       }
02492       
02493       // Test WriteMps
02494       
02495       {
02496 
02497         OsiSolverInterface *  si1 = emptySi->clone(); 
02498         OsiSolverInterface *  si2 = emptySi->clone(); 
02499         si1->readMps(fn.c_str(),"mps");
02500         si1->writeMpsNative("test.out",NULL,NULL);
02501         si1->writeMps("test2","out");
02502         si2->readMps("test.out","");
02503         bool solved = true;
02504         try {
02505            si1->initialSolve();
02506         }
02507         catch (CoinError e) {
02508            if (e.className() != "OsiVolSolverInterface") {
02509               printf("Couldn't solve initial LP in testing WriteMps\n");
02510               abort();
02511            }
02512            solved = false;
02513         }
02514         if (solved) {
02515            si2->initialSolve();
02516            double soln = si1->getObjValue();       
02517            CoinRelFltEq eq(1.0e-8) ;
02518            assert( eq(soln,si2->getObjValue()));       
02519         }
02520         delete si1;
02521         delete si2;
02522       }
02523         
02524       // Test collower
02525       basePv.setVector(base->getNumCols(),indices,base->getColLower());
02526       pv.setVector( si1->getNumCols(),indices, si1->getColLower());
02527       assert(basePv.isEquivalent(pv));
02528       pv.setVector( si2->getNumCols(),indices, si2->getColLower());
02529       assert(basePv.isEquivalent(pv));
02530       pv.setVector( si3->getNumCols(),indices, si3->getColLower());
02531       assert(basePv.isEquivalent(pv));
02532       pv.setVector( si4->getNumCols(),indices, si4->getColLower());
02533       assert(basePv.isEquivalent(pv));
02534       pv.setVector( si5->getNumCols(),indices, si5->getColLower());
02535       assert(basePv.isEquivalent(pv));
02536       pv.setVector( si6->getNumCols(),indices, si6->getColLower());
02537       assert(basePv.isEquivalent(pv));
02538       pv.setVector( si7->getNumCols(),indices, si7->getColLower());
02539       assert(basePv.isEquivalent(pv));
02540       pv.setVector( si8->getNumCols(),indices, si8->getColLower());
02541       assert(basePv.isEquivalent(pv));
02542         
02543       // Test colupper
02544       basePv.setVector(base->getNumCols(),indices,base->getColUpper());
02545       pv.setVector( si1->getNumCols(),indices, si1->getColUpper());
02546       assert(basePv.isEquivalent(pv));
02547       pv.setVector( si2->getNumCols(),indices, si2->getColUpper());
02548       assert(basePv.isEquivalent(pv));
02549       pv.setVector( si3->getNumCols(),indices, si3->getColUpper());
02550       assert(basePv.isEquivalent(pv));
02551       pv.setVector( si4->getNumCols(),indices, si4->getColUpper());
02552       assert(basePv.isEquivalent(pv));
02553       pv.setVector( si5->getNumCols(),indices, si5->getColUpper());
02554       assert(basePv.isEquivalent(pv));
02555       pv.setVector( si6->getNumCols(),indices, si6->getColUpper());
02556       assert(basePv.isEquivalent(pv));
02557       pv.setVector( si7->getNumCols(),indices, si7->getColUpper());
02558       assert(basePv.isEquivalent(pv));
02559       pv.setVector( si8->getNumCols(),indices, si8->getColUpper());
02560       assert(basePv.isEquivalent(pv));
02561         
02562       // Test getObjCoefficients
02563       basePv.setVector(base->getNumCols(),indices,base->getObjCoefficients());
02564       pv.setVector( si1->getNumCols(),indices, si1->getObjCoefficients());
02565       assert(basePv.isEquivalent(pv));
02566       pv.setVector( si2->getNumCols(),indices, si2->getObjCoefficients());
02567       assert(basePv.isEquivalent(pv));
02568       pv.setVector( si3->getNumCols(),indices, si3->getObjCoefficients());
02569       assert(basePv.isEquivalent(pv));
02570       pv.setVector( si4->getNumCols(),indices, si4->getObjCoefficients());
02571       assert(basePv.isEquivalent(pv));
02572       pv.setVector( si5->getNumCols(),indices, si5->getObjCoefficients());
02573       assert(basePv.isEquivalent(pv));
02574       pv.setVector( si6->getNumCols(),indices, si6->getObjCoefficients());
02575       assert(basePv.isEquivalent(pv));
02576       pv.setVector( si7->getNumCols(),indices, si7->getObjCoefficients());
02577       assert(basePv.isEquivalent(pv));
02578       pv.setVector( si8->getNumCols(),indices, si8->getObjCoefficients());
02579       assert(basePv.isEquivalent(pv));
02580                 
02581       // Test rowrhs
02582       basePv.setFull(base->getNumRows(),base->getRightHandSide());
02583       pv.setFull( si1->getNumRows(), si1->getRightHandSide());
02584       assert(basePv.isEquivalent(pv));
02585       pv.setFull( si2->getNumRows(), si2->getRightHandSide());
02586       assert(basePv.isEquivalent(pv));
02587       pv.setFull( si3->getNumRows(), si3->getRightHandSide());
02588       assert(basePv.isEquivalent(pv));
02589       pv.setFull( si4->getNumRows(), si4->getRightHandSide());
02590       assert(basePv.isEquivalent(pv));
02591       pv.setFull( si5->getNumRows(), si5->getRightHandSide());
02592       assert(basePv.isEquivalent(pv));
02593       pv.setFull( si6->getNumRows(), si6->getRightHandSide());
02594       assert(basePv.isEquivalent(pv));
02595       pv.setFull( si7->getNumRows(), si7->getRightHandSide());
02596       assert(basePv.isEquivalent(pv));
02597       pv.setFull( si8->getNumRows(), si8->getRightHandSide());
02598       assert(basePv.isEquivalent(pv));
02599         
02600       // Test rowrange
02601       basePv.setFull(base->getNumRows(),base->getRowRange());
02602       pv.setFull( si1->getNumRows(), si1->getRowRange());
02603       assert(basePv.isEquivalent(pv));
02604       pv.setFull( si2->getNumRows(), si2->getRowRange());
02605       assert(basePv.isEquivalent(pv));
02606       pv.setFull( si3->getNumRows(), si3->getRowRange());
02607       assert(basePv.isEquivalent(pv));
02608       pv.setFull( si4->getNumRows(), si4->getRowRange());
02609       assert(basePv.isEquivalent(pv));
02610       pv.setFull( si5->getNumRows(), si5->getRowRange());
02611       assert(basePv.isEquivalent(pv));
02612       pv.setFull( si6->getNumRows(), si6->getRowRange());
02613       assert(basePv.isEquivalent(pv));
02614       pv.setFull( si7->getNumRows(), si7->getRowRange());
02615       assert(basePv.isEquivalent(pv));
02616       pv.setFull( si8->getNumRows(), si8->getRowRange());
02617       assert(basePv.isEquivalent(pv));
02618         
02619       // Test row sense
02620       {
02621         const char * cb = base->getRowSense();
02622         const char * c1 = si1->getRowSense();
02623         const char * c2 = si2->getRowSense();
02624         const char * c3 = si3->getRowSense();
02625         const char * c4 = si4->getRowSense();
02626         const char * c5 = si5->getRowSense();
02627         const char * c6 = si6->getRowSense();
02628         const char * c7 = si7->getRowSense();
02629         const char * c8 = si8->getRowSense();
02630         int nr = base->getNumRows();
02631         for ( i=0; i<nr; i++ ) {
02632           assert( cb[i]==c1[i] );
02633           assert( cb[i]==c2[i] );
02634           assert( cb[i]==c3[i] );
02635           assert( cb[i]==c4[i] );
02636           assert( cb[i]==c5[i] );
02637           assert( cb[i]==c6[i] );
02638           assert( cb[i]==c7[i] );
02639           assert( cb[i]==c8[i] );
02640         }
02641       }
02642         
02643       // Test rowlower
02644       basePv.setVector(base->getNumRows(),indices,base->getRowLower());
02645       pv.setVector( si1->getNumRows(),indices, si1->getRowLower());
02646       assert(basePv.isEquivalent(pv));
02647       pv.setVector( si2->getNumRows(),indices, si2->getRowLower());
02648       assert(basePv.isEquivalent(pv));
02649       pv.setVector( si3->getNumRows(),indices, si3->getRowLower());
02650       assert(basePv.isEquivalent(pv));
02651       pv.setVector( si4->getNumRows(),indices, si4->getRowLower());
02652       assert(basePv.isEquivalent(pv));
02653       pv.setVector( si5->getNumRows(),indices, si5->getRowLower());
02654       assert(basePv.isEquivalent(pv));
02655       pv.setVector( si6->getNumRows(),indices, si6->getRowLower());
02656       assert(basePv.isEquivalent(pv));
02657       pv.setVector( si7->getNumRows(),indices, si7->getRowLower());
02658       assert(basePv.isEquivalent(pv));
02659       pv.setVector( si8->getNumRows(),indices, si8->getRowLower());
02660       assert(basePv.isEquivalent(pv));
02661         
02662       // Test rowupper
02663       basePv.setVector(base->getNumRows(),indices,base->getRowUpper());
02664       pv.setVector( si1->getNumRows(),indices, si1->getRowUpper());
02665       assert(basePv.isEquivalent(pv));
02666       pv.setVector( si2->getNumRows(),indices, si2->getRowUpper());
02667       assert(basePv.isEquivalent(pv));
02668       pv.setVector( si3->getNumRows(),indices, si3->getRowUpper());
02669       assert(basePv.isEquivalent(pv));
02670       pv.setVector( si4->getNumRows(),indices, si4->getRowUpper());
02671       assert(basePv.isEquivalent(pv));
02672       pv.setVector( si5->getNumRows(),indices, si5->getRowUpper());
02673       assert(basePv.isEquivalent(pv));
02674       pv.setVector( si6->getNumRows(),indices, si6->getRowUpper());
02675       assert(basePv.isEquivalent(pv));
02676       pv.setVector( si7->getNumRows(),indices, si7->getRowUpper());
02677       assert(basePv.isEquivalent(pv));
02678       pv.setVector( si8->getNumRows(),indices, si8->getRowUpper());
02679       assert(basePv.isEquivalent(pv)); 
02680         
02681       // Test Constraint Matrix
02682       assert( base->getMatrixByCol()->isEquivalent(*si1->getMatrixByCol()) );
02683       assert( base->getMatrixByRow()->isEquivalent(*si1->getMatrixByRow()) );
02684       assert( base->getMatrixByCol()->isEquivalent(*si2->getMatrixByCol()) );
02685       assert( base->getMatrixByRow()->isEquivalent(*si2->getMatrixByRow()) );
02686       assert( base->getMatrixByCol()->isEquivalent(*si3->getMatrixByCol()) );
02687       assert( base->getMatrixByRow()->isEquivalent(*si3->getMatrixByRow()) );
02688       assert( base->getMatrixByCol()->isEquivalent(*si4->getMatrixByCol()) );
02689       assert( base->getMatrixByRow()->isEquivalent(*si4->getMatrixByRow()) );
02690       assert( base->getMatrixByCol()->isEquivalent(*si5->getMatrixByCol()) );
02691       assert( base->getMatrixByRow()->isEquivalent(*si5->getMatrixByRow()) );
02692       assert( base->getMatrixByCol()->isEquivalent(*si6->getMatrixByCol()) );
02693       assert( base->getMatrixByRow()->isEquivalent(*si6->getMatrixByRow()) );
02694       assert( base->getMatrixByCol()->isEquivalent(*si7->getMatrixByCol()) );
02695       assert( base->getMatrixByRow()->isEquivalent(*si7->getMatrixByRow()) );
02696       assert( base->getMatrixByCol()->isEquivalent(*si8->getMatrixByCol()) );
02697       assert( base->getMatrixByRow()->isEquivalent(*si8->getMatrixByRow()) );
02698         
02699       // Test Objective Value
02700       assert( eq(base->getObjValue(),si1->getObjValue()) );
02701       assert( eq(base->getObjValue(),si2->getObjValue()) );
02702       assert( eq(base->getObjValue(),si3->getObjValue()) );
02703       assert( eq(base->getObjValue(),si4->getObjValue()) );
02704       assert( eq(base->getObjValue(),si5->getObjValue()) );
02705       assert( eq(base->getObjValue(),si6->getObjValue()) );
02706       assert( eq(base->getObjValue(),si7->getObjValue()) );
02707       assert( eq(base->getObjValue(),si8->getObjValue()) );
02708         
02709       // Clean-up
02710       delete si8;
02711       delete si7;
02712       delete si6;
02713       delete si5;
02714       delete si4;
02715       delete si3;
02716       delete si2;
02717       delete si1;
02718       delete base;
02719     }     
02720     // Test load/assign with null parms
02721     {
02722       //Load problem with row bounds and all rims at defaults
02723       {
02724         OsiSolverInterface *  si = emptySi->clone(); 
02725           
02726         si->loadProblem(*exmip1Si->getMatrixByCol(),NULL,NULL,NULL,NULL,NULL);
02727           
02728         // Test column settings
02729         assert(si->getNumCols()==exmip1Si->getNumCols() );
02730         for ( i=0; i<si->getNumCols(); i++ ) {
02731           assert( eq(si->getColLower()[i],0.0) );
02732           assert( eq(si->getColUpper()[i],si->getInfinity()) );
02733           assert( eq(si->getObjCoefficients()[i],0.0) );
02734         }
02735         // Test row settings
02736         assert(si->getNumRows()==exmip1Si->getNumRows() );
02737         const double * rh = si->getRightHandSide();
02738         const double * rr = si->getRowRange();
02739         const char * rs = si->getRowSense();
02740         const double * rl = si->getRowLower();
02741         const double * ru = si->getRowUpper();
02742         for ( i=0; i<si->getNumRows(); i++ ) {
02743           assert( eq(rh[i],0.0) );
02744           assert( eq(rr[i],0.0) );
02745           assert( 'N'==rs[i] );
02746           assert( eq(rl[i],-si->getInfinity()) );
02747           assert( eq(ru[i], si->getInfinity()) );
02748         }
02749           
02750         delete si;
02751       }
02752       //Load problem with row rhs and all rims at defaults
02753       {
02754         OsiSolverInterface *  si = emptySi->clone(); 
02755           
02756         si->loadProblem(*exmip1Si->getMatrixByRow(),
02757                         NULL,NULL,NULL,
02758                         exmip1Si->getRowSense(),
02759                         exmip1Si->getRightHandSide(),
02760                         exmip1Si->getRowRange());
02761         // Test column settings
02762         assert(si->getNumCols()==exmip1Si->getNumCols() );
02763         for ( i=0; i<si->getNumCols(); i++ ) {
02764           assert( eq(si->getColLower()[i],0.0) );
02765           assert( eq(si->getColUpper()[i],si->getInfinity()) );
02766           assert( eq(si->getObjCoefficients()[i],0.0) );
02767         }
02768         // Test row settings
02769         assert(si->getNumRows()==exmip1Si->getNumRows() );
02770         for ( i=0; i<si->getNumRows(); i++ ) {
02771           char s = si->getRowSense()[i];
02772           assert( eq(si->getRightHandSide()[i],
02773                      exmip1Si->getRightHandSide()[i]) );
02774           assert( eq(si->getRowRange()[i],
02775                      exmip1Si->getRowRange()[i]) );
02776           assert( s==exmip1Si->getRowSense()[i] );
02777             
02778           if ( s=='G' ) {
02779             assert( eq(si->getRowLower()[i],
02780                        exmip1Si->getRightHandSide()[i]) );
02781             assert( eq(si->getRowUpper()[i],
02782                        si->getInfinity()) );
02783           }
02784           else if ( s=='L' ) {
02785             assert( eq(si->getRowLower()[i],
02786                        -si->getInfinity()) );
02787             assert( eq(si->getRowUpper()[i],
02788                        exmip1Si->getRightHandSide()[i]) );
02789           }
02790           else if ( s=='E' ) {
02791             assert( eq(si->getRowLower()[i],
02792                        si->getRowUpper()[i]) );
02793             assert( eq(si->getRowUpper()[i],
02794                        exmip1Si->getRightHandSide()[i]) );
02795           }
02796           else if ( s=='N' ) {
02797             assert( eq(si->getRowLower()[i], -si->getInfinity()) );
02798             assert( eq(si->getRowUpper()[i],  si->getInfinity()) );
02799           }
02800           else if ( s=='R' ) {
02801             assert( eq(si->getRowLower()[i],
02802                        exmip1Si->getRightHandSide()[i] -
02803                        exmip1Si->getRowRange()[i]) );
02804             assert( eq(si->getRowUpper()[i],
02805                        exmip1Si->getRightHandSide()[i]) );
02806           }
02807         }
02808           
02809         delete si;
02810       }
02811       // Test adding rows to NULL
02812       {
02813         OsiSolverInterface *  si = emptySi->clone();
02814         int i;
02815 
02816         //Matrix
02817         int column[]={0,1,2};
02818         double row1E[]={4.0,7.0,5.0};
02819         double row2E[]={7.0,4.0,5.0};
02820         CoinPackedVector row1(3,column,row1E);
02821         CoinPackedVector row2(3,column,row2E);
02822 
02823         double objective[]={5.0,6.0,5.5};
02824 
02825   {
02826           // Add empty columns
02827           for (i=0;i<3;i++) 
02828             si->addCol(CoinPackedVector(),0.0,10.0,objective[i]);
02829 
02830           // Add rows
02831           si->addRow(row1,2.0,100.0);
02832           si->addRow(row2,2.0,100.0);
02833 
02834     // Vol can not solve problem of this form
02835     if ( !volSolverInterface ) {
02836             // solve
02837             si->initialSolve();
02838 
02839       CoinRelFltEq eq(1.0e-7) ;
02840       double objValue = si->getObjValue();
02841             if ( !eq(objValue,2.0) )
02842         failureMessage(solverName,"getObjValue after adding empty cols and then rows.");;
02843     }
02844   }
02845 
02846         delete si;
02847       }
02848       // Test adding columns to NULL
02849       {
02850         OsiSolverInterface *  si = emptySi->clone();
02851         int i;
02852 
02853         //Matrix
02854         int row[]={0,1};
02855         double col1E[]={4.0,7.0};
02856         double col2E[]={7.0,4.0};
02857         double col3E[]={5.0,5.0};
02858         CoinPackedVector col1(2,row,col1E);
02859         CoinPackedVector col2(2,row,col2E);
02860         CoinPackedVector col3(2,row,col3E);
02861 
02862         double objective[]={5.0,6.0,5.5};
02863   {
02864      // Add empty rows
02865      for (i=0;i<2;i++) 
02866         si->addRow(CoinPackedVector(),2.0,100.0);
02867 
02868      // Add columns
02869      if ( volSolverInterface ) {
02870         // FIXME: this test could be done w/ the volume, but the rows must not
02871         // be ranged.
02872         failureMessage(solverName,"addCol add columns to null");
02873      }
02874      else {
02875         si->addCol(col1,0.0,10.0,objective[0]);
02876         si->addCol(col2,0.0,10.0,objective[1]);
02877         si->addCol(col3,0.0,10.0,objective[2]);
02878 
02879         // solve
02880         si->initialSolve();
02881 
02882         CoinRelFltEq eq(1.0e-7) ;      
02883         double objValue = si->getObjValue();
02884         if ( !eq(objValue,2.0) )
02885            failureMessage(solverName,"getObjValue after adding empty rows and then cols.");
02886 
02887      }
02888   }
02889         delete si;
02890       }
02891     }
02892   }
02893 
02894   // Add a Laci suggested test case
02895   // Load in a problem as column ordered matrix, 
02896   // extract the row ordered copy, 
02897   // add a row, 
02898   // extract the row ordered copy again and test whether it's ok. 
02899   // (the same can be done with reversing the role
02900   //  of row and column ordered.)
02901   {
02902     OsiSolverInterface *  si = emptySi->clone(); 
02903       
02904     si->loadProblem(
02905                     *(exmip1Si->getMatrixByCol()),
02906                     exmip1Si->getColLower(),
02907                     exmip1Si->getColUpper(),
02908                     exmip1Si->getObjCoefficients(),
02909                     exmip1Si->getRowSense(),
02910                     exmip1Si->getRightHandSide(),
02911                     exmip1Si->getRowRange() );
02912 
02913     CoinPackedMatrix pm1 = *(si->getMatrixByRow());
02914 
02915     // Get a row of the matrix to make a cut
02916     CoinPackedVector pv =exmip1Si->getMatrixByRow()->getVector(1);
02917     pv.setElement(0,3.14*pv.getElements()[0]);
02918 
02919     OsiRowCut rc;
02920     rc.setRow( pv );
02921     rc.setLb( exmip1Si->getRowLower()[1]-0.5 );
02922     rc.setUb( exmip1Si->getRowUpper()[1]-0.5 );
02923 
02924     OsiCuts cuts;
02925     cuts.insert(rc);
02926 
02927     si->applyCuts(cuts);
02928       
02929     CoinPackedMatrix pm2 = *(si->getMatrixByRow());
02930 
02931     assert(pm1.getNumRows()==pm2.getNumRows()-1);
02932     int i;
02933     for( i=0; i<pm1.getNumRows(); ++i ) {
02934       assert( pm1.getVector(i) == pm2.getVector(i) );
02935     }
02936     // Test that last row of pm2 is same as added cut
02937     assert( pm2.getVector(pm2.getNumRows()-1).isEquivalent(pv) );
02938 
02939     delete si;
02940   }
02941   {
02942     OsiSolverInterface *  si = emptySi->clone(); 
02943       
02944     si->loadProblem(
02945                     *(exmip1Si->getMatrixByRow()),
02946                     exmip1Si->getColLower(),
02947                     exmip1Si->getColUpper(),
02948                     exmip1Si->getObjCoefficients(),
02949                     exmip1Si->getRowLower(),
02950                     exmip1Si->getRowUpper() );
02951 
02952     CoinPackedMatrix pm1 = *(si->getMatrixByCol());
02953 
02954     // Get a row of the matrix to make a cut
02955     CoinPackedVector pv =exmip1Si->getMatrixByRow()->getVector(1);
02956     pv.setElement(0,3.14*pv.getElements()[0]);
02957 
02958     OsiRowCut rc;
02959     rc.setRow( pv );
02960     rc.setLb( exmip1Si->getRowLower()[1]-0.5 );
02961     rc.setUb( exmip1Si->getRowUpper()[1]-0.5 );
02962 
02963     OsiCuts cuts;
02964     cuts.insert(rc);
02965 
02966     si->applyCuts(cuts);
02967       
02968     CoinPackedMatrix pm2 = *(si->getMatrixByCol());
02969 
02970     assert( pm1.isColOrdered() );
02971     assert( pm2.isColOrdered() );
02972     assert( pm1.getNumRows()==pm2.getNumRows()-1 );
02973 
02974     CoinPackedMatrix pm1ByRow;
02975     pm1ByRow.reverseOrderedCopyOf(pm1);
02976     CoinPackedMatrix pm2ByRow;
02977     pm2ByRow.reverseOrderedCopyOf(pm2);
02978 
02979     assert( !pm1ByRow.isColOrdered() );
02980     assert( !pm2ByRow.isColOrdered() );      
02981     assert( pm1ByRow.getNumRows()==pm2ByRow.getNumRows()-1 );
02982     assert( pm1.getNumRows() == pm1ByRow.getNumRows() );
02983     assert( pm2.getNumRows() == pm2ByRow.getNumRows() );
02984 
02985     int i;
02986     for( i=0; i<pm1ByRow.getNumRows(); ++i ) {
02987       assert( pm1ByRow.getVector(i) == pm2ByRow.getVector(i) );
02988     }
02989     // Test that last row of pm2 is same as added cut
02990     assert( pm2ByRow.getVector(pm2ByRow.getNumRows()-1).isEquivalent(pv) );
02991 
02992     delete si;
02993   }
02994     
02995   delete exmip1Si;
02996 
02997   {
02998     // Testing parameter settings
02999     OsiSolverInterface *  si = emptySi->clone();
03000     int i;
03001     int ival;
03002     double dval;
03003     bool hint;
03004     OsiHintStrength hintStrength;
03005     assert(si->getIntParam(OsiLastIntParam, ival) == false);
03006     assert(si->getDblParam(OsiLastDblParam, dval) == false);
03007     assert(si->getHintParam(OsiLastHintParam, hint) == false);
03008     assert(si->setIntParam(OsiLastIntParam, 0) == false);
03009     assert(si->setDblParam(OsiLastDblParam, 0) == false);
03010     assert(si->setHintParam(OsiLastHintParam, false) == false);
03011     
03012     for (i = 0; i < OsiLastIntParam; ++i) {
03013       const bool exists = si->getIntParam(static_cast<OsiIntParam>(i), ival);
03014       // existence and test should result in the same
03015       assert(!exists ^ testIntParam(si, i, -1));
03016       assert(!exists ^ testIntParam(si, i, 0));
03017       assert(!exists ^ testIntParam(si, i, 1));
03018       assert(!exists ^ testIntParam(si, i, 9999999));
03019       assert(!exists ^ testIntParam(si, i, INT_MAX));
03020       if (exists)
03021         assert(si->getIntParam(static_cast<OsiIntParam>(i), ival));
03022     }
03023     // Test for glpk since it dies on this test
03024     if ( glpkSolverInterface ) {
03025       failureMessage(solverName,"[g,s]etDblParam");
03026     }
03027     else {
03028       for (i = 0; i < OsiLastDblParam; ++i) {
03029         const bool exists = si->getDblParam(static_cast<OsiDblParam>(i), dval);
03030         // existence and test should result in the same
03031         assert(!exists ^ testDblParam(si, i, -1e50));
03032         assert(!exists ^ testDblParam(si, i, -1e10));
03033         assert(!exists ^ testDblParam(si, i, -1));
03034         assert(!exists ^ testDblParam(si, i, -1e-4));
03035         assert(!exists ^ testDblParam(si, i, -1e-15));
03036         assert(!exists ^ testDblParam(si, i, 1e50));
03037         assert(!exists ^ testDblParam(si, i, 1e10));
03038         assert(!exists ^ testDblParam(si, i, 1));
03039         assert(!exists ^ testDblParam(si, i, 1e-4));
03040         assert(!exists ^ testDblParam(si, i, 1e-15));
03041         if (exists)
03042           assert(si->setDblParam(static_cast<OsiDblParam>(i), dval));
03043       }
03044     }
03045 
03046     // test hints --- see testHintParam for detailed explanation.
03047 
03048     { int throws = 0 ;
03049 
03050       for (i = 0 ; i < OsiLastHintParam ; ++i)
03051       { const bool exists =
03052           si->getHintParam(static_cast<OsiHintParam>(i),hint,hintStrength) ;
03053 
03054         assert(!exists ^ testHintParam(si,i,true,OsiHintIgnore,&throws)) ;
03055         assert(!exists ^ testHintParam(si,i,true,OsiHintTry,&throws)) ;
03056         assert(!exists ^ testHintParam(si,i,false,OsiHintTry,&throws)) ;
03057         assert(!exists ^ testHintParam(si,i,true,OsiHintDo,&throws)) ;
03058         assert(!exists ^ testHintParam(si,i,false,OsiHintDo,&throws)) ;
03059         assert(!exists ^ testHintParam(si,i,true,OsiForceDo,&throws)) ;
03060         assert(!exists ^ testHintParam(si,i,false,OsiForceDo,&throws)) ; }
03061       
03062       std::cerr << "Checked " << OsiLastHintParam <<
03063                    " hints x (true, false) at strength OsiForceDo; " <<
03064                    throws << " throws." << std::endl ;
03065     }
03066 
03067     delete si;
03068   }
03069   
03070   // Test case submitted by Vivian De Smedt (slightly modifed to work with
03071   // Vol Algorithm).
03072 
03073   {
03074     OsiSolverInterface *s = emptySi->clone();
03075     double dEmpty = 0;
03076     int iEmpty = 0;
03077     //char cEmpty = '?';
03078     
03079     s->loadProblem(0, 0, &iEmpty, &iEmpty, &dEmpty, &dEmpty, &dEmpty, &dEmpty, &dEmpty, &dEmpty);
03080     double inf = s->getInfinity();
03081     CoinPackedVector c;
03082     
03083     s->addCol(c, 0, 10, 3);
03084     s->addCol(c, 0, 10, 1);
03085     
03086     CoinPackedVector r1;
03087     r1.insert(0, 2);
03088     r1.insert(1, 1);
03089     s->addRow(r1, -inf, 10);
03090     
03091     CoinPackedVector r2;
03092     r2.insert(0, 1);
03093     r2.insert(1, 3);
03094     s->addRow(r2, -inf, 15);
03095     
03096     s->setObjSense(-1);
03097 
03098     s->initialSolve() ;
03099     const double * colSol = s->getColSolution();
03100     // Don't test for exact answer, because Vol algorithm
03101     // only returns an appoximate solution
03102     assert( colSol[0]>4.5 );
03103     assert( colSol[1]<0.5 );
03104     
03105     s->setObjCoeff(0, 1);
03106     s->setObjCoeff(1, 1);
03107     
03108     s->resolve();    
03109     colSol = s->getColSolution();
03110     // Don't test for exact answer, because Vol algorithm
03111     // only returns an appoximate solution
03112     assert( colSol[0]>2.3 && colSol[0]<3.7 );
03113     assert( colSol[1]>3.5 && colSol[1]<4.5 );
03114     delete s;
03115   }
03116 
03117   // Test presolve
03118   if ( !volSolverInterface) {
03119     OsiSolverInterface * si = emptySi->clone();
03120     std::string fn = netlibDir+"25fv47";
03121     si->readMps(fn.c_str(),"mps");
03122     OsiSolverInterface * presolvedModel;
03123     OsiPresolve pinfo;
03124     int numberPasses=5; // can change this
03125     /* Use a tolerance of 1.0e-8 for feasibility, treat problem as 
03126        not being integer, do "numberpasses" passes */
03127     presolvedModel = pinfo.presolvedModel(*si,1.0e-8,false,numberPasses);
03128     assert(presolvedModel);
03129     // switch off presolve
03130     presolvedModel->setHintParam(OsiDoPresolveInInitial,false);
03131     presolvedModel->initialSolve();
03132     double objValue = presolvedModel->getObjValue(); 
03133     if( !eq(objValue,5.5018458883e+03) )
03134       failureMessage(solverName,"OsiPresolved model has wrong objective");
03135     pinfo.postsolve(true);
03136 
03137 
03138     delete presolvedModel;
03139     si->setHintParam(OsiDoPresolveInResolve,false);
03140     si->setHintParam(OsiDoDualInResolve,false);
03141     si->resolve();
03142     objValue = si->getObjValue(); 
03143     if( !eq(objValue,5.5018458883e+03) )
03144       failureMessage(solverName,"OsiPresolve - final objective wrong");
03145     if (si->getIterationCount())
03146       failureMessage(solverName,"OsiPresolve - minor error, needs iterations");
03147     delete si;
03148   }
03149 
03150   // Perform tests that are embodied in functions
03151   if ( !volSolverInterface )
03152   {
03153     
03154     typedef bool (*TestFunction)(OsiSolverInterface*);
03155     std::vector<std::pair<TestFunction, const char*> > test_functions;
03156     test_functions.push_back(std::pair<TestFunction, const char*>(&test1VivianDeSmedt, "test1VivianDeSmedt"));
03157     test_functions.push_back(std::pair<TestFunction, const char*>(&test2VivianDeSmedt, "test2VivianDeSmedt"));
03158     test_functions.push_back(std::pair<TestFunction, const char*>(&test3VivianDeSmedt, "test3VivianDeSmedt"));
03159     test_functions.push_back(std::pair<TestFunction, const char*>(&test4VivianDeSmedt, "test4VivianDeSmedt"));
03160     test_functions.push_back(std::pair<TestFunction, const char*>(&test5VivianDeSmedt, "test5VivianDeSmedt"));
03161     test_functions.push_back(std::pair<TestFunction, const char*>(&test6VivianDeSmedt, "test6VivianDeSmedt"));
03162     test_functions.push_back(std::pair<TestFunction, const char*>(&test7VivianDeSmedt, "test7VivianDeSmedt"));
03163     test_functions.push_back(std::pair<TestFunction, const char*>(&test8VivianDeSmedt, "test8VivianDeSmedt"));
03164     test_functions.push_back(std::pair<TestFunction, const char*>(&test9VivianDeSmedt, "test9VivianDeSmedt"));
03165     test_functions.push_back(std::pair<TestFunction, const char*>(&test10VivianDeSmedt,"test10VivianDeSmedt"));
03166     test_functions.push_back(std::pair<TestFunction, const char*>(&test11VivianDeSmedt,"test11VivianDeSmedt"));
03167     test_functions.push_back(std::pair<TestFunction, const char*>(&test12VivianDeSmedt,"test12VivianDeSmedt"));
03168     test_functions.push_back(std::pair<TestFunction, const char*>(&test13VivianDeSmedt,"test13VivianDeSmedt"));
03169     test_functions.push_back(std::pair<TestFunction, const char*>(&test14VivianDeSmedt,"test14VivianDeSmedt"));
03170     test_functions.push_back(std::pair<TestFunction, const char*>(&test15VivianDeSmedt,"test15VivianDeSmedt"));
03171     
03172     unsigned int i;
03173     for (i = 0; i < test_functions.size(); ++i) {
03174       OsiSolverInterface *s = emptySi->clone();
03175       const char * testName = test_functions[i].second;
03176       {
03177         bool test = test_functions[i].first(s);
03178         if (!test)
03179           failureMessage(*s, testName);
03180       }
03181       delete s;
03182     }
03183   }
03184   /*
03185     Orphan comment? If anyone happens to poke at the code that this belongs
03186     to, move it. 
03187 
03188     With this matrix we have a primal/dual infeas problem. Leaving the first
03189     row makes it primal feas, leaving the first col makes it dual feas.
03190     All vars are >= 0
03191 
03192     obj: -1  2 -3  4 -5 (min)
03193 
03194           0 -1  0  0 -2  >=  1
03195           1  0 -3  0  4  >= -2
03196           0  3  0 -5  0  >=  3
03197           0  0  5  0 -6  >= -4
03198           2 -4  0  6  0  >=  5
03199   */
03200 }
03201 

Generated on Wed Dec 3 14:35:34 2003 for Osi by doxygen 1.3.5