Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

ClpPackedMatrix Class Reference

#include <ClpPackedMatrix.hpp>

Inheritance diagram for ClpPackedMatrix:

ClpMatrixBase List of all members.

Public Member Functions

Useful methods
virtual CoinPackedMatrix * getPackedMatrix () const
 Return a complete CoinPackedMatrix.

virtual bool isColOrdered () const
virtual CoinBigIndex getNumElements () const
virtual int getNumCols () const
virtual int getNumRows () const
virtual const double * getElements () const
virtual const int * getIndices () const
virtual const CoinBigIndex * getVectorStarts () const
virtual const int * getVectorLengths () const
virtual void deleteCols (const int numDel, const int *indDel)
virtual void deleteRows (const int numDel, const int *indDel)
virtual void appendCols (int number, const CoinPackedVectorBase *const *columns)
 Append Columns.

virtual void appendRows (int number, const CoinPackedVectorBase *const *rows)
 Append Rows.

void replaceVector (const int index, const int numReplace, const double *newElements)
virtual ClpMatrixBasereverseOrderedCopy () const
virtual CoinBigIndex numberInBasis (const int *columnIsBasic) const
virtual CoinBigIndex fillBasis (const ClpSimplex *model, const int *columnIsBasic, int &numberBasic, int *row, int *column, double *element) const
 Fills in basis (Returns number of elements and updates numberBasic).

virtual CoinBigIndex fillBasis (const ClpSimplex *model, const int *whichColumn, int numberRowBasic, int numberColumnBasic, int *row, int *column, double *element) const
virtual int scale (ClpSimplex *model) const
virtual bool allElementsInRange (ClpModel *model, double smallest, double largest)
virtual void rangeOfElements (double &smallestNegative, double &largestNegative, double &smallestPositive, double &largestPositive)
virtual void unpack (const ClpSimplex *model, CoinIndexedVector *rowArray, int column) const
virtual void unpackPacked (ClpSimplex *model, CoinIndexedVector *rowArray, int column) const
virtual void add (const ClpSimplex *model, CoinIndexedVector *rowArray, int column, double multiplier) const
virtual void releasePackedMatrix () const
 Allow any parts of a created CoinPackedMatrix to be deleted.

virtual CoinBigIndex * dubiousWeights (const ClpSimplex *model, int *inputWeights) const
virtual bool canDoPartialPricing () const
 Says whether it can do partial pricing.

virtual void partialPricing (ClpSimplex *model, int start, int end, int &bestSequence, int &numberWanted)
 Partial pricing.

Matrix times vector methods
virtual void times (double scalar, const double *x, double *y) const
virtual void times (double scalar, const double *x, double *y, const double *rowScale, const double *columnScale) const
 And for scaling.

virtual void transposeTimes (double scalar, const double *x, double *y) const
virtual void transposeTimes (double scalar, const double *x, double *y, const double *rowScale, const double *columnScale) const
 And for scaling.

virtual void transposeTimes (const ClpSimplex *model, double scalar, const CoinIndexedVector *x, CoinIndexedVector *y, CoinIndexedVector *z) const
virtual void transposeTimesByRow (const ClpSimplex *model, double scalar, const CoinIndexedVector *x, CoinIndexedVector *y, CoinIndexedVector *z) const
virtual void subsetTransposeTimes (const ClpSimplex *model, const CoinIndexedVector *x, const CoinIndexedVector *y, CoinIndexedVector *z) const
Other
CoinPackedMatrix * matrix () const
 Returns CoinPackedMatrix (non const).

Constructors, destructor
 ClpPackedMatrix ()
virtual ~ClpPackedMatrix ()
Copy method
 ClpPackedMatrix (const ClpPackedMatrix &)
 ClpPackedMatrix (const CoinPackedMatrix &)
 ClpPackedMatrix (const ClpPackedMatrix &wholeModel, int numberRows, const int *whichRows, int numberColumns, const int *whichColumns)
 ClpPackedMatrix (const CoinPackedMatrix &wholeModel, int numberRows, const int *whichRows, int numberColumns, const int *whichColumns)
 ClpPackedMatrix (CoinPackedMatrix *matrix)
ClpPackedMatrixoperator= (const ClpPackedMatrix &)
virtual ClpMatrixBaseclone () const
 Clone.

virtual ClpMatrixBasesubsetClone (int numberRows, const int *whichRows, int numberColumns, const int *whichColumns) const

Protected Attributes

Data members
The data members are protected to allow access for derived classes.

CoinPackedMatrix * matrix_
 Data.

bool zeroElements_
 Zero element flag - set true if any zero elements.


Detailed Description

This implements OsiPackedMatrix as derived from ClpMatrixBase.

It adds a few methods that know about model as well as matrix

For details see OsiPackedMatrix

Definition at line 17 of file ClpPackedMatrix.hpp.


Constructor & Destructor Documentation

ClpPackedMatrix::ClpPackedMatrix  ) 
 

Default constructor.

Definition at line 25 of file ClpPackedMatrix.cpp.

References ClpMatrixBase::setType().

Referenced by clone(), reverseOrderedCopy(), and subsetClone().

00026   : ClpMatrixBase(),
00027     matrix_(NULL),
00028     zeroElements_(false)
00029 {
00030   setType(1);
00031 }

ClpPackedMatrix::~ClpPackedMatrix  )  [virtual]
 

Destructor

Definition at line 68 of file ClpPackedMatrix.cpp.

References matrix_.

00069 {
00070   delete matrix_;
00071 }

ClpPackedMatrix::ClpPackedMatrix const ClpPackedMatrix  ) 
 

The copy constructor.

Definition at line 36 of file ClpPackedMatrix.cpp.

References matrix_, and zeroElements_.

00037 : ClpMatrixBase(rhs)
00038 {  
00039   matrix_ = new CoinPackedMatrix(*(rhs.matrix_));
00040   zeroElements_ = rhs.zeroElements_;
00041   
00042 }

ClpPackedMatrix::ClpPackedMatrix const CoinPackedMatrix &   ) 
 

The copy constructor from an CoinPackedMatrix.

Definition at line 56 of file ClpPackedMatrix.cpp.

References matrix_, ClpMatrixBase::setType(), and zeroElements_.

00057 : ClpMatrixBase()
00058 {  
00059   matrix_ = new CoinPackedMatrix(rhs);
00060   zeroElements_ = false;
00061   setType(1);
00062   
00063 }

ClpPackedMatrix::ClpPackedMatrix const ClpPackedMatrix wholeModel,
int  numberRows,
const int *  whichRows,
int  numberColumns,
const int *  whichColumns
 

Subset constructor (without gaps). Duplicates are allowed and order is as given

Definition at line 106 of file ClpPackedMatrix.cpp.

References matrix_, and zeroElements_.

00110 : ClpMatrixBase(rhs)
00111 {
00112   matrix_ = new CoinPackedMatrix(*(rhs.matrix_),numberRows,whichRows,
00113                                  numberColumns,whichColumns);
00114   zeroElements_ = rhs.zeroElements_;
00115 }

ClpPackedMatrix::ClpPackedMatrix CoinPackedMatrix *  matrix  ) 
 

This takes over ownership (for space reasons)

Definition at line 47 of file ClpPackedMatrix.cpp.

References matrix_, ClpMatrixBase::setType(), and zeroElements_.

00048 : ClpMatrixBase()
00049 {  
00050   matrix_ = rhs;
00051   zeroElements_ = false;
00052   setType(1);
00053   
00054 }


Member Function Documentation

void ClpPackedMatrix::add const ClpSimplex model,
CoinIndexedVector rowArray,
int  column,
double  multiplier
const [virtual]
 

Adds multiple of a column into an CoinIndexedvector You can use quickAdd to add to vector

Implements ClpMatrixBase.

Definition at line 1484 of file ClpPackedMatrix.cpp.

References ClpSimplex::columnScale(), matrix_, CoinIndexedVector::quickAdd(), ClpSimplex::rowScale(), and scale().

01486 {
01487   const double * rowScale = model->rowScale();
01488   const int * row = matrix_->getIndices();
01489   const CoinBigIndex * columnStart = matrix_->getVectorStarts();
01490   const int * columnLength = matrix_->getVectorLengths(); 
01491   const double * elementByColumn = matrix_->getElements();
01492   CoinBigIndex i;
01493   if (!rowScale) {
01494     for (i=columnStart[iColumn];
01495          i<columnStart[iColumn]+columnLength[iColumn];i++) {
01496       int iRow = row[i];
01497       rowArray->quickAdd(iRow,multiplier*elementByColumn[i]);
01498     }
01499   } else {
01500     // apply scaling
01501     double scale = model->columnScale()[iColumn]*multiplier;
01502     for (i=columnStart[iColumn];
01503          i<columnStart[iColumn]+columnLength[iColumn];i++) {
01504       int iRow = row[i];
01505       rowArray->quickAdd(iRow,elementByColumn[i]*scale*rowScale[iRow]);
01506     }
01507   }
01508 }

bool ClpPackedMatrix::allElementsInRange ClpModel model,
double  smallest,
double  largest
[virtual]
 

