source: branches/unlabeled-1.1.2/ClpPlusMinusOneMatrix.cpp @ 118

Last change on this file since 118 was 118, checked in by forrest, 17 years ago

Adding Network matrix and PlusMinusOne?

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.6 KB
Line 
1// Copyright (C) 2003, International Business Machines
2// Corporation and others.  All Rights Reserved.
3
4
5#include <cstdio>
6
7#include "CoinPragma.hpp"
8#include "CoinIndexedVector.hpp"
9#include "CoinHelperFunctions.hpp"
10
11#include "ClpSimplex.hpp"
12#include "ClpFactorization.hpp"
13// at end to get min/max!
14#include "ClpPlusMinusOneMatrix.hpp"
15#include "ClpMessage.hpp"
16
17//#############################################################################
18// Constructors / Destructor / Assignment
19//#############################################################################
20
21//-------------------------------------------------------------------
22// Default Constructor
23//-------------------------------------------------------------------
24ClpPlusMinusOneMatrix::ClpPlusMinusOneMatrix () 
25  : ClpMatrixBase()
26{
27  setType(12);
28  elements_ = NULL;
29  startPositive_ = NULL;
30  startNegative_ = NULL;
31  lengths_=NULL;
32  indices_=NULL;
33  numberRows_=0;
34  numberColumns_=0;
35  columnOrdered_=true;
36}
37
38//-------------------------------------------------------------------
39// Copy constructor
40//-------------------------------------------------------------------
41ClpPlusMinusOneMatrix::ClpPlusMinusOneMatrix (const ClpPlusMinusOneMatrix & rhs) 
42: ClpMatrixBase(rhs)
43{ 
44  elements_ = NULL;
45  startPositive_ = NULL;
46  startNegative_ = NULL;
47  lengths_=NULL;
48  indices_=NULL;
49  numberRows_=rhs.numberRows_;
50  numberColumns_=rhs.numberColumns_;
51  columnOrdered_=rhs.columnOrdered_;
52  if (numberColumns_) {
53    indices_ = new int [ 2*numberColumns_];
54    memcpy(indices_,rhs.indices_,2*numberColumns_*sizeof(int));
55    startPositive_ = new int [ numberColumns_+1];
56    memcpy(startPositive_,rhs.startPositive_,(numberColumns_+1)*sizeof(int));
57    startNegative_ = new int [ numberColumns_];
58    memcpy(startNegative_,rhs.startNegative_,numberColumns_*sizeof(int));
59  }
60}
61
62ClpPlusMinusOneMatrix::ClpPlusMinusOneMatrix (const CoinPackedMatrix & rhs) 
63  : ClpMatrixBase()
64{ 
65  setType(12);
66  elements_ = NULL;
67  startPositive_ = NULL;
68  startNegative_ = NULL;
69  lengths_=NULL;
70  indices_=NULL;
71  int iColumn;
72  assert (rhs.isColOrdered());
73  // get matrix data pointers
74  const int * row = rhs.getIndices();
75  const CoinBigIndex * columnStart = rhs.getVectorStarts();
76  const int * columnLength = rhs.getVectorLengths(); 
77  const double * elementByColumn = rhs.getElements();
78  numberColumns_ = rhs.getNumCols();
79  bool goodPlusMinusOne=true;
80  numberRows_=-1;
81  indices_ = new int[rhs.getNumElements()];
82  startPositive_ = new int [numberColumns_+1];
83  startNegative_ = new int [numberColumns_];
84  int * temp = new int [rhs.getNumRows()];
85  CoinBigIndex j=0;
86  for (iColumn=0;iColumn<numberColumns_;iColumn++) {
87    CoinBigIndex k;
88    int iNeg=0;
89    startPositive_[iColumn]=j;
90    for (k=columnStart[iColumn];k<columnStart[iColumn]+columnLength[iColumn];
91         k++) {
92      int iRow;
93      if (fabs(elementByColumn[k]-1.0)<1.0e-10) {
94        iRow = row[k];
95        numberRows_ = max(numberRows_,iRow);
96        indices_[j++]=iRow;
97      } else if (fabs(elementByColumn[k]+1.0)<1.0e-10) {
98        iRow = row[k];
99        numberRows_ = max(numberRows_,iRow);
100        temp[iNeg++]=iRow;
101      } else {
102        goodPlusMinusOne = false; // not a network
103      }
104    }
105    if (goodPlusMinusOne) {
106      // move negative
107      startNegative_[iColumn]=j;
108      for (k=0;k<iNeg;k++) {
109        indices_[j++] = temp[k];
110      }
111    } else {
112      break;
113    }
114  }
115  startPositive_[numberColumns_]=j;
116  delete [] temp;
117  if (!goodPlusMinusOne) {
118    delete [] indices_;
119    // put in message
120    printf("Not all +-1 - can test if indices_ null\n");
121    indices_=NULL;
122    numberRows_=0;
123    numberColumns_=0;
124    delete [] startPositive_;
125    delete [] startNegative_;
126    startPositive_ = NULL;
127    startNegative_ = NULL;
128  } else {
129    numberRows_ ++; //  correct
130    columnOrdered_ = true;
131  }
132}
133
134//-------------------------------------------------------------------
135// Destructor
136//-------------------------------------------------------------------
137ClpPlusMinusOneMatrix::~ClpPlusMinusOneMatrix ()
138{
139  delete [] elements_;
140  delete [] startPositive_;
141  delete [] startNegative_;
142  delete [] lengths_;
143  delete [] indices_;
144}
145
146//----------------------------------------------------------------
147// Assignment operator
148//-------------------------------------------------------------------
149ClpPlusMinusOneMatrix &
150ClpPlusMinusOneMatrix::operator=(const ClpPlusMinusOneMatrix& rhs)
151{
152  if (this != &rhs) {
153    ClpMatrixBase::operator=(rhs);
154    delete [] elements_;
155    delete [] startPositive_;
156    delete [] startNegative_;
157    delete [] lengths_;
158    delete [] indices_;
159    elements_ = NULL;
160    startPositive_ = NULL;
161    lengths_=NULL;
162    indices_=NULL;
163    numberRows_=rhs.numberRows_;
164    numberColumns_=rhs.numberColumns_;
165    columnOrdered_=rhs.columnOrdered_;
166    if (numberColumns_) {
167      indices_ = new int [ 2*numberColumns_];
168      memcpy(indices_,rhs.indices_,2*numberColumns_*sizeof(int));
169      startPositive_ = new int [ numberColumns_+1];
170      memcpy(startPositive_,rhs.startPositive_,(numberColumns_+1)*sizeof(int));
171      startNegative_ = new int [ numberColumns_];
172      memcpy(startNegative_,rhs.startNegative_,numberColumns_*sizeof(int));
173    }
174  }
175  return *this;
176}
177//-------------------------------------------------------------------
178// Clone
179//-------------------------------------------------------------------
180ClpMatrixBase * ClpPlusMinusOneMatrix::clone() const
181{
182  return new ClpPlusMinusOneMatrix(*this);
183}
184
185/* Returns a new matrix in reverse order without gaps */
186ClpMatrixBase * 
187ClpPlusMinusOneMatrix::reverseOrderedCopy() const
188{
189  int numberMinor = (!columnOrdered_) ? numberColumns_ : numberRows_;
190  int numberMajor = (columnOrdered_) ? numberColumns_ : numberRows_;
191  // count number in each row/column
192  int * tempP = new int [numberMinor];
193  int * tempN = new int [numberMinor];
194  memset(tempP,0,numberMinor*sizeof(int));
195  memset(tempN,0,numberMinor*sizeof(int));
196  CoinBigIndex j=0;
197  int i;
198  for (i=0;i<numberMajor;i++) {
199    for (;j<startNegative_[i];j++) {
200      int iRow = indices_[j];
201      tempP[iRow]++;
202    }
203    for (;j<startPositive_[i+1];j++) {
204      int iRow = indices_[j];
205      tempN[iRow]++;
206    }
207  }
208  int * newIndices = new int [startPositive_[numberMajor]];
209  int * newP = new int [numberMinor+1];
210  int * newN = new int[numberMinor];
211  int iRow;
212  j=0;
213  // do starts
214  for (iRow=0;iRow<numberMinor;iRow++) {
215    newP[iRow]=j;
216    j += tempP[iRow];
217    tempP[iRow]=newP[iRow];
218    newN[iRow] = j;
219    j += tempN[iRow];
220    tempN[iRow]=newN[iRow];
221  }
222  newP[numberMinor]=j;
223  j=0;
224  for (i=0;i<numberMajor;i++) {
225    for (;j<startNegative_[i];j++) {
226      int iRow = indices_[j];
227      int put = tempP[iRow];
228      newIndices[put++] = i;
229      tempP[iRow] = put;
230    }
231    for (;j<startPositive_[i+1];j++) {
232      int iRow = indices_[j];
233      int put = tempN[iRow];
234      newIndices[put++] = i;
235      tempN[iRow] = put;
236    }
237  }
238  delete [] tempP;
239  delete [] tempN;
240  ClpPlusMinusOneMatrix * newCopy = new ClpPlusMinusOneMatrix();
241  newCopy->passInCopy(numberMinor, numberMajor,
242                      !columnOrdered_,  newIndices, newP, newN);
243  return newCopy;
244}
245//unscaled versions
246void 
247ClpPlusMinusOneMatrix::times(double scalar,
248                   const double * x, double * y) const
249{
250  int numberMajor = (columnOrdered_) ? numberColumns_ : numberRows_;
251  int i;
252  CoinBigIndex j;
253  assert (columnOrdered_);
254  for (i=0;i<numberMajor;i++) {
255    double value = scalar*x[i];
256    if (value) {
257      for (j=startPositive_[i];j<startNegative_[i];j++) {
258        int iRow = indices_[j];
259        y[iRow] += value;
260      }
261      for (;j<startPositive_[i+1];j++) {
262        int iRow = indices_[j];
263        y[iRow] -= value;
264      }
265    }
266  }
267}
268void 
269ClpPlusMinusOneMatrix::transposeTimes(double scalar,
270                                const double * x, double * y) const
271{
272  int numberMajor = (columnOrdered_) ? numberColumns_ : numberRows_;
273  int i;
274  CoinBigIndex j=0;
275  assert (columnOrdered_);
276  for (i=0;i<numberMajor;i++) {
277    double value = 0.0;
278    for (;j<startNegative_[i];j++) {
279      int iRow = indices_[j];
280      value += x[iRow];
281    }
282    for (;j<startPositive_[i+1];j++) {
283      int iRow = indices_[j];
284      value -= x[iRow];
285    }
286    y[i] += scalar*value;
287  }
288}
289void 
290ClpPlusMinusOneMatrix::times(double scalar,
291                       const double * x, double * y,
292                       const double * rowScale, 
293                       const double * columnScale) const
294{
295  // we know it is not scaled
296  times(scalar, x, y);
297}
298void 
299ClpPlusMinusOneMatrix::transposeTimes( double scalar,
300                                 const double * x, double * y,
301                                 const double * rowScale, 
302                                 const double * columnScale) const
303{
304  // we know it is not scaled
305  transposeTimes(scalar, x, y);
306}
307/* Return <code>x * A + y</code> in <code>z</code>.
308        Squashes small elements and knows about ClpSimplex */
309void 
310ClpPlusMinusOneMatrix::transposeTimes(const ClpSimplex * model, double scalar,
311                              const CoinIndexedVector * rowArray,
312                              CoinIndexedVector * y,
313                              CoinIndexedVector * columnArray) const
314{
315  // we know it is not scaled
316  columnArray->clear();
317  double * pi = rowArray->denseVector();
318  int numberNonZero=0;
319  int * index = columnArray->getIndices();
320  double * array = columnArray->denseVector();
321  int numberInRowArray = rowArray->getNumElements();
322  // maybe I need one in OsiSimplex
323  double zeroTolerance = model->factorization()->zeroTolerance();
324  int numberRows = model->numberRows();
325  ClpPlusMinusOneMatrix* rowCopy =
326    dynamic_cast< ClpPlusMinusOneMatrix*>(model->rowCopy());
327  if (numberInRowArray>0.3*numberRows||!rowCopy) {
328    // do by column
329    int iColumn;
330    double * markVector = y->denseVector(); // probably empty
331    CoinBigIndex j=0;
332    assert (columnOrdered_);
333    for (iColumn=0;iColumn<numberColumns_;iColumn++) {
334      double value2 = 0.0;
335      for (;j<startNegative_[iColumn];j++) {
336        int iRow = indices_[j];
337        value2 += pi[iRow];
338      }
339      for (;j<startPositive_[iColumn+1];j++) {
340        int iRow = indices_[j];
341        value2 -= pi[iRow];
342      }
343      double value = markVector[iColumn];
344      markVector[iColumn]=0.0;
345      value += scalar*value2;
346      if (fabs(value)>zeroTolerance) {
347        index[numberNonZero++]=iColumn;
348        array[iColumn]=value;
349      }
350    }
351    columnArray->setNumElements(numberNonZero);
352    y->setNumElements(0);
353  } else {
354    // do by row
355    rowCopy->transposeTimesByRow(model, scalar, rowArray, y, columnArray);
356  }
357}
358/* Return <code>x * A + y</code> in <code>z</code>.
359        Squashes small elements and knows about ClpSimplex */
360void 
361ClpPlusMinusOneMatrix::transposeTimesByRow(const ClpSimplex * model, double scalar,
362                              const CoinIndexedVector * rowArray,
363                              CoinIndexedVector * y,
364                              CoinIndexedVector * columnArray) const
365{
366  columnArray->clear();
367  double * pi = rowArray->denseVector();
368  int numberNonZero=0;
369  int * index = columnArray->getIndices();
370  double * array = columnArray->denseVector();
371  int numberInRowArray = rowArray->getNumElements();
372  // maybe I need one in OsiSimplex
373  double zeroTolerance = model->factorization()->zeroTolerance();
374  const int * column = indices_;
375  const CoinBigIndex * startPositive = startPositive_;
376  const CoinBigIndex * startNegative = startNegative_;
377  const int * whichRow = rowArray->getIndices();
378  if (numberInRowArray>2||y->getNumElements()) {
379    // do by rows
380    int iRow;
381    double * markVector = y->denseVector(); // probably empty .. but
382    int * mark = y->getIndices();
383    int numberOriginal=y->getNumElements();
384    int i;
385    for (i=0;i<numberOriginal;i++) {
386      int iColumn = mark[i];
387      index[i]=iColumn;
388      array[iColumn]=markVector[iColumn];
389      markVector[iColumn]=0.0;
390    }
391    numberNonZero=numberOriginal;
392    // and set up mark as char array
393    char * marked = (char *) markVector;
394    for (i=0;i<numberOriginal;i++) {
395      int iColumn = index[i];
396      marked[iColumn]=0;
397    }
398    for (i=0;i<numberInRowArray;i++) {
399      iRow = whichRow[i]; 
400      double value = pi[iRow]*scalar;
401      CoinBigIndex j;
402      for (j=startPositive[iRow];j<startNegative[iRow];j++) {
403        int iColumn = column[j];
404        if (!marked[iColumn]) {
405          marked[iColumn]=1;
406          index[numberNonZero++]=iColumn;
407        }
408        array[iColumn] += value;
409      }
410      for (j=startNegative[iRow];j<startPositive[iRow+1];j++) {
411        int iColumn = column[j];
412        if (!marked[iColumn]) {
413          marked[iColumn]=1;
414          index[numberNonZero++]=iColumn;
415        }
416        array[iColumn] -= value;
417      }
418    }
419    // get rid of tiny values and zero out marked
420    numberOriginal=numberNonZero;
421    numberNonZero=0;
422    for (i=0;i<numberOriginal;i++) {
423      int iColumn = index[i];
424      marked[iColumn]=0;
425      if (fabs(array[iColumn])>zeroTolerance) {
426        index[numberNonZero++]=iColumn;
427      } else {
428        array[iColumn]=0.0;
429      }
430    }
431  } else if (numberInRowArray==2) {
432    // do by rows when two rows
433    int iRow;
434    int numberOriginal;
435    int i;
436    numberNonZero=0;
437    double value;
438    iRow = whichRow[0]; 
439    value = pi[iRow]*scalar;
440    CoinBigIndex j;
441    for (j=startPositive[iRow];j<startNegative[iRow];j++) {
442      int iColumn = column[j];
443      index[numberNonZero++]=iColumn;
444      array[iColumn] = value;
445    }
446    for (j=startNegative[iRow];j<startPositive[iRow+1];j++) {
447      int iColumn = column[j];
448      index[numberNonZero++]=iColumn;
449      array[iColumn] = -value;
450    }
451    iRow = whichRow[1]; 
452    value = pi[iRow]*scalar;
453    for (j=startPositive[iRow];j<startNegative[iRow];j++) {
454      int iColumn = column[j];
455      double value2= array[iColumn];
456      if (value2) {
457        value2 += value;
458      } else {
459        value2 = value;
460        index[numberNonZero++]=iColumn;
461      }
462      array[iColumn] = value2;
463    }
464    for (j=startNegative[iRow];j<startPositive[iRow+1];j++) {
465      int iColumn = column[j];
466      double value2= array[iColumn];
467      if (value2) {
468        value2 -= value;
469      } else {
470        value2 = -value;
471        index[numberNonZero++]=iColumn;
472      }
473      array[iColumn] = value2;
474    }
475    // get rid of tiny values and zero out marked
476    numberOriginal=numberNonZero;
477    numberNonZero=0;
478    for (i=0;i<numberOriginal;i++) {
479      int iColumn = index[i];
480      if (fabs(array[iColumn])>zeroTolerance) {
481        index[numberNonZero++]=iColumn;
482      } else {
483        array[iColumn]=0.0;
484      }
485    }
486  } else if (numberInRowArray==1) {
487    // Just one row
488    int iRow=rowArray->getIndices()[0];
489    numberNonZero=0;
490    double value;
491    iRow = whichRow[0]; 
492    value = pi[iRow]*scalar;
493    if (fabs(value)>zeroTolerance) {
494      CoinBigIndex j;
495      for (j=startPositive[iRow];j<startNegative[iRow];j++) {
496        int iColumn = column[j];
497        index[numberNonZero++]=iColumn;
498        array[iColumn] = value;
499      }
500      for (j=startNegative[iRow];j<startPositive[iRow+1];j++) {
501        int iColumn = column[j];
502        index[numberNonZero++]=iColumn;
503        array[iColumn] = -value;
504      }
505    }
506  }
507  columnArray->setNumElements(numberNonZero);
508  y->setNumElements(0);
509}
510/* Return <code>x *A in <code>z</code> but
511   just for indices in y.
512   Squashes small elements and knows about ClpSimplex */
513void 
514ClpPlusMinusOneMatrix::subsetTransposeTimes(const ClpSimplex * model,
515                              const CoinIndexedVector * rowArray,
516                              const CoinIndexedVector * y,
517                              CoinIndexedVector * columnArray) const
518{
519  columnArray->clear();
520  double * pi = rowArray->denseVector();
521  int numberNonZero=0;
522  int * index = columnArray->getIndices();
523  double * array = columnArray->denseVector();
524  // maybe I need one in OsiSimplex
525  double zeroTolerance = model->factorization()->zeroTolerance();
526  int jColumn;
527  int numberToDo = y->getNumElements();
528  const int * which = y->getIndices();
529  for (jColumn=0;jColumn<numberToDo;jColumn++) {
530    int iColumn = which[jColumn];
531    double value = 0.0;
532    CoinBigIndex j=startPositive_[iColumn];
533    for (;j<startNegative_[iColumn];j++) {
534      int iRow = indices_[j];
535      value += pi[iRow];
536    }
537    for (;j<startPositive_[iColumn+1];j++) {
538      int iRow = indices_[j];
539      value -= pi[iRow];
540    }
541    if (fabs(value)>zeroTolerance) {
542      index[numberNonZero++]=iColumn;
543      array[iColumn]=value;
544    }
545  }
546}
547/* Returns number of elements in basis
548   column is basic if entry >=0 */
549CoinBigIndex
550ClpPlusMinusOneMatrix::numberInBasis(const int * columnIsBasic) const 
551{
552  int i;
553  CoinBigIndex numberElements=0;
554  assert (columnOrdered_);
555  for (i=0;i<numberColumns_;i++) {
556    if (columnIsBasic[i]>=0) 
557      numberElements += startPositive_[i+1]-startPositive_[i];
558  }
559  return numberElements;
560}
561// Fills in basis (Returns number of elements and updates numberBasic)
562CoinBigIndex
563ClpPlusMinusOneMatrix::fillBasis(const ClpSimplex * model,
564                                const int * columnIsBasic, int & numberBasic,
565                                int * indexRowU, int * indexColumnU,
566                                double * elementU) const 
567{
568  const double * rowScale = model->rowScale();
569  assert (!rowScale);
570  int i;
571  CoinBigIndex numberElements=0;
572  assert (columnOrdered_);
573  for (i=0;i<numberColumns_;i++) {
574    if (columnIsBasic[i]>=0) {
575      CoinBigIndex j=startPositive_[i];
576      for (;j<startNegative_[i];j++) {
577        int iRow = indices_[j];
578        indexRowU[numberElements]=iRow;
579        indexColumnU[numberElements]=numberBasic;
580        elementU[numberElements++]=1.0;
581      }
582      for (;j<startPositive_[i+1];j++) {
583        int iRow = indices_[j];
584        indexRowU[numberElements]=iRow;
585        indexColumnU[numberElements]=numberBasic;
586        elementU[numberElements++]=-1.0;
587      }
588      numberBasic++;
589    }
590  }
591  return numberElements;
592}
593/* Unpacks a column into an CoinIndexedvector
594      Note that model is NOT const.  Bounds and objective could
595      be modified if doing column generation */
596void 
597ClpPlusMinusOneMatrix::unpack(ClpSimplex * model,CoinIndexedVector * rowArray,
598                   int iColumn) const 
599{
600  CoinBigIndex j=startPositive_[iColumn];
601  for (;j<startNegative_[iColumn];j++) {
602    int iRow = indices_[j];
603    rowArray->add(iRow,1.0);
604  }
605  for (;j<startPositive_[iColumn+1];j++) {
606    int iRow = indices_[j];
607    rowArray->add(iRow,-1.0);
608  }
609}
610/* Adds multiple of a column into an CoinIndexedvector
611      You can use quickAdd to add to vector */
612void 
613ClpPlusMinusOneMatrix::add(const ClpSimplex * model,CoinIndexedVector * rowArray,
614                   int iColumn, double multiplier) const 
615{
616  CoinBigIndex j=startPositive_[iColumn];
617  for (;j<startNegative_[iColumn];j++) {
618    int iRow = indices_[j];
619    rowArray->quickAdd(iRow,multiplier);
620  }
621  for (;j<startPositive_[iColumn+1];j++) {
622    int iRow = indices_[j];
623    rowArray->quickAdd(iRow,-multiplier);
624  }
625}
626
627// Return a complete CoinPackedMatrix
628CoinPackedMatrix * 
629ClpPlusMinusOneMatrix::getPackedMatrix() const 
630{
631  int numberMinor = (!columnOrdered_) ? numberColumns_ : numberRows_;
632  int numberMajor = (columnOrdered_) ? numberColumns_ : numberRows_;
633  return new CoinPackedMatrix(columnOrdered_,numberMinor,numberMajor,
634                              getNumElements(),
635                              getElements(),indices_,
636                              startPositive_,getVectorLengths());
637
638}
639/* A vector containing the elements in the packed matrix. Note that there
640   might be gaps in this list, entries that do not belong to any
641   major-dimension vector. To get the actual elements one should look at
642   this vector together with vectorStarts and vectorLengths. */
643const double * 
644ClpPlusMinusOneMatrix::getElements() const 
645{
646  if (!elements_) {
647    int numberMajor = (columnOrdered_) ? numberColumns_ : numberRows_;
648    int numberElements = startPositive_[numberMajor];
649    elements_ = new double [numberElements];
650    CoinBigIndex j=0;
651    int i;
652    for (i=0;i<numberMajor;i++) {
653      for (;j<startNegative_[i];j++) {
654        elements_[j]=1.0;
655      }
656      for (;j<startPositive_[i+1];j++) {
657        elements_[j]=-1.0;
658      }
659    }
660  }
661  return elements_;
662}
663
664const CoinBigIndex * 
665ClpPlusMinusOneMatrix::getVectorStarts() const 
666{
667  return startPositive_;
668}
669/* The lengths of the major-dimension vectors. */
670const int * 
671ClpPlusMinusOneMatrix::getVectorLengths() const
672{
673  if (!lengths_) {
674    int numberMajor = (columnOrdered_) ? numberColumns_ : numberRows_;
675    lengths_ = new int [numberMajor];
676    int i;
677    for (i=0;i<numberMajor;i++) {
678      lengths_[i]=startPositive_[i+1]-startPositive_[i];
679    }
680  }
681  return lengths_;
682}
683/* Delete the columns whose indices are listed in <code>indDel</code>. */
684void 
685ClpPlusMinusOneMatrix::deleteCols(const int numDel, const int * indDel) 
686{
687  abort();
688}
689/* Delete the rows whose indices are listed in <code>indDel</code>. */
690void 
691ClpPlusMinusOneMatrix::deleteRows(const int numDel, const int * indDel) 
692{
693  abort();
694}
695bool 
696ClpPlusMinusOneMatrix::isColOrdered() const 
697{ 
698  return columnOrdered_;
699}
700/* Number of entries in the packed matrix. */
701CoinBigIndex
702ClpPlusMinusOneMatrix::getNumElements() const 
703{
704  int numberMajor = (columnOrdered_) ? numberColumns_ : numberRows_;
705  if (startPositive_) 
706    return startPositive_[numberMajor];
707  else
708    return 0;
709}
710// pass in copy (object takes ownership)
711void 
712ClpPlusMinusOneMatrix::passInCopy(int numberRows, int numberColumns,
713                  bool columnOrdered, int * indices,
714                  int * startPositive, int * startNegative)
715{
716  columnOrdered_=columnOrdered;
717  startPositive_ = startPositive;
718  startNegative_ = startNegative;
719  indices_ = indices;
720  numberRows_=numberRows;
721  numberColumns_=numberColumns;
722}
Note: See TracBrowser for help on using the repository browser.