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

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

Generated on Thu Aug 5 03:02:56 2010 by  doxygen 1.4.7