Checks if all elements are in valid range. Can just return true if you are not paranoid. For Clp I will probably expect no zeros. Code can modify matrix to get rid of small elements.

Reimplemented from ClpMatrixBase.

Definition at line 1515 of file ClpPackedMatrix.cpp.

References matrix_, CoinMessageHandler::message(), ClpModel::messageHandler(), ClpModel::messages(), and zeroElements_.

01517 {
01518   int iColumn;
01519   CoinBigIndex numberLarge=0;;
01520   CoinBigIndex numberSmall=0;;
01521   CoinBigIndex numberDuplicate=0;;
01522   int firstBadColumn=-1;
01523   int firstBadRow=-1;
01524   double firstBadElement=0.0;
01525   // get matrix data pointers
01526   const int * row = matrix_->getIndices();
01527   const CoinBigIndex * columnStart = matrix_->getVectorStarts();
01528   const int * columnLength = matrix_->getVectorLengths(); 
01529   const double * elementByColumn = matrix_->getElements();
01530   int numberColumns = matrix_->getNumCols();
01531   int numberRows = matrix_->getNumRows();
01532   int * mark = new int [numberRows];
01533   int i;
01534   for (i=0;i<numberRows;i++)
01535     mark[i]=-1;
01536   for (iColumn=0;iColumn<numberColumns;iColumn++) {
01537     CoinBigIndex j;
01538     for (j=columnStart[iColumn];
01539          j<columnStart[iColumn]+columnLength[iColumn];j++) {
01540       double value = fabs(elementByColumn[j]);
01541       int iRow = row[j];
01542       if (iRow<0||iRow>=numberRows) {
01543         printf("Out of range %d %d %d %g\n",iColumn,j,row[j],elementByColumn[j]);
01544         return false;
01545       }
01546       if (mark[iRow]==-1) {
01547         mark[iRow]=j;
01548       } else {
01549         // duplicate
01550         numberDuplicate++;
01551       }
01552       //printf("%d %d %d %g\n",iColumn,j,row[j],elementByColumn[j]);
01553       if (!value)
01554         zeroElements_ = true; // there are zero elements
01555       if (value<smallest) {
01556         numberSmall++;
01557       } else if (value>largest) {
01558         numberLarge++;
01559         if (firstBadColumn<0) {
01560           firstBadColumn=iColumn;
01561           firstBadRow=row[j];
01562           firstBadElement=elementByColumn[j];
01563         }
01564       }
01565     }
01566     //clear mark
01567     for (j=columnStart[iColumn];
01568          j<columnStart[iColumn]+columnLength[iColumn];j++) {
01569       int iRow = row[j];
01570       mark[iRow]=-1;
01571     }
01572   }
01573   delete [] mark;
01574   if (numberLarge) {
01575     model->messageHandler()->message(CLP_BAD_MATRIX,model->messages())
01576       <<numberLarge
01577       <<firstBadColumn<<firstBadRow<<firstBadElement
01578       <<CoinMessageEol;
01579     return false;
01580   }
01581   if (numberSmall) 
01582     model->messageHandler()->message(CLP_SMALLELEMENTS,model->messages())
01583       <<numberSmall
01584       <<CoinMessageEol;
01585   if (numberDuplicate) 
01586     model->messageHandler()->message(CLP_DUPLICATEELEMENTS,model->messages())
01587       <<numberDuplicate
01588       <<CoinMessageEol;
01589   if (numberDuplicate) 
01590     matrix_->eliminateDuplicates(smallest);
01591   else if (numberSmall) 
01592     matrix_->compress(smallest);
01593   // If smallest >0.0 then there can't be zero elements
01594   if (smallest>0.0)
01595     zeroElements_=false;
01596   return true;
01597 }

virtual void ClpPackedMatrix::deleteCols const int  numDel,
const int *  indDel
[inline, virtual]
 

Delete the columns whose indices are listed in indDel.

Implements ClpMatrixBase.

Definition at line 55 of file ClpPackedMatrix.hpp.

References matrix_.

00056   { matrix_->deleteCols(numDel,indDel);};

virtual void ClpPackedMatrix::deleteRows const int  numDel,
const int *  indDel
[inline, virtual]
 

Delete the rows whose indices are listed in indDel.

Implements ClpMatrixBase.

Definition at line 58 of file ClpPackedMatrix.hpp.

References matrix_.

00059   { matrix_->deleteRows(numDel,indDel);};

CoinBigIndex * ClpPackedMatrix::dubiousWeights const ClpSimplex model,
int *  inputWeights
const [virtual]
 

Given positive integer weights for each row fills in sum of weights for each column (and slack). Returns weights vector

Reimplemented from ClpMatrixBase.

Definition at line 1603 of file ClpPackedMatrix.cpp.

References matrix_, ClpModel::numberColumns(), and ClpModel::numberRows().

01604 {
01605   int numberRows = model->numberRows();
01606   int numberColumns =model->numberColumns();
01607   int number = numberRows+numberColumns;
01608   CoinBigIndex * weights = new CoinBigIndex[number];
01609   // get matrix data pointers
01610   const int * row = matrix_->getIndices();
01611   const CoinBigIndex * columnStart = matrix_->getVectorStarts();
01612   const int * columnLength = matrix_->getVectorLengths(); 
01613   int i;
01614   for (i=0;i<numberColumns;i++) {
01615     CoinBigIndex j;
01616     CoinBigIndex count=0;
01617     for (j=columnStart[i];j<columnStart[i]+columnLength[i];j++) {
01618       int iRow=row[j];
01619       count += inputWeights[iRow];
01620     }
01621     weights[i]=count;
01622   }
01623   for (i=0;i<numberRows;i++) {
01624     weights[i+numberColumns]=inputWeights[i];
01625   }
01626   return weights;
01627 }

CoinBigIndex ClpPackedMatrix::fillBasis const ClpSimplex model,
const int *  whichColumn,
int  numberRowBasic,
int  numberColumnBasic,
int *  row,
int *  column,
double *  element
const [virtual]
 

If element NULL returns number of elements in column part of basis, If not NULL fills in as well

Implements ClpMatrixBase.

Definition at line 934 of file ClpPackedMatrix.cpp.

References ClpSimplex::columnScale(), matrix_, ClpSimplex::rowScale(), scale(), and zeroElements_.

00940 {
00941   const int * columnLength = matrix_->getVectorLengths(); 
00942   int i;
00943   CoinBigIndex numberElements=0;
00944   if (elementU!=NULL) {
00945     // fill
00946     const CoinBigIndex * columnStart = matrix_->getVectorStarts();
00947     const double * rowScale = model->rowScale();
00948     const int * row = matrix_->getIndices();
00949     const double * elementByColumn = matrix_->getElements();
00950     if (!zeroElements_) {
00951       if (!rowScale) {
00952         // no scaling
00953         for (i=0;i<numberColumnBasic;i++) {
00954           int iColumn = whichColumn[i];
00955           CoinBigIndex j;
00956           for (j=columnStart[iColumn];
00957                j<columnStart[iColumn]+columnLength[iColumn];j++) {
00958             indexRowU[numberElements]=row[j];
00959             indexColumnU[numberElements]=numberBasic;
00960             elementU[numberElements++]=elementByColumn[j];
00961           }
00962           numberBasic++;
00963         }
00964       } else {
00965         // scaling
00966         const double * columnScale = model->columnScale();
00967         for (i=0;i<numberColumnBasic;i++) {
00968           int iColumn = whichColumn[i];
00969           CoinBigIndex j;
00970           double scale = columnScale[iColumn];
00971           for (j=columnStart[iColumn];
00972                j<columnStart[iColumn]+columnLength[iColumn];j++) {
00973             int iRow = row[j];
00974             indexRowU[numberElements]=iRow;
00975             indexColumnU[numberElements]=numberBasic;
00976             elementU[numberElements++]=
00977               elementByColumn[j]*scale*rowScale[iRow];
00978           }
00979           numberBasic++;
00980         }
00981       }
00982     } else {
00983       // there are zero elements so need to look more closely
00984       if (!rowScale) {
00985         // no scaling
00986         for (i=0;i<numberColumnBasic;i++) {
00987           int iColumn = whichColumn[i];
00988           CoinBigIndex j;
00989           for (j=columnStart[iColumn];
00990                j<columnStart[iColumn]+columnLength[iColumn];j++) {
00991             double value = elementByColumn[j];
00992             if (value) {
00993               indexRowU[numberElements]=row[j];
00994               indexColumnU[numberElements]=numberBasic;
00995               elementU[numberElements++]=value;
00996             }
00997           }
00998           numberBasic++;
00999         }
01000       } else {
01001         // scaling
01002         const double * columnScale = model->columnScale();
01003         for (i=0;i<numberColumnBasic;i++) {
01004           int iColumn = whichColumn[i];
01005           CoinBigIndex j;
01006           double scale = columnScale[iColumn];
01007           for (j=columnStart[iColumn];
01008                j<columnStart[iColumn]+columnLength[i];j++) {
01009             double value = elementByColumn[j];
01010             if (value) {
01011               int iRow = row[j];
01012               indexRowU[numberElements]=iRow;
01013               indexColumnU[numberElements]=numberBasic;
01014               elementU[numberElements++]=value*scale*rowScale[iRow];
01015             }
01016           }
01017           numberBasic++;
01018         }
01019       }
01020     }
01021   } else {
01022     // just count - can be over so ignore zero problem
01023     for (i=0;i<numberColumnBasic;i++) {
01024       int iColumn = whichColumn[i];
01025       numberElements += columnLength[iColumn];
01026     }
01027   }
01028   return numberElements;
01029 }

