OsiLinear2MatrVec.cpp
Go to the documentation of this file.
1 /* $Id: OsiLinear2MatrVec.cpp 694 2011-06-18 20:13:17Z stefan $
2  *
3  * Name: OsiLinear2MatrVec.cpp
4  * Author: Pietro Belotti
5  * Purpose: turn OsiSolverInterface objects into coefficient matrix and rhs vector
6  *
7  * (C) Carnegie-Mellon University, 2008.
8  * This file is licensed under the Eclipse Public License (EPL)
9  */
10 
11 #include "CouenneDisjCuts.hpp"
12 
13 #include "OsiSolverInterface.hpp"
14 
15 #include "CoinPackedVector.hpp"
16 #include "CoinPackedMatrix.hpp"
17 #include "CoinHelperFunctions.hpp"
18 
19 #include "CouennePrecisions.hpp"
20 #include "CouenneCutGenerator.hpp"
21 #include "CouenneProblem.hpp"
22 #include "CouenneExprVar.hpp"
23 
24 using namespace Ipopt;
25 using namespace Couenne;
26 
27 // construct reduced, standard form matrix M from coefficient matrix of si
28 void CouenneDisjCuts::OsiSI2MatrVec (CoinPackedMatrix &M,
29  CoinPackedVector &r,
30  OsiSolverInterface &si) const {
31 
32  // the coefficient matrix
33  const CoinPackedMatrix *A = si.getMatrixByRow ();
34 
35  int
36  nrows = A -> getMajorDim (),
37  ncols = A -> getMinorDim (),
38  nel = A -> getNumElements ();
39 
40  const char *sen = si.getRowSense ();
41 
42  const double
43  *rac = si.getRowActivity (),
44  *x = si.getColSolution (),
45  *rlb = si.getRowLower (),
46  *rub = si.getRowUpper (),
47  *clb = si.getColLower (),
48  *cub = si.getColUpper (),
49  *el = A -> getElements ();
50 
51  const int
52  *len = A -> getVectorLengths (),
53  *start = A -> getVectorStarts (),
54  *ind = A -> getIndices ();
55 
57  int
58  ndupEl = 0, // count nonzero elements
59  ndupRows = 0; // count rows
60 
61  for (int i=0; i<nrows; i++, sen++, len++)
62  if ((*sen == 'E') ||
63  (*sen == 'R')) {
64  ndupEl += *len;
65  ndupRows++;
66  }
67 
68  sen -= nrows;
69  len -= nrows;
70 
71  double *mEl = new double [nel + ndupEl + 2*ncols];
72 
73  r.reserve (nrows + ndupRows + 2*ncols + 1);
74 
75  int
76  mRows = 0,
77  curA = 0,
78  curM = 0,
79  *mIn = new int [nel + ndupEl + 2*ncols],
80  *mSt = new int [nrows + ndupRows + 2*ncols + 1],
81  *mLe = new int [nrows + ndupRows + 2*ncols];
82 
83 
84  if (jnlst_ -> ProduceOutput (J_MATRIX, J_DISJCUTS)) {
85  printf ("matrix A (%d %d) %d elements:\n", nrows, ncols, nel);
86 
87  printf ("start: "); for (int i=0; i <= nrows; i++) printf ("%d ", start [i]);
88  printf ("\nlen: "); for (int i=0; i < nrows; i++) printf ("%d ", len [i]);
89 
90  printf ("\nElements:\n");
91  for (int i=0, j=0; i<nrows; i++) {
92  for (int k=0; k<start [i+1] - start [i]; k++, j++)
93  printf ("(%d %g) ", ind [j], el [j]);
94  printf (" in [%g,%g]\n", rlb [i], rub [i]);
95  }
96  }
97 
98  // for each constraint
99  // if activerows on and no activity, continue
100  // if 'E' or 'L' or 'R', copy entries in matrix and upper bound in R
101  // if 'E' or 'G' or 'R', copy -1*entries in matrix and -1*lower bound in R
102  //
103  // for each variable
104  // if activecols on and within bounds, continue
105  // if upper bounded, copy 1 in matrix and upper bound in R
106  // if lower bounded, copy -1 in matrix and -1*lower bound in R
107 
108  // Constraints //////////////////////////////////
109  for (int i=0; i<nrows; i++, rac++, rlb++, rub++, sen++, start++, curA += *len++) {
110 
111  if (activeRows_ &&
112  (*rac < *rub - COUENNE_EPS) &&
113  (*rac > *rlb + COUENNE_EPS))
114  continue;
115 
116  if (*sen != 'G') {
117  *mSt++ = curM;
118  *mLe++ = *len;
119  CoinCopyN (ind + curA, *len, mIn + curM);
120  CoinCopyN (el + curA, *len, mEl + curM);
121  curM += *len;
122  if (*rub != 0.) r.insert (mRows, *rub);
123  mRows++;
124  }
125 
126  if (*sen != 'L') {
127  *mSt++ = curM;
128  *mLe++ = *len;
129  CoinCopyN (ind + curA, *len, mIn + curM);
130  CoinInvN (el + curA, *len, mEl + curM); // invert contents
131  curM += *len;
132  if (*rlb != 0.) r.insert (mRows, -*rlb); // invert bound
133  mRows++;
134  }
135  }
136 
137 
138  // Variables ////////////////////////////////////
139  for (int i=0; i<ncols; i++, x++, clb++, cub++) {
140 
141  if ((activeCols_ &&
142  (*x < *cub - COUENNE_EPS) &&
143  (*x > *clb + COUENNE_EPS)) ||
144  (couenneCG_ -> Problem () -> Var (i) -> Multiplicity () <= 0))
145  continue;
146 
147  if (*clb > -COUENNE_INFINITY) { // has lower bound -- invert!
148  *mSt++ = curM;
149  *mLe++ = 1;
150  mIn [curM] = i;
151  mEl [curM++] = -1.;
152  if (*clb != 0.) r.insert (mRows, -*clb); // invert bound so x >= b becomes -x <= -b
153  mRows++;
154  }
155 
156  if (*cub < COUENNE_INFINITY) { // has upper bound
157  *mSt++ = curM;
158  *mLe++ = 1;
159  mIn [curM] = i;
160  mEl [curM++] = 1.;
161  if (*cub != 0.) r.insert (mRows, *cub);
162  mRows++;
163  }
164  }
165 
166  *mSt = curM;
167 
168  mSt -= mRows;
169  mLe -= mRows;
170 
171  if (jnlst_ -> ProduceOutput (J_MATRIX, J_DISJCUTS)) {
172  printf ("matrix (%d %d) %d elements:\n", mRows, ncols, curM);
173 
174  printf ("start: "); for (int i=0; i<=mRows; i++) printf ("%d ", mSt [i]);
175  printf ("\nlen: "); for (int i=0; i<mRows; i++) printf ("%d ", mLe [i]);
176 
177  printf ("\nElements:\n");
178  for (int i=0, j=0; i<mRows; i++) {
179  for (int k=0; k<mSt[i+1] - mSt[i]; k++, j++)
180  printf ("(%d %g) ", mIn [j], mEl [j]);
181  printf ("\n");
182  }
183 
184  printf ("vector:\n");
185  for (int i=0; i<r.getNumElements (); i++)
186  printf ("(%d %g) ", r.getIndices () [i], r.getElements () [i]);
187  printf ("\n");
188  }
189 
190  M.assignMatrix (true, // column ordered
191  ncols, // minor dimension
192  mRows, // major dimension
193  curM, // number of elements
194  mEl, // elements
195  mIn, // indices
196  mSt, // starting positions
197  mLe); // length
198 }
void CoinInvN(register const double *orig, register int n, register double *inverted)
invert all contents
const Ipopt::EJournalCategory J_DISJCUTS(Ipopt::J_USER6)
static char * j
Definition: OSdtoa.cpp:3622
void fint fint * k
#define COUENNE_EPS
void fint fint fint real fint real real real real real real real * r
#define COUENNE_INFINITY
void fint fint fint real fint real * x