/home/coin/SVN-release/OS-2.4.0/Couenne/src/disjunctive/OsiLinear2MatrVec.cpp

Go to the documentation of this file.
00001 /* $Id: OsiLinear2MatrVec.cpp 694 2011-06-18 20:13:17Z stefan $
00002  *
00003  * Name:    OsiLinear2MatrVec.cpp
00004  * Author:  Pietro Belotti
00005  * Purpose: turn OsiSolverInterface objects into coefficient matrix and rhs vector
00006  *
00007  * (C) Carnegie-Mellon University, 2008. 
00008  * This file is licensed under the Eclipse Public License (EPL)
00009  */
00010 
00011 #include "CouenneDisjCuts.hpp"
00012 
00013 #include "OsiSolverInterface.hpp"
00014 
00015 #include "CoinPackedVector.hpp"
00016 #include "CoinPackedMatrix.hpp"
00017 #include "CoinHelperFunctions.hpp"
00018 
00019 #include "CouennePrecisions.hpp"
00020 #include "CouenneCutGenerator.hpp"
00021 #include "CouenneProblem.hpp"
00022 #include "CouenneExprVar.hpp"
00023 
00024 using namespace Ipopt;
00025 using namespace Couenne;
00026 
00027 // construct reduced, standard form matrix M from coefficient matrix of si
00028 void CouenneDisjCuts::OsiSI2MatrVec (CoinPackedMatrix &M, 
00029                                      CoinPackedVector &r,
00030                                      OsiSolverInterface &si) const {
00031 
00032   // the coefficient matrix
00033   const CoinPackedMatrix *A = si.getMatrixByRow ();
00034 
00035   int 
00036     nrows = A -> getMajorDim    (),
00037     ncols = A -> getMinorDim    (),
00038     nel   = A -> getNumElements ();
00039 
00040   const char *sen = si.getRowSense ();
00041 
00042   const double
00043     *rac = si.getRowActivity (),
00044     *x   = si.getColSolution (),
00045     *rlb = si.getRowLower (),
00046     *rub = si.getRowUpper (),
00047     *clb = si.getColLower (),
00048     *cub = si.getColUpper (),
00049     *el  = A -> getElements  ();
00050 
00051   const int
00052     *len   = A -> getVectorLengths (),
00053     *start = A -> getVectorStarts  (),
00054     *ind   = A -> getIndices       ();
00055 
00057   int 
00058     ndupEl   = 0, // count nonzero elements
00059     ndupRows = 0; // count rows
00060 
00061   for (int i=0; i<nrows; i++, sen++, len++) 
00062     if ((*sen == 'E') || 
00063         (*sen == 'R')) {
00064       ndupEl += *len;
00065       ndupRows++;
00066     }
00067 
00068   sen -= nrows;
00069   len -= nrows;
00070 
00071   double *mEl = new double [nel + ndupEl + 2*ncols];
00072 
00073   r.reserve (nrows + ndupRows + 2*ncols + 1);
00074 
00075   int 
00076     mRows = 0,
00077     curA  = 0, 
00078     curM  = 0, 
00079     *mIn  = new int [nel + ndupEl + 2*ncols],
00080     *mSt  = new int [nrows + ndupRows + 2*ncols + 1],
00081     *mLe  = new int [nrows + ndupRows + 2*ncols];
00082 
00083 
00084   if (jnlst_ -> ProduceOutput (J_MATRIX, J_DISJCUTS)) {
00085     printf ("matrix A (%d %d) %d elements:\n", nrows, ncols, nel);
00086 
00087     printf ("start: ");   for (int i=0; i <= nrows; i++) printf ("%d ", start [i]);
00088     printf ("\nlen:   "); for (int i=0; i <  nrows; i++) printf ("%d ", len   [i]);
00089 
00090     printf ("\nElements:\n"); 
00091     for (int i=0, j=0; i<nrows; i++) {
00092       for (int k=0; k<start [i+1] - start [i]; k++, j++) 
00093         printf ("(%d %g) ", ind [j], el [j]);
00094       printf (" in [%g,%g]\n", rlb [i], rub [i]);
00095     }
00096   }
00097 
00098   // for each constraint
00099   //   if activerows on and no activity, continue
00100   //   if 'E' or 'L' or 'R', copy    entries in matrix and    upper bound in R
00101   //   if 'E' or 'G' or 'R', copy -1*entries in matrix and -1*lower bound in R
00102   //
00103   // for each variable
00104   //   if activecols on and within bounds, continue
00105   //   if upper bounded, copy  1 in matrix and    upper bound in R
00106   //   if lower bounded, copy -1 in matrix and -1*lower bound in R
00107 
00108   // Constraints //////////////////////////////////
00109   for (int i=0; i<nrows; i++, rac++, rlb++, rub++, sen++, start++, curA += *len++) {
00110 
00111     if (activeRows_ &&
00112         (*rac < *rub - COUENNE_EPS) &&
00113         (*rac > *rlb + COUENNE_EPS))
00114       continue;
00115 
00116     if (*sen != 'G') {
00117       *mSt++ = curM;
00118       *mLe++ = *len;
00119       CoinCopyN (ind + curA, *len, mIn + curM);
00120       CoinCopyN (el  + curA, *len, mEl + curM);
00121       curM += *len;
00122       if (*rub != 0.) r.insert (mRows, *rub);
00123       mRows++;
00124     }
00125 
00126     if (*sen != 'L') {
00127       *mSt++ = curM;
00128       *mLe++ = *len;
00129       CoinCopyN (ind + curA, *len, mIn + curM);
00130       CoinInvN  (el  + curA, *len, mEl + curM); // invert contents
00131       curM += *len;
00132       if (*rlb != 0.) r.insert (mRows, -*rlb); // invert bound
00133       mRows++;
00134     }
00135   }
00136 
00137 
00138   // Variables ////////////////////////////////////
00139   for (int i=0; i<ncols; i++, x++, clb++, cub++) {
00140 
00141     if ((activeCols_ && 
00142          (*x < *cub - COUENNE_EPS) &&
00143          (*x > *clb + COUENNE_EPS)) ||
00144         (couenneCG_ -> Problem () -> Var (i) -> Multiplicity () <= 0))
00145       continue;
00146 
00147     if (*clb > -COUENNE_INFINITY) { // has lower bound -- invert!
00148       *mSt++ = curM;
00149       *mLe++ = 1;
00150       mIn [curM]   = i;
00151       mEl [curM++] = -1.;
00152       if (*clb != 0.) r.insert (mRows, -*clb);  // invert bound so x >= b becomes -x <= -b
00153       mRows++;
00154     }
00155 
00156     if (*cub <  COUENNE_INFINITY) { // has upper bound
00157       *mSt++ = curM;
00158       *mLe++ = 1;
00159       mIn [curM] = i;
00160       mEl [curM++] = 1.;
00161       if (*cub != 0.) r.insert (mRows, *cub);
00162       mRows++;
00163     }
00164   }
00165 
00166   *mSt = curM;
00167 
00168   mSt -= mRows;
00169   mLe -= mRows;
00170 
00171   if (jnlst_ -> ProduceOutput (J_MATRIX, J_DISJCUTS)) {
00172     printf ("matrix (%d %d) %d elements:\n", mRows, ncols, curM);
00173 
00174     printf ("start: ");   for (int i=0; i<=mRows; i++) printf ("%d ", mSt [i]);
00175     printf ("\nlen:   "); for (int i=0; i<mRows;  i++) printf ("%d ", mLe [i]);
00176 
00177     printf ("\nElements:\n"); 
00178     for (int i=0, j=0; i<mRows; i++) {
00179       for (int k=0; k<mSt[i+1] - mSt[i]; k++, j++) 
00180         printf ("(%d %g) ", mIn [j], mEl [j]);
00181       printf ("\n");
00182     }
00183 
00184     printf ("vector:\n"); 
00185     for (int i=0; i<r.getNumElements (); i++)
00186       printf ("(%d %g) ", r.getIndices () [i], r.getElements () [i]);
00187     printf ("\n");
00188   }
00189 
00190   M.assignMatrix (true,     // column ordered
00191                   ncols,    // minor dimension
00192                   mRows,    // major dimension
00193                   curM,     // number of elements
00194                   mEl,      // elements
00195                   mIn,      // indices
00196                   mSt,      // starting positions
00197                   mLe);     // length
00198 }

Generated on Thu Sep 22 03:05:57 2011 by  doxygen 1.4.7