virtual const double* ClpPackedMatrix::getElements  )  const [inline, virtual]
 

A vector containing the elements in the packed matrix. Note that there might be gaps in this list, entries that do not belong to any major-dimension vector. To get the actual elements one should look at this vector together with vectorStarts and vectorLengths.

Implements ClpMatrixBase.

Definition at line 38 of file ClpPackedMatrix.hpp.

References matrix_.

Referenced by ClpSimplex::createRim(), scale(), transposeTimesByRow(), and ClpSimplexPrimalQuadratic::whileIterating().

00039   { return matrix_->getElements();};

virtual const int* ClpPackedMatrix::getIndices  )  const [inline, virtual]
 

A vector containing the minor indices of the elements in the packed matrix. Note that there might be gaps in this list, entries that do not belong to any major-dimension vector. To get the actual elements one should look at this vector together with vectorStarts and vectorLengths.

Implements ClpMatrixBase.

Definition at line 45 of file ClpPackedMatrix.hpp.

References matrix_.

Referenced by ClpSimplex::createRim(), scale(), transposeTimesByRow(), and ClpSimplexPrimalQuadratic::whileIterating().

00046   { return matrix_->getIndices();};

virtual int ClpPackedMatrix::getNumCols  )  const [inline, virtual]
 

Number of columns.

Implements ClpMatrixBase.

Definition at line 30 of file ClpPackedMatrix.hpp.

References matrix_.

Referenced by fillBasis(), and numberInBasis().

00030 { return matrix_->getNumCols(); }

virtual CoinBigIndex ClpPackedMatrix::getNumElements  )  const [inline, virtual]
 

Number of entries in the packed matrix.

Implements ClpMatrixBase.

Definition at line 27 of file ClpPackedMatrix.hpp.

References matrix_.

00028   { return matrix_->getNumElements(); }

virtual int ClpPackedMatrix::getNumRows  )  const [inline, virtual]
 

Number of rows.

Implements ClpMatrixBase.

Definition at line 32 of file ClpPackedMatrix.hpp.

References matrix_.

Referenced by times().

00032 { return matrix_->getNumRows(); };

virtual const int* ClpPackedMatrix::getVectorLengths  )  const [inline, virtual]
 

The lengths of the major-dimension vectors.

Implements ClpMatrixBase.

Definition at line 51 of file ClpPackedMatrix.hpp.

References matrix_.

00052   { return matrix_->getVectorLengths();} ;

virtual bool ClpPackedMatrix::isColOrdered  )  const [inline, virtual]
 

Whether the packed matrix is column major ordered or not.

Implements ClpMatrixBase.

Definition at line 25 of file ClpPackedMatrix.hpp.

References matrix_.

00025 { return matrix_->isColOrdered(); }

CoinBigIndex ClpPackedMatrix::numberInBasis const int *  columnIsBasic  )  const [virtual]
 

Returns number of elements in basis column is basic if entry >=0

Implements ClpMatrixBase.

Definition at line 816 of file ClpPackedMatrix.cpp.

References getNumCols(), matrix_, and zeroElements_.

00817 {
00818   int i;
00819   int numberColumns = getNumCols();
00820   const int * columnLength = matrix_->getVectorLengths(); 
00821   CoinBigIndex numberElements=0;
00822   if (!zeroElements_) {
00823     for (i=0;i<numberColumns;i++) {
00824       if (columnIsBasic[i]>=0) {
00825         numberElements += columnLength[i];
00826       }
00827     }
00828   } else {
00829     // there are zero elements so need to look more closely
00830     const CoinBigIndex * columnStart = matrix_->getVectorStarts();
00831     const double * elementByColumn = matrix_->getElements();
00832     for (i=0;i<numberColumns;i++) {
00833       if (columnIsBasic[i]>=0) {
00834         CoinBigIndex j;
00835         for (j=columnStart[i];j<columnStart[i]+columnLength[i];j++) {
00836           if (elementByColumn[j])
00837             numberElements++;
00838         }
00839       }
00840     }
00841   }
00842   return numberElements;
00843 }

void ClpPackedMatrix::rangeOfElements double &  smallestNegative,
double &  largestNegative,
double &  smallestPositive,
double &  largestPositive
[virtual]
 

Returns largest and smallest elements of both signs. Largest refers to largest absolute value.

Reimplemented from ClpMatrixBase.

Definition at line 1632 of file ClpPackedMatrix.cpp.

References matrix_.

01634 {
01635   smallestNegative=-COIN_DBL_MAX;
01636   largestNegative=0.0;
01637   smallestPositive=COIN_DBL_MAX;
01638   largestPositive=0.0;
01639   int numberColumns = matrix_->getNumCols();
01640   // get matrix data pointers
01641   const double * elementByColumn = matrix_->getElements();
01642   const CoinBigIndex * columnStart = matrix_->getVectorStarts();
01643   const int * columnLength = matrix_->getVectorLengths(); 
01644   int i;
01645   for (i=0;i<numberColumns;i++) {
01646     CoinBigIndex j;
01647     for (j=columnStart[i];j<columnStart[i]+columnLength[i];j++) {
01648       double value = elementByColumn[j];
01649       if (value>0.0) {
01650         smallestPositive = min(smallestPositive,value);
01651         largestPositive = max(largestPositive,value);
01652       } else if (value<0.0) {
01653         smallestNegative = max(smallestNegative,value);
01654         largestNegative = min(largestNegative,value);
01655       }
01656     }
01657   }
01658 }

void ClpPackedMatrix::replaceVector const int  index,
const int  numReplace,
const double *  newElements
[inline]
 

Replace the elements of a vector. The indices remain the same. This is only needed if scaling and a row copy is used. At most the number specified will be replaced. The index is between 0 and major dimension of matrix

Definition at line 70 of file ClpPackedMatrix.hpp.

References matrix_.

Referenced by scale().

00072       {matrix_->replaceVector(index,numReplace,newElements);};

ClpMatrixBase * ClpPackedMatrix::reverseOrderedCopy  )  const [virtual]
 

Returns a new matrix in reverse order without gaps

Reimplemented from ClpMatrixBase.

Definition at line 130 of file ClpPackedMatrix.cpp.

References ClpPackedMatrix(), and matrix_.

Referenced by scale().

00131 {
00132   ClpPackedMatrix * copy = new ClpPackedMatrix();
00133   copy->matrix_= new CoinPackedMatrix();
00134   copy->matrix_->reverseOrderedCopyOf(*matrix_);
00135   copy->matrix_->removeGaps();
00136   return copy;
00137 }

int ClpPackedMatrix::scale ClpSimplex model  )  const [virtual]
 

Creates scales for column copy (rowCopy in model may be modified) returns non-zero if no scaling done

Reimplemented from ClpMatrixBase.

Definition at line 1032 of file ClpPackedMatrix.cpp.

References ClpModel::columnLower(), ClpModel::columnUpper(), ClpSimplex::costRegion(), getElements(), getIndices(), getVectorStarts(), matrix_, CoinMessageHandler::message(), ClpModel::messageHandler(), ClpModel::messagesPointer(), ClpModel::numberColumns(), ClpModel::numberRows(), ClpModel::objectiveAsObject(), ClpModel::primalTolerance(), ClpQuadraticObjective::quadraticObjective(), replaceVector(), reverseOrderedCopy(), ClpModel::rowCopy(), ClpModel::rowLower(), ClpModel::rowUpper(), scale(), ClpSimplex::scalingFlag(), ClpSimplex::setColumnScale(), and ClpSimplex::setRowScale().

Referenced by add(), fillBasis(), scale(), unpack(), and unpackPacked().

