SoPlex Doxygen Documentation
spxlp.cpp
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the class library */
4 /* SoPlex --- the Sequential object-oriented simPlex. */
5 /* */
6 /* Copyright (C) 1996-2012 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SoPlex is distributed under the terms of the ZIB Academic Licence. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SoPlex; see the file COPYING. If not email to soplex@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 #include <stdio.h>
17 
18 #include "spxdefines.h"
19 #include "spxlp.h"
20 
21 namespace soplex
22 {
23 int SPxLP::nNzos() const
24 {
25  METHOD( "SPxLP::nNzos()" );
26  int n = 0;
27  for( int i = 0; i < nCols(); ++i )
28  n += colVector(i).size();
29  return n;
30 }
31 
33 {
34  METHOD( "SPxLP::minAbsNzo()" );
35 
36  Real mini = infinity;
37 
38  for( int i = 0; i < nCols(); ++i )
39  {
40  Real m = colVector(i).minAbs();
41 
42  if (m < mini)
43  mini = m;
44  }
45  assert(mini >= 0.0);
46 
47  return mini;
48 }
49 
51 {
52  METHOD( "SPxLP::maxAbsNzo()" );
53 
54  Real maxi = 0.0;
55 
56  for( int i = 0; i < nCols(); ++i )
57  {
58  Real m = colVector(i).maxAbs();
59 
60  if (m > maxi)
61  maxi = m;
62  }
63  assert(maxi >= 0.0);
64 
65  return maxi;
66 }
67 
68 void SPxLP::getRow(int i, LPRow& row) const
69 {
70  METHOD( "SPxLP::getRow()" );
71  row.setLhs(lhs(i));
72  row.setRhs(rhs(i));
74 }
75 
76 void SPxLP::getRows(int start, int end, LPRowSet& p_set) const
77 {
78  METHOD( "SPxLP::getRows()" );
79  p_set.clear();
80  for(int i = start; i <= end; i++)
81  p_set.add(lhs(i), rowVector(i), rhs(i));
82 }
83 
84 void SPxLP::getCol(int i, LPCol& col) const
85 {
86  METHOD( "SPxLP::getCol()" );
87  col.setUpper(upper(i));
88  col.setLower(lower(i));
89  col.setObj( obj(i) );
90  col.setColVector(colVector(i));
91 }
92 
93 void SPxLP::getCols(int start, int end, LPColSet& p_set) const
94 {
95  METHOD( "SPxLP::getCols()" );
96  p_set.clear();
97  for(int i = start; i <= end; i++)
98  p_set.add(obj(i), lower(i), colVector(i), upper(i));
99 }
100 
101 void SPxLP::getObj(Vector& p_obj) const
102 {
103  METHOD( "SPxLP::getObj()" );
104  p_obj = LPColSet::maxObj();
105  if (spxSense() == MINIMIZE)
106  p_obj *= -1.0;
107 }
108 
109 void SPxLP::doAddRow(const LPRow& row)
110 {
111  METHOD( "SPxLP::doAddRow()" );
112  int idx = nRows();
113  int oldColNumber = nCols();
114  const SVector& vec = row.rowVector();
115 
116  LPRowSet::add(row);
117 
118  // now insert nonzeros to column file also
119  for (int j = vec.size() - 1; j >= 0; --j)
120  {
121  Real val = vec.value(j);
122  int i = vec.index(j);
123  if (i >= nCols()) // create new columns if required
124  {
125  LPCol empty;
126  for (int k = nCols(); k <= i; ++k)
127  LPColSet::add(empty);
128  // doAddCol(empty);
129  }
130 
131  assert(i < nCols());
132  LPColSet::add2(i, 1, &idx, &val);
133  }
134 
135  addedRows(1);
136  addedCols( nCols() - oldColNumber );
137 }
138 
139 void SPxLP::doAddCol(const LPCol& col)
140 {
141  METHOD( "SPxLP::doAddCol()" );
142  int idx = nCols();
143  int oldRowNumber = nRows();
144  const SVector& vec = col.colVector();
145 
146  LPColSet::add(col);
148 
149  // now insert nonzeros to row file also
150  for (int j = vec.size() - 1; j >= 0; --j)
151  {
152  Real val = vec.value(j);
153  int i = vec.index(j);
154  if (i >= nRows()) // create new rows if required
155  {
156  LPRow empty;
157  for (int k = nRows(); k <= i; ++k)
158  LPRowSet::add(empty);
159  // doAddRow(empty);
160  }
161 
162  assert(i < nRows());
163  LPRowSet::add2(i, 1, &idx, &val);
164  }
165 
166  addedCols(1);
167  addedRows( nRows() - oldRowNumber );
168 }
169 
170 void SPxLP::added2Set(SVSet& p_set, const SVSet& p_add, int n)
171 {
172  METHOD( "SPxLP::added2Set()" );
173 
174  if( n == 0 )
175  return;
176 
177  int i;
178  int j;
179  int end;
180  int tot;
181  DataArray<int> moreArray(p_set.num());
182  int* more = moreArray.get_ptr();
183 
184  for (i = p_set.num() - 1; i >= 0; --i)
185  more[i] = 0;
186 
187  for (tot = 0, i = p_add.num() - n, end = p_add.num(); i < end; ++i)
188  {
189  const SVector& vec = p_add[i];
190  tot += vec.size();
191  for (j = vec.size() - 1; j >= 0; --j)
192  more[ vec.index(j) ]++;
193  }
194 
195  if (p_set.memMax() < tot)
196  p_set.memRemax(tot);
197 
198  for (i = p_set.num() - 1; i >= 0; --i)
199  {
200  j = p_set[i].size();
201  p_set.xtend(p_set[i], j + more[i]);
202  p_set[i].set_size( j + more[i] );
203  more[i] = j;
204  }
205 
206  for (i = p_add.num() - n; i < p_add.num(); ++i)
207  {
208  const SVector& vec = p_add[i];
209  for (j = vec.size() - 1; j >= 0; --j)
210  {
211  int k = vec.index(j);
212  int m = more[k]++;
213  SVector& l_xtend = p_set[k];
214  l_xtend.index(m) = i;
215  l_xtend.value(m) = vec.value(j);
216  }
217  }
218 }
219 
220 void SPxLP::doAddRows(const LPRowSet& p_set)
221 {
222  METHOD( "SPxLP::doAddRows()" );
223  int i, j, k, ii, idx;
224  SVector* col;
225  DataArray < int > newCols(nCols());
226  int oldRowNumber = nRows();
227  int oldColNumber = nCols();
228 
229  if (&p_set != this)
230  LPRowSet::add(p_set);
231  assert(LPRowSet::isConsistent());
232  assert(LPColSet::isConsistent());
233 
234  // count additional nonzeros per column
235  for (i = nCols() - 1; i >= 0; --i)
236  newCols[i] = 0;
237  for (i = p_set.num() - 1; i >= 0; --i)
238  {
239  const SVector& vec = p_set.rowVector(i);
240  for (j = vec.size() - 1; j >= 0; --j)
241  {
242  ii = vec.index(j);
243  if (ii >= nCols()) // create new columns if required
244  {
245  LPCol empty;
246  newCols.reSize(ii + 1);
247  for (k = nCols(); k <= ii; ++k)
248  {
249  newCols[k] = 0;
250  // doAddCol(empty);
251  LPColSet::add(empty);
252  }
253  }
254  assert(ii < nCols());
255  newCols[ii]++;
256  }
257  }
258 
259  // extend columns as required (backward because of memory efficiency reasons)
260  for (i = nCols() - 1; i >= 0; --i)
261  {
262  if (newCols[i] > 0)
263  {
264  int len = newCols[i] + colVector(i).size();
265  LPColSet::xtend(i, len);
266  /* preset the sizes: beware that this can irritate a consistency check call from
267  xtend(). We need to set the sizes here, because a possible garbage collection called
268  from xtend might destroy the sizes again. */
269  colVector_w(i).set_size( len );
270  }
271  }
272 
273  // insert new elements to column file
274  for (i = nRows() - 1; i >= oldRowNumber; --i)
275  {
276  const SVector& vec = rowVector(i);
277  for (j = vec.size() - 1; j >= 0; --j)
278  {
279  k = vec.index(j);
280  col = &colVector_w(k);
281  idx = col->size() - newCols[k];
282  assert(newCols[k] > 0);
283  assert(idx >= 0);
284  newCols[k]--;
285  col->index(idx) = i;
286  col->value(idx) = vec.value(j);
287  }
288  }
289 #ifndef NDEBUG
290  for( i = 0; i < nCols(); ++i )
291  assert( newCols[i] == 0 );
292 #endif
293  assert(SPxLP::isConsistent());
294 
295  assert( p_set.num() == nRows() - oldRowNumber );
296  addedRows( nRows() - oldRowNumber );
297  addedCols( nCols() - oldColNumber );
298 }
299 
300 void SPxLP::doAddCols(const LPColSet& p_set)
301 {
302  METHOD( "SPxLP::doAddCols()" );
303  int i, j;
304  int oldColNumber = nCols();
305  int oldRowNumber = nRows();
306  DataArray < int > newRows(nRows());
307 
308  if (&p_set != this)
309  LPColSet::add(p_set);
310  assert(LPColSet::isConsistent());
311  assert(LPRowSet::isConsistent());
312 
313  // count additional nonzeros per row
314  for (i = nRows() - 1; i >= 0; --i)
315  newRows[i] = 0;
316  for (i = p_set.num() - 1; i >= 0; --i)
317  {
318  const SVector& vec = p_set.colVector(i);
319  for (j = vec.size() - 1; j >= 0; --j)
320  {
321  int l = vec.index(j);
322  if (l >= nRows()) // create new rows if required
323  {
324  LPRow empty;
325  newRows.reSize(l + 1);
326  for (int k = nRows(); k <= l; ++k)
327  {
328  newRows[k] = 0;
329  // doAddRow(empty);
330  LPRowSet::add(empty);
331  }
332 
333  }
334  assert(l < nRows());
335  newRows[l]++;
336  }
337  }
338 
339  // extend rows as required
340  for( i = 0; i < nRows(); ++i )
341  {
342  if (newRows[i] > 0)
343  {
344  int len = newRows[i] + rowVector(i).size();
345  LPRowSet::xtend(i, len);
346  rowVector_w(i).set_size( len );
347  }
348  }
349 
350  // insert new elements to row file
351  for (i = oldColNumber; i < nCols(); ++i)
352  {
354  const SVector& vec = colVector(i);
355  for (j = vec.size() - 1; j >= 0; --j)
356  {
357  int k = vec.index(j);
358  SVector& row = rowVector_w(k);
359  int idx = row.size() - newRows[k];
360  assert(newRows[k] > 0);
361  newRows[k]--;
362  row.index(idx) = i;
363  row.value(idx) = vec.value(j);
364  }
365  }
366 #ifndef NDEBUG
367  for( i = 0; i < nRows(); ++i )
368  assert( newRows[i] == 0 );
369 #endif
370  assert(SPxLP::isConsistent());
371 
372  assert( p_set.num() == nCols() - oldColNumber );
373  addedCols( nCols() - oldColNumber );
374  addedRows( nRows() - oldRowNumber );
375 }
376 
377 void SPxLP::addRows(SPxRowId id[], const LPRowSet& p_set)
378 {
379  METHOD( "SPxLP::addRows()" );
380  int i = nRows();
381  addRows(p_set);
382  for (int j = 0; i < nRows(); ++i, ++j)
383  id[j] = rId(i);
384 }
385 
386 void SPxLP::addCols(SPxColId id[], const LPColSet& p_set)
387 {
388  METHOD( "SPxLP::addCols()" );
389  int i = nCols();
390  addCols(p_set);
391  for (int j = 0; i < nCols(); ++i, ++j)
392  id[j] = cId(i);
393 }
394 
396 {
397  METHOD( "SPxLP::doRemoveRow()" );
398  const SVector& vec = rowVector(j);
399  int i;
400 
401  // remove row vector from column file
402  for (i = vec.size() - 1; i >= 0; --i)
403  {
404  SVector& remvec = colVector_w(vec.index(i));
405  remvec.remove(remvec.number(j));
406  }
407 
408  int idx = nRows() - 1;
409  if (j != idx) // move last row to removed position
410  {
411  const SVector& l_vec = rowVector(idx);
412  for (i = l_vec.size() - 1; i >= 0; --i)
413  {
414  SVector& movevec = colVector_w(l_vec.index(i));
415  movevec.index(movevec.number(idx)) = j;
416  }
417  }
418 
419  LPRowSet::remove(j);
420 }
421 
423 {
424  METHOD( "SPxLP::doRemoveCol()" );
425  const SVector& vec = colVector(j);
426  int i;
427 
428  // remove column vector from row file
429  for (i = vec.size() - 1; i >= 0; --i)
430  {
431  SVector& remvec = rowVector_w(vec.index(i));
432  remvec.remove(remvec.number(j));
433  }
434 
435  int idx = nCols() - 1;
436  if (j != idx) // move last column to removed position
437  {
438  const SVector& l_vec = colVector(idx);
439  for (i = l_vec.size() - 1; i >= 0; --i)
440  {
441  SVector& movevec = rowVector_w(l_vec.index(i));
442  movevec.index(movevec.number(idx)) = j;
443  }
444  }
445 
446  LPColSet::remove(j);
447 }
448 
449 void SPxLP::doRemoveRows(int perm[])
450 {
451  METHOD( "SPxLP::doRemoveRows()" );
452  int j = nCols();
453 
454  LPRowSet::remove(perm);
455  for (int i = 0; i < j; ++i)
456  {
457  SVector& vec = colVector_w(i);
458  for (int k = vec.size() - 1; k >= 0; --k)
459  {
460  int idx = vec.index(k);
461  if (perm[idx] < 0)
462  vec.remove(k);
463  else
464  vec.index(k) = perm[idx];
465  }
466  }
467 }
468 
469 void SPxLP::doRemoveCols(int perm[])
470 {
471  METHOD( "SPxLP::doRemoveCols()" );
472  int j = nRows();
473 
474  LPColSet::remove(perm);
475  for (int i = 0; i < j; ++i)
476  {
477  SVector& vec = rowVector_w(i);
478  for (int k = vec.size() - 1; k >= 0; --k)
479  {
480  int idx = vec.index(k);
481  if (perm[idx] < 0)
482  vec.remove(k);
483  else
484  vec.index(k) = perm[idx];
485  }
486  }
487 }
488 
489 void SPxLP::removeRows(SPxRowId id[], int n, int perm[])
490 {
491  METHOD( "SPxLP::removeRows()" );
492  if (perm == 0)
493  {
495  removeRows(id, n, p.get_ptr());
496  return;
497  }
498  for (int i = nRows() - 1; i >= 0; --i)
499  perm[i] = i;
500  while (n--)
501  perm[number(id[n])] = -1;
502  removeRows(perm);
503 }
504 
505 void SPxLP::removeRows(int nums[], int n, int perm[])
506 {
507  METHOD( "SPxLP::removeRows()" );
508  if (perm == 0)
509  {
511  removeRows(nums, n, p.get_ptr());
512  return;
513  }
514  for (int i = nRows() - 1; i >= 0; --i)
515  perm[i] = i;
516  while (n--)
517  perm[nums[n]] = -1;
518  removeRows(perm);
519 }
520 
521 void SPxLP::removeRowRange(int start, int end, int perm[])
522 {
523  METHOD( "SPxLP::removeRowRange()" );
524  if (perm == 0)
525  {
526  int i = end - start + 1;
527  DataArray < int > p(i);
528  while (--i >= 0)
529  p[i] = start + i;
530  removeRows(p.get_ptr(), end - start + 1);
531  return;
532  }
533  int i;
534  for (i = 0; i < start; ++i)
535  perm[i] = i;
536  for (; i <= end; ++i)
537  perm[i] = -1;
538  for (; i < nRows(); ++i)
539  perm[i] = i;
540  removeRows(perm);
541 }
542 
543 void SPxLP::removeCols(SPxColId id[], int n, int perm[])
544 {
545  METHOD( "SPxLP::removeCols()" );
546  if (perm == 0)
547  {
549  removeCols(id, n, p.get_ptr());
550  return;
551  }
552  for (int i = nCols() - 1; i >= 0; --i)
553  perm[i] = i;
554  while (n--)
555  perm[number(id[n])] = -1;
556  removeCols(perm);
557 }
558 
559 void SPxLP::removeCols(int nums[], int n, int perm[])
560 {
561  METHOD( "SPxLP::removeCols()" );
562  if (perm == 0)
563  {
565  removeCols(nums, n, p.get_ptr());
566  return;
567  }
568  for (int i = nCols() - 1; i >= 0; --i)
569  perm[i] = i;
570  while (n--)
571  perm[nums[n]] = -1;
572  removeCols(perm);
573 }
574 
575 void SPxLP::removeColRange(int start, int end, int perm[])
576 {
577  METHOD( "SPxLP::removeColRange()" );
578  if (perm == 0)
579  {
580  int i = end - start + 1;
581  DataArray < int > p(i);
582  while (--i >= 0)
583  p[i] = start + i;
584  removeCols(p.get_ptr(), end - start + 1);
585  return;
586  }
587  int i;
588  for (i = 0; i < start; ++i)
589  perm[i] = i;
590  for (; i <= end; ++i)
591  perm[i] = -1;
592  for (; i < nCols(); ++i)
593  perm[i] = i;
594  removeCols(perm);
595 }
596 
598 {
599  METHOD( "SPxLP::clear()" );
600  LPRowSet::clear();
601  LPColSet::clear();
602  thesense = MAXIMIZE;
603 }
604 
605 void SPxLP::changeObj(const Vector& newObj)
606 {
607  METHOD( "SPxLP::changeObj()" );
608  assert(maxObj().dim() == newObj.dim());
609  LPColSet::maxObj_w() = newObj;
611  assert(isConsistent());
612 }
613 
614 void SPxLP::changeObj(int i, Real newVal)
615 {
616  METHOD( "SPxLP::changeObj()" );
617  LPColSet::maxObj_w(i) = Real(spxSense()) * newVal;
618  assert(isConsistent());
619 }
620 
621 void SPxLP::changeLower(const Vector& newLower)
622 {
623  METHOD( "SPxLP::changeLower()" );
624  assert(lower().dim() == newLower.dim());
625  LPColSet::lower_w() = newLower;
626  assert(isConsistent());
627 }
628 
629 void SPxLP::changeLower(int i, Real newLower)
630 {
631  METHOD( "SPxLP::changeLower()" );
632  LPColSet::lower_w(i) = newLower;
633  assert(isConsistent());
634 }
635 
636 void SPxLP::changeUpper(const Vector& newUpper)
637 {
638  METHOD( "SPxLP::changeUpper()" );
639  assert(upper().dim() == newUpper.dim());
640  LPColSet::upper_w() = newUpper;
641  assert(isConsistent());
642 }
643 
644 void SPxLP::changeUpper(int i, Real newUpper)
645 {
646  METHOD( "SPxLP::changeUpper()" );
647  LPColSet::upper_w(i) = newUpper;
648  assert(isConsistent());
649 }
650 
651 void SPxLP::changeLhs(const Vector& newLhs)
652 {
653  METHOD( "SPxLP::changeLhs()" );
654  assert(lhs().dim() == newLhs.dim());
655  LPRowSet::lhs_w() = newLhs;
656  assert(isConsistent());
657 }
658 
659 void SPxLP::changeBounds(const Vector& newLower, const Vector& newUpper)
660 {
661  METHOD( "SPxLP::changeBounds()" );
662  changeLower(newLower);
663  changeUpper(newUpper);
664  assert(isConsistent());
665 }
666 
667 void SPxLP::changeBounds(int i, Real newLower, Real newUpper)
668 {
669  METHOD( "SPxLP::changeBounds()" );
670  changeLower(i, newLower);
671  changeUpper(i, newUpper);
672  assert(isConsistent());
673 }
674 
675 void SPxLP::changeLhs(int i, Real newLhs)
676 {
677  METHOD( "SPxLP::changeLhs()" );
678  LPRowSet::lhs_w(i) = newLhs;
679  assert(isConsistent());
680 }
681 
682 void SPxLP::changeRhs(const Vector& newRhs)
683 {
684  METHOD( "SPxLP::changeRhs()" );
685  assert(rhs().dim() == newRhs.dim());
686  LPRowSet::rhs_w() = newRhs;
687  assert(isConsistent());
688 }
689 
690 void SPxLP::changeRhs(int i, Real newRhs)
691 {
692  METHOD( "SPxLP::changeRhs()" );
693  LPRowSet::rhs_w(i) = newRhs;
694  assert(isConsistent());
695 }
696 
697 void SPxLP::changeRange(const Vector& newLhs, const Vector& newRhs)
698 {
699  METHOD( "SPxLP::changeRange()" );
700  changeLhs(newLhs);
701  changeRhs(newRhs);
702  assert(isConsistent());
703 }
704 
705 void SPxLP::changeRange(int i, Real newLhs, Real newRhs)
706 {
707  METHOD( "SPxLP::changeRange()" );
708  changeLhs(i, newLhs);
709  changeRhs(i, newRhs);
710  assert(isConsistent());
711 }
712 
713 
714 void SPxLP::changeRow(int n, const LPRow& newRow)
715 {
716  METHOD( "SPxLP::changeRow()" );
717  int j;
718  SVector& row = rowVector_w(n);
719  for (j = row.size() - 1; j >= 0; --j)
720  {
721  SVector& col = colVector_w(row.index(j));
722  col.remove(col.number(n));
723  }
724  row.clear();
725 
726  changeLhs(n, newRow.lhs());
727  changeRhs(n, newRow.rhs());
728  const SVector& newrow = newRow.rowVector();
729  for (j = newrow.size() - 1; j >= 0; --j)
730  {
731  int idx = newrow.index(j);
732  Real val = newrow.value(j);
733  LPRowSet::add2(n, 1, &idx, &val);
734  LPColSet::add2(idx, 1, &n, &val);
735  }
736  assert(isConsistent());
737 }
738 
739 void SPxLP::changeCol(int n, const LPCol& newCol)
740 {
741  METHOD( "SPxLP::changeCol()" );
742  int j;
743  SVector& col = colVector_w(n);
744  for (j = col.size() - 1; j >= 0; --j)
745  {
746  SVector& row = rowVector_w(col.index(j));
747  row.remove(row.number(n));
748  }
749  col.clear();
750 
751  changeUpper(n, newCol.upper());
752  changeLower(n, newCol.lower());
753  changeObj (n, newCol.obj());
754  const SVector& newcol = newCol.colVector();
755  for (j = newcol.size() - 1; j >= 0; --j)
756  {
757  int idx = newcol.index(j);
758  Real val = newcol.value(j);
759  LPColSet::add2(n, 1, &idx, &val);
760  LPRowSet::add2(idx, 1, &n, &val);
761  }
762  assert(isConsistent());
763 }
764 
765 void SPxLP::changeElement(int i, int j, Real val)
766 {
767  METHOD( "SPxLP::changeElement()" );
768  SVector& row = rowVector_w(i);
769  SVector& col = colVector_w(j);
770 
771  if (val != 0.0)
772  {
773  if (row.number(j) >= 0)
774  {
775  row.value(row.number(j)) = val;
776  col.value(col.number(i)) = val;
777  }
778  else
779  {
780  LPRowSet::add2(i, 1, &j, &val);
781  LPColSet::add2(j, 1, &i, &val);
782  }
783  }
784  else if (row.number(j) >= 0)
785  {
786  row.remove(row.number(j));
787  col.remove(col.number(i));
788  }
789  assert(isConsistent());
790 }
791 
793  const Vector_exact& primal
794  ) const
795 {
796  METHOD( "SPxLP::computePrimalActivity()" );
797 
798  if( primal.dim() != nCols() )
799  {
800  throw SPxInternalCodeException("XSPXLP01 Primal vector for computing row activity has wrong dimension");
801  }
802 
803  DVector_exact activity(nRows());
804 
805  activity.clear();
806  for( int c = 0; c < nCols(); c++ )
807  {
808  activity.multAdd(primal[c], colVector(c));
809  }
810 
811  return activity;
812 }
813 
815  const Vector_exact& dual
816  ) const
817 {
818  METHOD( "SPxLP::computeDualActivity()" );
819 
820  if( dual.dim() != nRows() )
821  {
822  throw SPxInternalCodeException("XSPXLP02 Dual vector for computing activity has wrong dimension");
823  }
824 
825  DVector_exact activity(nCols());
826 
827  activity.clear();
828  for( int r = 0; r < nRows(); r++ )
829  {
830  activity.multAdd(dual[r], rowVector(r));
831  }
832 
833  return activity;
834 }
835 
837 {
838 #ifdef ENABLE_CONSISTENCY_CHECKS
839  METHOD( "SPxLP::isConsistent()" );
840  int i, j, n;
841 
842  for (i = nCols() - 1; i >= 0; --i)
843  {
844  const SVector& v = colVector(i);
845  for (j = v.size() - 1; j >= 0; --j)
846  {
847  const SVector& w = rowVector(v.index(j));
848  n = w.number(i);
849  if (n < 0)
850  return MSGinconsistent("SPxLP");
851  if (v.value(j) != w.value(n))
852  return MSGinconsistent("SPxLP");
853  }
854  }
855 
856  for (i = nRows() - 1; i >= 0; --i)
857  {
858  const SVector& v = rowVector(i);
859  for (j = v.size() - 1; j >= 0; --j)
860  {
861  const SVector& w = colVector(v.index(j));
862  n = w.number(i);
863  if (n < 0)
864  return MSGinconsistent("SPxLP");
865  if (v.value(j) != w.value(n))
866  return MSGinconsistent("SPxLP");
867  }
868  }
870 #else
871  return true;
872 #endif
873 }
874 } // namespace soplex
875 
876 //-----------------------------------------------------------------------------
877 //Emacs Local Variables:
878 //Emacs mode:c++
879 //Emacs c-basic-offset:3
880 //Emacs tab-width:8
881 //Emacs indent-tabs-mode:nil
882 //Emacs End:
883 //-----------------------------------------------------------------------------