01033 {
01034   int numberRows = model->numberRows();
01035   int numberColumns = model->numberColumns();
01036   // If empty - return as sanityCheck will trap
01037   if (!numberRows||!numberColumns)
01038     return 1;
01039   ClpMatrixBase * rowCopyBase=model->rowCopy();
01040   if (!rowCopyBase) {
01041     // temporary copy
01042     rowCopyBase = reverseOrderedCopy();
01043   }
01044   ClpPackedMatrix* rowCopy =
01045     dynamic_cast< ClpPackedMatrix*>(rowCopyBase);
01046 
01047   // Make sure it is really a ClpPackedMatrix
01048   assert (rowCopy!=NULL);
01049   const int * column = rowCopy->getIndices();
01050   const CoinBigIndex * rowStart = rowCopy->getVectorStarts();
01051   const double * element = rowCopy->getElements();
01052   double * rowScale = new double [numberRows];
01053   double * columnScale = new double [numberColumns];
01054   // we are going to mark bits we are interested in
01055   char * usefulRow = new char [numberRows];
01056   char * usefulColumn = new char [numberColumns];
01057   double * rowLower = model->rowLower();
01058   double * rowUpper = model->rowUpper();
01059   double * columnLower = model->columnLower();
01060   double * columnUpper = model->columnUpper();
01061   int iColumn, iRow;
01062   // mark free rows
01063   for (iRow=0;iRow<numberRows;iRow++) {
01064     usefulRow[iRow]=0;
01065     if (rowUpper[iRow]<1.0e20||
01066         rowLower[iRow]>-1.0e20)
01067       usefulRow[iRow]=1;
01068   }
01069   // mark empty and fixed columns
01070   // also see if worth scaling
01071   assert (model->scalingFlag()<4); // dynamic not implemented
01072   double largest=0.0;
01073   double smallest=1.0e50;
01074   // get matrix data pointers
01075   const int * row = matrix_->getIndices();
01076   const CoinBigIndex * columnStart = matrix_->getVectorStarts();
01077   const int * columnLength = matrix_->getVectorLengths(); 
01078   const double * elementByColumn = matrix_->getElements();
01079   for (iColumn=0;iColumn<numberColumns;iColumn++) {
01080     CoinBigIndex j;
01081     char useful=0;
01082     if (columnUpper[iColumn]>
01083         columnLower[iColumn]+1.0e-9) {
01084       for (j=columnStart[iColumn];
01085            j<columnStart[iColumn]+columnLength[iColumn];j++) {
01086         iRow=row[j];
01087         if(elementByColumn[j]&&usefulRow[iRow]) {
01088           useful=1;
01089           largest = max(largest,fabs(elementByColumn[j]));
01090           smallest = min(smallest,fabs(elementByColumn[j]));
01091         }
01092       }
01093     }
01094     usefulColumn[iColumn]=useful;
01095   }
01096   model->messageHandler()->message(CLP_PACKEDSCALE_INITIAL,*model->messagesPointer())
01097     <<smallest<<largest
01098     <<CoinMessageEol;
01099   if (smallest>=0.5&&largest<=2.0) {
01100     // don't bother scaling
01101     model->messageHandler()->message(CLP_PACKEDSCALE_FORGET,*model->messagesPointer())
01102       <<CoinMessageEol;
01103     delete [] rowScale;
01104     delete [] usefulRow;
01105     delete [] columnScale;
01106     delete [] usefulColumn;
01107     return 1;
01108   } else {
01109       // need to scale 
01110     int scalingMethod = model->scalingFlag();
01111     if (scalingMethod==3) {
01112       // Choose between 1 and 2
01113       if (smallest<1.0e-5||smallest*largest<1.0)
01114         scalingMethod=1;
01115       else
01116         scalingMethod=2;
01117     }
01118     // and see if there any empty rows
01119     for (iRow=0;iRow<numberRows;iRow++) {
01120       if (usefulRow[iRow]) {
01121         CoinBigIndex j;
01122         int useful=0;
01123         for (j=rowStart[iRow];j<rowStart[iRow+1];j++) {
01124           int iColumn = column[j];
01125           if (usefulColumn[iColumn]) {
01126             useful=1;
01127             break;
01128           }
01129         }
01130         usefulRow[iRow]=useful;
01131       }
01132     }
01133     ClpFillN ( rowScale, numberRows,1.0);
01134     ClpFillN ( columnScale, numberColumns,1.0);
01135     double overallLargest=-1.0e-30;
01136     double overallSmallest=1.0e30;
01137     if (scalingMethod==1) {
01138       // Maximum in each row
01139       for (iRow=0;iRow<numberRows;iRow++) {
01140         if (usefulRow[iRow]) {
01141           CoinBigIndex j;
01142           largest=1.0e-20;
01143           for (j=rowStart[iRow];j<rowStart[iRow+1];j++) {
01144             int iColumn = column[j];
01145             if (usefulColumn[iColumn]) {
01146               double value = fabs(element[j]);
01147               largest = max(largest,value);
01148             }
01149           }
01150           rowScale[iRow]=1.0/largest;
01151           overallLargest = max(overallLargest,largest);
01152           overallSmallest = min(overallSmallest,largest);
01153         }
01154       }
01155     } else {
01156       assert(scalingMethod==2);
01157       int numberPass=3;
01158 #ifdef USE_OBJECTIVE
01159       // This will be used to help get scale factors
01160       double * objective = new double[numberColumns];
01161       memcpy(objective,model->costRegion(1),numberColumns*sizeof(double));
01162       double objScale=1.0;
01163 #endif
01164       while (numberPass) {
01165         overallLargest=0.0;
01166         overallSmallest=1.0e50;
01167         numberPass--;
01168         // Geometric mean on row scales
01169         for (iRow=0;iRow<numberRows;iRow++) {
01170           if (usefulRow[iRow]) {
01171             CoinBigIndex j;
01172             largest=1.0e-20;
01173             smallest=1.0e50;
01174             for (j=rowStart[iRow];j<rowStart[iRow+1];j++) {
01175               int iColumn = column[j];
01176               if (usefulColumn[iColumn]) {
01177                 double value = fabs(element[j]);
01178                 // Don't bother with tiny elements
01179                 if (value>1.0e-30) {
01180                   value *= columnScale[iColumn];
01181                   largest = max(largest,value);
01182                   smallest = min(smallest,value);
01183                 }
01184               }
01185             }
01186             rowScale[iRow]=1.0/sqrt(smallest*largest);
01187             overallLargest = max(largest*rowScale[iRow],overallLargest);
01188             overallSmallest = min(smallest*rowScale[iRow],overallSmallest);
01189           }
01190         }
01191 #ifdef USE_OBJECTIVE
01192         largest=1.0e-20;
01193         smallest=1.0e50;
01194         for (iColumn=0;iColumn<numberColumns;iColumn++) {
01195           if (usefulColumn[iColumn]) {
01196             double value = fabs(objective[iColumn]);
01197             // Don't bother with tiny elements
01198             if (value>1.0e-30) {
01199               value *= columnScale[iColumn];
01200               largest = max(largest,value);
01201               smallest = min(smallest,value);
01202             }
01203           }
01204         }
01205         objScale=1.0/sqrt(smallest*largest);
01206 #endif
01207         model->messageHandler()->message(CLP_PACKEDSCALE_WHILE,*model->messagesPointer())
01208           <<overallSmallest
01209           <<overallLargest
01210           <<CoinMessageEol;
01211         // skip last column round
01212         if (numberPass==1)
01213           break;
01214         // Geometric mean on column scales
01215         for (iColumn=0;iColumn<numberColumns;iColumn++) {
01216           if (usefulColumn[iColumn]) {
01217             CoinBigIndex j;
01218             largest=1.0e-20;
01219             smallest=1.0e50;
01220             for (j=columnStart[iColumn];
01221                  j<columnStart[iColumn]+columnLength[iColumn];j++) {
01222               iRow=row[j];
01223               double value = fabs(elementByColumn[j]);
01224               // Don't bother with tiny elements
01225               if (value>1.0e-30&&usefulRow[iRow]) {
01226                 value *= rowScale[iRow];
01227                 largest = max(largest,value);
01228                 smallest = min(smallest,value);
01229               }
01230             }
01231 #ifdef USE_OBJECTIVE
01232             if (fabs(objective[iColumn])>1.0e-30) {
01233               double value = fabs(objective[iColumn])*objScale;
01234               largest = max(largest,value);
01235               smallest = min(smallest,value);
01236             }
01237 #endif
01238             columnScale[iColumn]=1.0/sqrt(smallest*largest);
01239           }
01240         }
01241       }
01242 #ifdef USE_OBJECTIVE
01243       delete [] objective;
01244       printf("obj scale %g - use it if you want\n",objScale);
01245 #endif
01246     }
01247     // If ranges will make horrid then scale
01248     double tolerance = 5.0*model->primalTolerance();
01249     for (iRow=0;iRow<numberRows;iRow++) {
01250       if (usefulRow[iRow]) {
01251         double difference = rowUpper[iRow]-rowLower[iRow];
01252         double scaledDifference = difference*rowScale[iRow];
01253         if (scaledDifference>tolerance&&scaledDifference<1.0e-4) {
01254           // make gap larger
01255           rowScale[iRow] *= 1.0e-4/scaledDifference;
01256           //printf("Row %d difference %g scaled diff %g => %g\n",iRow,difference,
01257           // scaledDifference,difference*rowScale[iRow]);
01258         }
01259       }
01260     }
01261     // final pass to scale columns so largest is reasonable
01262     // See what smallest will be if largest is 1.0
01263     overallSmallest=1.0e50;
01264     for (iColumn=0;iColumn<numberColumns;iColumn++) {
01265       if (usefulColumn[iColumn]) {
01266         CoinBigIndex j;
01267         largest=1.0e-20;
01268         smallest=1.0e50;
01269         for (j=columnStart[iColumn];
01270              j<columnStart[iColumn]+columnLength[iColumn];j++) {
01271           iRow=row[j];
01272           if(elementByColumn[j]&&usefulRow[iRow]) {
01273             double value = fabs(elementByColumn[j]*rowScale[iRow]);
01274             largest = max(largest,value);
01275             smallest = min(smallest,value);
01276           }
01277         }
01278         if (overallSmallest*largest>smallest)
01279           overallSmallest = smallest/largest;
01280       }
01281     }
01282 #define RANDOMIZE
01283 #ifdef RANDOMIZE
01284     // randomize by up to 10%
01285     for (iRow=0;iRow<numberRows;iRow++) {
01286       double value = 0.5-CoinDrand48();//between -0.5 to + 0.5
01287       rowScale[iRow] *= (1.0+0.1*value);
01288     }
01289 #endif
01290     overallLargest=1.0;
01291     if (overallSmallest<1.0e-1)
01292       overallLargest = 1.0/sqrt(overallSmallest);
01293     overallLargest = min(1000.0,overallLargest);
01294     overallSmallest=1.0e50;
01295     for (iColumn=0;iColumn<numberColumns;iColumn++) {
01296       if (usefulColumn[iColumn]) {
01297         CoinBigIndex j;
01298         largest=1.0e-20;
01299         smallest=1.0e50;
01300         for (j=columnStart[iColumn];
01301              j<columnStart[iColumn]+columnLength[iColumn];j++) {
01302           iRow=row[j];
01303           if(elementByColumn[j]&&usefulRow[iRow]) {
01304             double value = fabs(elementByColumn[j]*rowScale[iRow]);
01305             largest = max(largest,value);
01306             smallest = min(smallest,value);
01307           }
01308         }
01309         columnScale[iColumn]=overallLargest/largest;
01310 #ifdef RANDOMIZE
01311         double value = 0.5-CoinDrand48();//between -0.5 to + 0.5
01312         columnScale[iColumn] *= (1.0+0.1*value);
01313 #endif
01314         double difference = columnUpper[iColumn]-columnLower[iColumn];
01315         double scaledDifference = difference*columnScale[iColumn];
01316         if (scaledDifference>tolerance&&scaledDifference<1.0e-4) {
01317           // make gap larger
01318           columnScale[iColumn] *= 1.0e-4/scaledDifference;
01319           //printf("Column %d difference %g scaled diff %g => %g\n",iColumn,difference,
01320           // scaledDifference,difference*columnScale[iColumn]);
01321         }
01322         overallSmallest = min(overallSmallest,smallest*columnScale[iColumn]);
01323       }
01324     }
01325     model->messageHandler()->message(CLP_PACKEDSCALE_FINAL,*model->messagesPointer())
01326       <<overallSmallest
01327       <<overallLargest
01328       <<CoinMessageEol;
01329     delete [] usefulRow;
01330     delete [] usefulColumn;
01331     // If quadratic then make symmetric
01332     ClpObjective * obj = model->objectiveAsObject();
01333     ClpQuadraticObjective * quadraticObj = (dynamic_cast< ClpQuadraticObjective*>(obj));
01334     if (quadraticObj) {
01335       CoinPackedMatrix * quadratic = quadraticObj->quadraticObjective();
01336       int numberXColumns = quadratic->getNumCols();
01337       if (numberXColumns<numberColumns) {
01338         // we assume symmetric
01339         int numberQuadraticColumns=0;
01340         int i;
01341         //const int * columnQuadratic = quadratic->getIndices();
01342         //const int * columnQuadraticStart = quadratic->getVectorStarts();
01343         const int * columnQuadraticLength = quadratic->getVectorLengths();
01344         for (i=0;i<numberXColumns;i++) {
01345           int length=columnQuadraticLength[i];
01346 #ifndef CORRECT_COLUMN_COUNTS
01347           length=1;
01348 #endif
01349           if (length)
01350             numberQuadraticColumns++;
01351         }
01352         int numberXRows = numberRows-numberQuadraticColumns;
01353         numberQuadraticColumns=0;
01354         for (i=0;i<numberXColumns;i++) { 
01355           int length=columnQuadraticLength[i];
01356 #ifndef CORRECT_COLUMN_COUNTS
01357           length=1;
01358 #endif
01359           if (length) {
01360             rowScale[numberQuadraticColumns+numberXRows] = columnScale[i];
01361             numberQuadraticColumns++;
01362           }
01363         }    
01364         int numberQuadraticRows=0;
01365         for (i=0;i<numberXRows;i++) {
01366           // See if any in row quadratic
01367           int j;
01368           int numberQ=0;
01369           for (j=rowStart[i];j<rowStart[i+1];j++) {
01370             int iColumn = column[j];
01371             if (columnQuadraticLength[iColumn])
01372               numberQ++;
01373           }
01374 #ifndef CORRECT_ROW_COUNTS
01375           numberQ=1;
01376 #endif
01377           if (numberQ) {
01378             columnScale[numberQuadraticRows+numberXColumns] = rowScale[i];
01379             numberQuadraticRows++;
01380           }
01381         }
01382         // and make sure Sj okay
01383         for (iColumn=numberQuadraticRows+numberXColumns;iColumn<numberColumns;iColumn++) {
01384           CoinBigIndex j=columnStart[iColumn];
01385           assert(columnLength[iColumn]==1);
01386           int iRow=row[j];
01387           double value = fabs(elementByColumn[j]*rowScale[iRow]);
01388           columnScale[iColumn]=1.0/value;
01389         }
01390       }
01391     }
01392     model->setRowScale(rowScale);
01393     model->setColumnScale(columnScale);
01394     if (model->rowCopy()) {
01395       // need to replace row by row
01396       double * newElement = new double[numberColumns];
01397       // scale row copy
01398       for (iRow=0;iRow<numberRows;iRow++) {
01399         int j;
01400         double scale = rowScale[iRow];
01401         const double * elementsInThisRow = element + rowStart[iRow];
01402         const int * columnsInThisRow = column + rowStart[iRow];
01403         int number = rowStart[iRow+1]-rowStart[iRow];
01404         assert (number<=numberColumns);
01405         for (j=0;j<number;j++) {
01406           int iColumn = columnsInThisRow[j];
01407           newElement[j] = elementsInThisRow[j]*scale*columnScale[iColumn];
01408         }
01409         rowCopy->replaceVector(iRow,number,newElement);
01410       }
01411       delete [] newElement;
01412     } else {
01413       // no row copy
01414       delete rowCopyBase;
01415     }
01416     return 0;
01417   }
01418 }

ClpMatrixBase * ClpPackedMatrix::subsetClone int  numberRows,
const int *  whichRows,
int  numberColumns,
const int *  whichColumns
const [virtual]
 

Subset clone (without gaps). Duplicates are allowed and order is as given

Reimplemented from ClpMatrixBase.

Definition at line 97 of file ClpPackedMatrix.cpp.

References ClpPackedMatrix().

00100 {
00101   return new ClpPackedMatrix(*this, numberRows, whichRows,
00102                                    numberColumns, whichColumns);
00103 }

void ClpPackedMatrix::subsetTransposeTimes const ClpSimplex model,
const CoinIndexedVector x,
const CoinIndexedVector y,
CoinIndexedVector z
const [virtual]
 

Return x *A in z but just for indices in y. Note - z always packed mode Squashes small elements and knows about ClpSimplex

Implements ClpMatrixBase.

Definition at line 765 of file ClpPackedMatrix.cpp.

References CoinIndexedVector::clear(), ClpSimplex::columnScale(), CoinIndexedVector::denseVector(), CoinIndexedVector::getIndices(), CoinIndexedVector::getNumElements(), matrix_, CoinIndexedVector::packedMode(), ClpSimplex::rowScale(), and CoinIndexedVector::setPacked().

00769 {
00770   columnArray->clear();
00771   double * pi = rowArray->denseVector();
00772   double * array = columnArray->denseVector();
00773   int jColumn;
00774   // get matrix data pointers
00775   const int * row = matrix_->getIndices();
00776   const CoinBigIndex * columnStart = matrix_->getVectorStarts();
00777   const int * columnLength = matrix_->getVectorLengths(); 
00778   const double * elementByColumn = matrix_->getElements();
00779   const double * rowScale = model->rowScale();
00780   int numberToDo = y->getNumElements();
00781   const int * which = y->getIndices();
00782   assert (!rowArray->packedMode());
00783   columnArray->setPacked();
00784   if (!rowScale) {
00785     for (jColumn=0;jColumn<numberToDo;jColumn++) {
00786       int iColumn = which[jColumn];
00787       double value = 0.0;
00788       CoinBigIndex j;
00789       for (j=columnStart[iColumn];
00790            j<columnStart[iColumn]+columnLength[iColumn];j++) {
00791         int iRow = row[j];
00792         value += pi[iRow]*elementByColumn[j];
00793       }
00794       array[jColumn]=value;
00795     }
00796   } else {
00797     // scaled
00798     for (jColumn=0;jColumn<numberToDo;jColumn++) {
00799       int iColumn = which[jColumn];
00800       double value = 0.0;
00801       CoinBigIndex j;
00802       const double * columnScale = model->columnScale();
00803       for (j=columnStart[iColumn];
00804            j<columnStart[iColumn]+columnLength[iColumn];j++) {
00805         int iRow = row[j];
00806         value += pi[iRow]*elementByColumn[j]*rowScale[iRow];
00807       }
00808       value *= columnScale[iColumn];
00809       array[jColumn]=value;
00810     }
00811   }
00812 }

void ClpPackedMatrix::times double  scalar,
const double *  x,
double *  y
const [virtual]
 

Return y + A * scalar *x in y.

Precondition:
x must be of size numColumns()

y must be of size numRows()

Implements ClpMatrixBase.

Definition at line 140 of file ClpPackedMatrix.cpp.

References matrix_.

Referenced by times().

00142 {
00143   int iRow,iColumn;
00144   // get matrix data pointers
00145   const int * row = matrix_->getIndices();
00146   const CoinBigIndex * columnStart = matrix_->getVectorStarts();
00147   const int * columnLength = matrix_->getVectorLengths(); 
00148   const double * elementByColumn = matrix_->getElements();
00149   int numberColumns = matrix_->getNumCols();
00150   //memset(y,0,matrix_->getNumRows()*sizeof(double));
00151   for (iColumn=0;iColumn<numberColumns;iColumn++) {
00152     CoinBigIndex j;
00153     double value = scalar*x[iColumn];
00154     if (value) {
00155       for (j=columnStart[iColumn];
00156            j<columnStart[iColumn]+columnLength[iColumn];j++) {
00157         iRow=row[j];
00158         y[iRow] += value*elementByColumn[j];
00159       }
00160     }
00161   }
00162 }

void ClpPackedMatrix::transposeTimes const ClpSimplex model,
double  scalar,
const CoinIndexedVector x,
CoinIndexedVector y,
CoinIndexedVector z
const [virtual]
 

Return x * scalar * A + y in z. Can use y as temporary array (will be empty at end) Note - If x packed mode - then z packed mode Squashes small elements and knows about ClpSimplex

Implements ClpMatrixBase.

Definition at line 255 of file ClpPackedMatrix.cpp.

References CoinIndexedVector::capacity(), CoinIndexedVector::checkClean(), CoinIndexedVector::clear(), ClpSimplex::columnScale(), CoinIndexedVector::denseVector(), ClpSimplex::factorization(), CoinIndexedVector::getIndices(), CoinIndexedVector::getNumElements(), matrix_, ClpModel::numberColumns(), ClpModel::numberRows(), CoinIndexedVector::packedMode(), ClpModel::rowCopy(), ClpSimplex::rowScale(), CoinIndexedVector::setNumElements(), CoinIndexedVector::setPackedMode(), and transposeTimesByRow().

00259 {
00260   columnArray->clear();
00261   double * pi = rowArray->denseVector();
00262   int numberNonZero=0;
00263   int * index = columnArray->getIndices();
00264   double * array = columnArray->denseVector();
00265   int numberInRowArray = rowArray->getNumElements();
00266   // maybe I need one in OsiSimplex
00267   double zeroTolerance = model->factorization()->zeroTolerance();
00268   int numberRows = model->numberRows();
00269   ClpPackedMatrix* rowCopy =
00270     dynamic_cast< ClpPackedMatrix*>(model->rowCopy());
00271   bool packed = rowArray->packedMode();
00272   double factor = 0.3;
00273   // We may not want to do by row if there may be cache problems
00274   int numberColumns = model->numberColumns();
00275   // It would be nice to find L2 cache size - for moment 512K
00276   // Be slightly optimistic
00277   if (numberColumns*sizeof(double)>1000000) {
00278     if (numberRows*10<numberColumns)
00279       factor=0.1;
00280     else if (numberRows*4<numberColumns)
00281       factor=0.15;
00282     else if (numberRows*2<numberColumns)
00283       factor=0.2;
00284     //if (model->numberIterations()%50==0)
00285     //printf("%d nonzero\n",numberInRowArray);
00286   }
00287   if (numberInRowArray>factor*numberRows||!rowCopy) {
00288     // do by column
00289     int iColumn;
00290     // get matrix data pointers
00291     const int * row = matrix_->getIndices();
00292     const CoinBigIndex * columnStart = matrix_->getVectorStarts();
00293     const int * columnLength = matrix_->getVectorLengths(); 
00294     const double * elementByColumn = matrix_->getElements();
00295     const double * rowScale = model->rowScale();
00296     int numberColumns = model->numberColumns();
00297     if (!y->getNumElements()) {
00298       if (packed) {
00299         // need to expand pi into y
00300         assert(y->capacity()>=numberRows);
00301         double * piOld = pi;
00302         pi = y->denseVector();
00303         const int * whichRow = rowArray->getIndices();
00304         int i;
00305         if (!rowScale) {
00306           // modify pi so can collapse to one loop
00307           for (i=0;i<numberInRowArray;i++) {
00308             int iRow = whichRow[i];
00309             pi[iRow]=scalar*piOld[i];
00310           }
00311           for (iColumn=0;iColumn<numberColumns;iColumn++) {
00312             double value = 0.0;
00313             CoinBigIndex j;
00314             for (j=columnStart[iColumn];
00315                  j<columnStart[iColumn]+columnLength[iColumn];j++) {
00316               int iRow = row[j];
00317               value += pi[iRow]*elementByColumn[j];
00318             }
00319             if (fabs(value)>zeroTolerance) {
00320               array[numberNonZero]=value;
00321               index[numberNonZero++]=iColumn;
00322             }
00323           }
00324         } else {
00325           // scaled
00326           // modify pi so can collapse to one loop
00327           for (i=0;i<numberInRowArray;i++) {
00328             int iRow = whichRow[i];
00329             pi[iRow]=scalar*piOld[i]*rowScale[iRow];
00330           }
00331           for (iColumn=0;iColumn<numberColumns;iColumn++) {
00332             double value = 0.0;
00333             CoinBigIndex j;
00334             const double * columnScale = model->columnScale();
00335             for (j=columnStart[iColumn];
00336                  j<columnStart[iColumn]+columnLength[iColumn];j++) {
00337               int iRow = row[j];
00338               value += pi[iRow]*elementByColumn[j];
00339             }
00340             value *= columnScale[iColumn];
00341             if (fabs(value)>zeroTolerance) {
00342               array[numberNonZero]=value;
00343               index[numberNonZero++]=iColumn;
00344             }
00345           }
00346         }
00347         // zero out
00348         for (i=0;i<numberInRowArray;i++) {
00349           int iRow = whichRow[i];
00350           pi[iRow]=0.0;
00351         }
00352       } else {
00353         if (!rowScale) {
00354           if (scalar==-1.0) {
00355             for (iColumn=0;iColumn<numberColumns;iColumn++) {
00356               double value = 0.0;
00357               CoinBigIndex j;
00358               for (j=columnStart[iColumn];
00359                    j<columnStart[iColumn]+columnLength[iColumn];j++) {
00360                 int iRow = row[j];
00361                 value += pi[iRow]*elementByColumn[j];
00362               }
00363               if (fabs(value)>zeroTolerance) {
00364                 index[numberNonZero++]=iColumn;
00365                 array[iColumn]=-value;
00366               }
00367             }
00368           } else if (scalar==1.0) {
00369             for (iColumn=0;iColumn<numberColumns;iColumn++) {
00370               double value = 0.0;
00371               CoinBigIndex j;
00372               for (j=columnStart[iColumn];
00373                    j<columnStart[iColumn]+columnLength[iColumn];j++) {
00374                 int iRow = row[j];
00375                 value += pi[iRow]*elementByColumn[j];
00376               }
00377               if (fabs(value)>zeroTolerance) {
00378                 index[numberNonZero++]=iColumn;
00379                 array[iColumn]=value;
00380               }
00381             }
00382           } else {
00383             for (iColumn=0;iColumn<numberColumns;iColumn++) {
00384               double value = 0.0;
00385               CoinBigIndex j;
00386               for (j=columnStart[iColumn];
00387                    j<columnStart[iColumn]+columnLength[iColumn];j++) {
00388                 int iRow = row[j];
00389                 value += pi[iRow]*elementByColumn[j];
00390               }
00391               value *= scalar;
00392               if (fabs(value)>zeroTolerance) {
00393                 index[numberNonZero++]=iColumn;
00394                 array[iColumn]=value;
00395               }
00396             }
00397           }
00398         } else {
00399           // scaled
00400           if (scalar==-1.0) {
00401             for (iColumn=0;iColumn<numberColumns;iColumn++) {
00402               double value = 0.0;
00403               CoinBigIndex j;
00404               const double * columnScale = model->columnScale();
00405               for (j=columnStart[iColumn];
00406                    j<columnStart[iColumn]+columnLength[iColumn];j++) {
00407                 int iRow = row[j];
00408                 value += pi[iRow]*elementByColumn[j]*rowScale[iRow];
00409               }
00410               value *= columnScale[iColumn];
00411               if (fabs(value)>zeroTolerance) {
00412                 index[numberNonZero++]=iColumn;
00413                 array[iColumn]=-value;
00414               }
00415             }
00416           } else if (scalar==1.0) {
00417             for (iColumn=0;iColumn<numberColumns;iColumn++) {
00418               double value = 0.0;
00419               CoinBigIndex j;
00420               const double * columnScale = model->columnScale();
00421               for (j=columnStart[iColumn];
00422                    j<columnStart[iColumn]+columnLength[iColumn];j++) {
00423                 int iRow = row[j];
00424                 value += pi[iRow]*elementByColumn[j]*rowScale[iRow];
00425               }
00426               value *= columnScale[iColumn];
00427               if (fabs(value)>zeroTolerance) {
00428                 index[numberNonZero++]=iColumn;
00429                 array[iColumn]=value;
00430               }
00431             }
00432           } else {
00433             for (iColumn=0;iColumn<numberColumns;iColumn++) {
00434               double value = 0.0;
00435               CoinBigIndex j;
00436               const double * columnScale = model->columnScale();
00437               for (j=columnStart[iColumn];
00438                    j<columnStart[iColumn]+columnLength[iColumn];j++) {
00439                 int iRow = row[j];
00440                 value += pi[iRow]*elementByColumn[j]*rowScale[iRow];
00441               }
00442               value *= scalar*columnScale[iColumn];
00443               if (fabs(value)>zeroTolerance) {
00444                 index[numberNonZero++]=iColumn;
00445                 array[iColumn]=value;
00446               }
00447             }
00448           }
00449         }
00450       }
00451     } else {
00452       assert(!packed);
00453       double * markVector = y->denseVector(); // not empty
00454       if (!rowScale) {
00455         for (iColumn=0;iColumn<numberColumns;iColumn++) {
00456           double value = markVector[iColumn];
00457           markVector[iColumn]=0.0;
00458           double value2 = 0.0;
00459           CoinBigIndex j;
00460           for (j=columnStart[iColumn];
00461                j<columnStart[iColumn]+columnLength[iColumn];j++) {
00462             int iRow = row[j];
00463             value2 += pi[iRow]*elementByColumn[j];
00464           }
00465           value += value2*scalar;
00466           if (fabs(value)>zeroTolerance) {
00467             index[numberNonZero++]=iColumn;
00468             array[iColumn]=value;
00469           }
00470         }
00471       } else {
00472         // scaled
00473         for (iColumn=0;iColumn<numberColumns;iColumn++) {
00474           double value = markVector[iColumn];
00475           markVector[iColumn]=0.0;
00476           CoinBigIndex j;
00477           const double * columnScale = model->columnScale();
00478           double value2 = 0.0;
00479           for (j=columnStart[iColumn];
00480                j<columnStart[iColumn]+columnLength[iColumn];j++) {
00481             int iRow = row[j];
00482             value2 += pi[iRow]*elementByColumn[j]*rowScale[iRow];
00483           }
00484           value += value2*scalar*columnScale[iColumn];
00485           if (fabs(value)>zeroTolerance) {
00486             index[numberNonZero++]=iColumn;
00487             array[iColumn]=value;
00488           }
00489         }
00490       }
00491     }
00492     columnArray->setNumElements(numberNonZero);
00493     y->setNumElements(0);
00494   } else {
00495     // do by row
00496     rowCopy->transposeTimesByRow(model, scalar, rowArray, y, columnArray);
00497   }
00498   if (packed)
00499     columnArray->setPackedMode(true);
00500   if (0) {
00501     columnArray->checkClean();
00502     int numberNonZero=columnArray->getNumElements();;
00503     int * index = columnArray->getIndices();
00504     double * array = columnArray->denseVector();
00505     int i;
00506     for (i=0;i<numberNonZero;i++) {
00507       int j=index[i];
00508       double value;
00509       if (packed)
00510         value=array[i];
00511       else
00512         value=array[j];
00513       printf("Ti %d %d %g\n",i,j,value);
00514     }
00515   }
00516 }

void ClpPackedMatrix::transposeTimes double  scalar,
const double *  x,
double *  y
const [virtual]
 

Return y + x * scalar * A in y.

Precondition:
x must be of size numRows()

y must be of size numColumns()

Implements ClpMatrixBase.

Definition at line 164 of file ClpPackedMatrix.cpp.

References matrix_.

Referenced by transposeTimes().

00166 {
00167   int iColumn;
00168   // get matrix data pointers
00169   const int * row = matrix_->getIndices();
00170   const CoinBigIndex * columnStart = matrix_->getVectorStarts();
00171   const int * columnLength = matrix_->getVectorLengths(); 
00172   const double * elementByColumn = matrix_->getElements();
00173   int numberColumns = matrix_->getNumCols();
00174   //memset(y,0,numberColumns*sizeof(double));
00175   for (iColumn=0;iColumn<numberColumns;iColumn++) {
00176     CoinBigIndex j;
00177     double value=0.0;
00178     for (j=columnStart[iColumn];
00179          j<columnStart[iColumn]+columnLength[iColumn];j++) {
00180       int jRow=row[j];
00181       value += x[jRow]*elementByColumn[j];
00182     }
00183     y[iColumn] += value*scalar;
00184   }
00185 }

void ClpPackedMatrix::transposeTimesByRow const ClpSimplex model,
double  scalar,
const CoinIndexedVector x,
CoinIndexedVector y,
CoinIndexedVector z
const [virtual]
 

Return x * scalar * A + y in z. Can use y as temporary array (will be empty at end) Note - If x packed mode - then z packed mode Squashes small elements and knows about ClpSimplex. This version uses row copy

Definition at line 520 of file ClpPackedMatrix.cpp.

References CoinIndexedVector::capacity(), CoinIndexedVector::clear(), CoinIndexedVector::denseVector(), ClpSimplex::factorization(), getElements(), getIndices(), CoinIndexedVector::getIndices(), CoinIndexedVector::getNumElements(), ClpModel::numberColumns(), CoinIndexedVector::packedMode(), and CoinIndexedVector::setNumElements().

Referenced by transposeTimes().

00524 {
00525   columnArray->clear();
00526   double * pi = rowArray->denseVector();
00527   int numberNonZero=0;
00528   int * index = columnArray->getIndices();
00529   double * array = columnArray->denseVector();
00530   int numberInRowArray = rowArray->getNumElements();
00531   // maybe I need one in OsiSimplex
00532   double zeroTolerance = model->factorization()->zeroTolerance();
00533   const int * column = getIndices();
00534   const CoinBigIndex * rowStart = getVectorStarts();
00535   const double * element = getElements();
00536   const int * whichRow = rowArray->getIndices();
00537   bool packed = rowArray->packedMode();
00538   if (numberInRowArray>2||y->getNumElements()) {
00539     // do by rows
00540     // ** Row copy is already scaled
00541     int iRow;
00542     int * mark = y->getIndices();
00543     int numberOriginal=y->getNumElements();
00544     int i;
00545     if (packed) {
00546       assert(!numberOriginal);
00547       numberNonZero=0;
00548       // and set up mark as char array
00549       char * marked = (char *) (index+columnArray->capacity());
00550       double * array2 = y->denseVector();
00551 #ifdef CLP_DEBUG
00552       int numberColumns = model->numberColumns();
00553       for (i=0;i<numberColumns;i++) {
00554         assert(!marked[i]);
00555         assert(!array2[i]);
00556       }
00557 #endif      
00558       for (i=0;i<numberInRowArray;i++) {
00559         iRow = whichRow[i]; 
00560         double value = pi[i]*scalar;
00561         CoinBigIndex j;
00562         for (j=rowStart[iRow];j<rowStart[iRow+1];j++) {
00563           int iColumn = column[j];
00564           if (!marked[iColumn]) {
00565             marked[iColumn]=1;
00566             index[numberNonZero++]=iColumn;
00567           }
00568           array2[iColumn] += value*element[j];
00569         }
00570       }
00571       // get rid of tiny values and zero out marked
00572       numberOriginal=numberNonZero;
00573       numberNonZero=0;
00574       for (i=0;i<numberOriginal;i++) {
00575         int iColumn = index[i];
00576         if (marked[iColumn]) {
00577           double value = array2[iColumn];
00578           array2[iColumn]=0.0;
00579           marked[iColumn]=0;
00580           if (fabs(value)>zeroTolerance) {
00581             array[numberNonZero]=value;
00582             index[numberNonZero++]=iColumn;
00583           }
00584         }
00585       }
00586     } else {
00587       double * markVector = y->denseVector(); // probably empty .. but
00588       for (i=0;i<numberOriginal;i++) {
00589         int iColumn = mark[i];
00590         index[i]=iColumn;
00591         array[iColumn]=markVector[iColumn];
00592         markVector[iColumn]=0.0;
00593       }
00594       numberNonZero=numberOriginal;
00595       // and set up mark as char array
00596       char * marked = (char *) markVector;
00597       for (i=0;i<numberOriginal;i++) {
00598         int iColumn = index[i];
00599         marked[iColumn]=0;
00600       }
00601       
00602       for (i=0;i<numberInRowArray;i++) {
00603         iRow = whichRow[i]; 
00604         double value = pi[iRow]*scalar;
00605         CoinBigIndex j;
00606         for (j=rowStart[iRow];j<rowStart[iRow+1];j++) {
00607           int iColumn = column[j];
00608           if (!marked[iColumn]) {
00609             marked[iColumn]=1;
00610             index[numberNonZero++]=iColumn;
00611           }
00612           array[iColumn] += value*element[j];
00613         }
00614       }
00615       // get rid of tiny values and zero out marked
00616       numberOriginal=numberNonZero;
00617       numberNonZero=0;
00618       for (i=0;i<numberOriginal;i++) {
00619         int iColumn = index[i];
00620         marked[iColumn]=0;
00621         if (fabs(array[iColumn])>zeroTolerance) {
00622           index[numberNonZero++]=iColumn;
00623         } else {
00624           array[iColumn]=0.0;
00625         }
00626       }
00627     }
00628   } else if (numberInRowArray==2) {
00629     // do by rows when two rows
00630     int numberOriginal;
00631     int i;
00632     CoinBigIndex j;
00633     numberNonZero=0;
00634 
00635     double value;
00636     if (packed) {
00637       int iRow0 = whichRow[0]; 
00638       int iRow1 = whichRow[1]; 
00639       double pi0 = pi[0];
00640       double pi1 = pi[1];
00641       if (rowStart[iRow0+1]-rowStart[iRow0]>
00642           rowStart[iRow1+1]-rowStart[iRow1]) {
00643         // do one with fewer first
00644         iRow0=iRow1;
00645         iRow1=whichRow[0];
00646         pi0=pi1;
00647         pi1=pi[0];
00648       }
00649       // and set up mark as char array
00650       char * marked = (char *) (index+columnArray->capacity());
00651       int * lookup = y->getIndices();
00652       value = pi0*scalar;
00653       for (j=rowStart[iRow0];j<rowStart[iRow0+1];j++) {
00654         int iColumn = column[j];
00655         double value2 = value*element[j];
00656         array[numberNonZero] = value2;
00657         marked[iColumn]=1;
00658         lookup[iColumn]=numberNonZero;
00659         index[numberNonZero++]=iColumn;
00660       }
00661       numberOriginal = numberNonZero;
00662       value = pi1*scalar;
00663       for (j=rowStart[iRow1];j<rowStart[iRow1+1];j++) {
00664         int iColumn = column[j];
00665         double value2 = value*element[j];
00666         // I am assuming no zeros in matrix
00667         if (marked[iColumn]) {
00668           int iLookup = lookup[iColumn];
00669           array[iLookup] += value2;
00670         } else {
00671           if (fabs(value2)>zeroTolerance) {
00672             array[numberNonZero] = value2;
00673             index[numberNonZero++]=iColumn;
00674           }
00675         }
00676       }
00677       // get rid of tiny values and zero out marked
00678       int nDelete=0;
00679       for (i=0;i<numberOriginal;i++) {
00680         int iColumn = index[i];
00681         marked[iColumn]=0;
00682         if (fabs(array[i])<=zeroTolerance) 
00683           nDelete++;
00684       }
00685       if (nDelete) {
00686         numberOriginal=numberNonZero;
00687         numberNonZero=0;
00688         for (i=0;i<numberOriginal;i++) {
00689           int iColumn = index[i];
00690           double value = array[i];
00691           array[i]=0.0;
00692           if (fabs(value)>zeroTolerance) {
00693             array[numberNonZero]=value;
00694             index[numberNonZero++]=iColumn;
00695           }
00696         }
00697       }
00698     } else {
00699       int iRow = whichRow[0]; 
00700       value = pi[iRow]*scalar;
00701       for (j=rowStart[iRow];j<rowStart[iRow+1];j++) {
00702         int iColumn = column[j];
00703         double value2 = value*element[j];
00704         index[numberNonZero++]=iColumn;
00705         array[iColumn] = value2;
00706       }
00707       iRow = whichRow[1]; 
00708       value = pi[iRow]*scalar;
00709       for (j=rowStart[iRow];j<rowStart[iRow+1];j++) {
00710         int iColumn = column[j];
00711         double value2 = value*element[j];
00712         // I am assuming no zeros in matrix
00713         if (array[iColumn])
00714           value2 += array[iColumn];
00715         else
00716           index[numberNonZero++]=iColumn;
00717         array[iColumn] = value2;
00718       }
00719       // get rid of tiny values and zero out marked
00720       numberOriginal=numberNonZero;
00721       numberNonZero=0;
00722       for (i=0;i<numberOriginal;i++) {
00723         int iColumn = index[i];
00724         if (fabs(array[iColumn])>zeroTolerance) {
00725           index[numberNonZero++]=iColumn;
00726         } else {
00727           array[iColumn]=0.0;
00728         }
00729       }
00730     }
00731   } else if (numberInRowArray==1) {
00732     // Just one row
00733     int iRow=rowArray->getIndices()[0];
00734     numberNonZero=0;
00735     CoinBigIndex j;
00736     if (packed) {
00737       double value = pi[0]*scalar;
00738       for (j=rowStart[iRow];j<rowStart[iRow+1];j++) {
00739         int iColumn = column[j];
00740         double value2 = value*element[j];
00741         if (fabs(value2)>zeroTolerance) {
00742           array[numberNonZero] = value2;
00743           index[numberNonZero++]=iColumn;
00744         }
00745       }
00746     } else {
00747       double value = pi[iRow]*scalar;
00748       for (j=rowStart[iRow];j<rowStart[iRow+1];j++) {
00749         int iColumn = column[j];
00750         double value2 = value*element[j];
00751         if (fabs(value2)>zeroTolerance) {
00752           index[numberNonZero++]=iColumn;
00753           array[iColumn] = value2;
00754         }
00755       }
00756     }
00757   }
00758   columnArray->setNumElements(numberNonZero);
00759   y->setNumElements(0);
00760 }

void ClpPackedMatrix::unpack const ClpSimplex model,
CoinIndexedVector rowArray,
int  column
const [virtual]
 

Unpacks a column into an CoinIndexedvector

Implements ClpMatrixBase.

Definition at line 1422 of file ClpPackedMatrix.cpp.

References CoinIndexedVector::add(), ClpSimplex::columnScale(), matrix_, ClpSimplex::rowScale(), and scale().

01424 {
01425   const double * rowScale = model->rowScale();
01426   const int * row = matrix_->getIndices();
01427   const CoinBigIndex * columnStart = matrix_->getVectorStarts();
01428   const int * columnLength = matrix_->getVectorLengths(); 
01429   const double * elementByColumn = matrix_->getElements();
01430   CoinBigIndex i;
01431   if (!rowScale) {
01432     for (i=columnStart[iColumn];
01433          i<columnStart[iColumn]+columnLength[iColumn];i++) {
01434       rowArray->add(row[i],elementByColumn[i]);
01435     }
01436   } else {
01437     // apply scaling
01438     double scale = model->columnScale()[iColumn];
01439     for (i=columnStart[iColumn];
01440          i<columnStart[iColumn]+columnLength[iColumn];i++) {
01441       int iRow = row[i];
01442       rowArray->add(iRow,elementByColumn[i]*scale*rowScale[iRow]);
01443     }
01444   }
01445 }

void ClpPackedMatrix::unpackPacked ClpSimplex model,
CoinIndexedVector rowArray,
int  column
const [virtual]
 

Unpacks a column into an CoinIndexedvector in packed foramt Note that model is NOT const. Bounds and objective could be modified if doing column generation (just for this variable)

Implements ClpMatrixBase.

Definition at line 1451 of file ClpPackedMatrix.cpp.

References ClpSimplex::columnScale(), CoinIndexedVector::createPacked(), CoinIndexedVector::denseVector(), CoinIndexedVector::getIndices(), matrix_, ClpSimplex::rowScale(), scale(), CoinIndexedVector::setNumElements(), and CoinIndexedVector::setPackedMode().

01454 {
01455   const double * rowScale = model->rowScale();
01456   const int * row = matrix_->getIndices();
01457   const CoinBigIndex * columnStart = matrix_->getVectorStarts();
01458   const int * columnLength = matrix_->getVectorLengths(); 
01459   const double * elementByColumn = matrix_->getElements();
01460   CoinBigIndex i;
01461   if (!rowScale) {
01462     int j=columnStart[iColumn];
01463     rowArray->createPacked(columnLength[iColumn],
01464                            row+j,elementByColumn+j);
01465   } else {
01466     // apply scaling
01467     double scale = model->columnScale()[iColumn];
01468     int * index = rowArray->getIndices();
01469     double * array = rowArray->denseVector();
01470     int number = 0;
01471     for (i=columnStart[iColumn];
01472          i<columnStart[iColumn]+columnLength[iColumn];i++) {
01473       int iRow = row[i];
01474       array[number]=elementByColumn[i]*scale*rowScale[iRow];
01475       index[number++]=iRow;
01476     }
01477     rowArray->setNumElements(number);
01478     rowArray->setPackedMode(true);
01479   }
01480 }


The documentation for this class was generated from the following files:
Generated on Wed Dec 3 14:37:41 2003 for CLP by doxygen 1.3.5