/* $Id: ClpPlusMinusOneMatrix.hpp 2078 2015-01-05 12:39:49Z forrest $ */ // Copyright (C) 2003, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). #ifndef ClpPlusMinusOneMatrix_H #define ClpPlusMinusOneMatrix_H #include "CoinPragma.hpp" #include "ClpMatrixBase.hpp" /** This implements a simple +- one matrix as derived from ClpMatrixBase. */ class ClpPlusMinusOneMatrix : public ClpMatrixBase { public: /**@name Useful methods */ //@{ /// Return a complete CoinPackedMatrix virtual CoinPackedMatrix * getPackedMatrix() const; /** Whether the packed matrix is column major ordered or not. */ virtual bool isColOrdered() const ; /** Number of entries in the packed matrix. */ virtual CoinBigIndex getNumElements() const; /** Number of columns. */ virtual int getNumCols() const { return numberColumns_; } /** Number of rows. */ virtual int getNumRows() const { return numberRows_; } /** 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. */ virtual const double * getElements() const; /** 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. */ virtual const int * getIndices() const { return indices_; } // and for advanced use int * getMutableIndices() const { return indices_; } virtual const CoinBigIndex * getVectorStarts() const; /** The lengths of the major-dimension vectors. */ virtual const int * getVectorLengths() const; /** Delete the columns whose indices are listed in indDel. */ virtual void deleteCols(const int numDel, const int * indDel); /** Delete the rows whose indices are listed in indDel. */ virtual void deleteRows(const int numDel, const int * indDel); /// Append Columns virtual void appendCols(int number, const CoinPackedVectorBase * const * columns); /// Append Rows virtual void appendRows(int number, const CoinPackedVectorBase * const * rows); #ifndef SLIM_CLP /** Append a set of rows/columns to the end of the matrix. Returns number of errors i.e. if any of the new rows/columns contain an index that's larger than the number of columns-1/rows-1 (if numberOther>0) or duplicates If 0 then rows, 1 if columns */ virtual int appendMatrix(int number, int type, const CoinBigIndex * starts, const int * index, const double * element, int numberOther = -1); #endif /** Returns a new matrix in reverse order without gaps */ virtual ClpMatrixBase * reverseOrderedCopy() const; /// Returns number of elements in column part of basis virtual CoinBigIndex countBasis( const int * whichColumn, int & numberColumnBasic); /// Fills in column part of basis virtual void fillBasis(ClpSimplex * model, const int * whichColumn, int & numberColumnBasic, int * row, int * start, int * rowCount, int * columnCount, CoinFactorizationDouble * element); /** Given positive integer weights for each row fills in sum of weights for each column (and slack). Returns weights vector */ virtual CoinBigIndex * dubiousWeights(const ClpSimplex * model, int * inputWeights) const; /** Returns largest and smallest elements of both signs. Largest refers to largest absolute value. */ virtual void rangeOfElements(double & smallestNegative, double & largestNegative, double & smallestPositive, double & largestPositive); /** Unpacks a column into an CoinIndexedvector */ virtual void unpack(const ClpSimplex * model, CoinIndexedVector * rowArray, int column) const ; /** 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) */ virtual void unpackPacked(ClpSimplex * model, CoinIndexedVector * rowArray, int column) const; /** Adds multiple of a column into an CoinIndexedvector You can use quickAdd to add to vector */ virtual void add(const ClpSimplex * model, CoinIndexedVector * rowArray, int column, double multiplier) const ; /** Adds multiple of a column into an array */ virtual void add(const ClpSimplex * model, double * array, int column, double multiplier) const; /// Allow any parts of a created CoinMatrix to be deleted virtual void releasePackedMatrix() const; /** Set the dimensions of the matrix. In effect, append new empty columns/rows to the matrix. A negative number for either dimension means that that dimension doesn't change. Otherwise the new dimensions MUST be at least as large as the current ones otherwise an exception is thrown. */ virtual void setDimensions(int numrows, int numcols); /// Just checks matrix valid - will say if dimensions not quite right if detail void checkValid(bool detail) const; //@} /**@name Matrix times vector methods */ //@{ /** Return y + A * scalar *x in y. @pre x must be of size numColumns() @pre y must be of size numRows() */ virtual void times(double scalar, const double * x, double * y) const; /// And for scaling virtual void times(double scalar, const double * x, double * y, const double * rowScale, const double * columnScale) const; /** Return y + x * scalar * A in y. @pre x must be of size numRows() @pre y must be of size numColumns() */ virtual void transposeTimes(double scalar, const double * x, double * y) const; /// And for scaling virtual void transposeTimes(double scalar, const double * x, double * y, const double * rowScale, const double * columnScale, double * spare = NULL) const; /** 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 */ virtual void transposeTimes(const ClpSimplex * model, double scalar, const CoinIndexedVector * x, CoinIndexedVector * y, CoinIndexedVector * z) const; /** 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*/ virtual void transposeTimesByRow(const ClpSimplex * model, double scalar, const CoinIndexedVector * x, CoinIndexedVector * y, CoinIndexedVector * z) const; /** Return x *A in z but just for indices in y. Note - z always packed mode */ virtual void subsetTransposeTimes(const ClpSimplex * model, const CoinIndexedVector * x, const CoinIndexedVector * y, CoinIndexedVector * z) const; /** Returns true if can combine transposeTimes and subsetTransposeTimes and if it would be faster */ virtual bool canCombine(const ClpSimplex * model, const CoinIndexedVector * pi) const; /// Updates two arrays for steepest virtual void transposeTimes2(const ClpSimplex * model, const CoinIndexedVector * pi1, CoinIndexedVector * dj1, const CoinIndexedVector * pi2, CoinIndexedVector * spare, double referenceIn, double devex, // Array for exact devex to say what is in reference framework unsigned int * reference, double * weights, double scaleFactor); /// Updates second array for steepest and does devex weights virtual void subsetTimes2(const ClpSimplex * model, CoinIndexedVector * dj1, const CoinIndexedVector * pi2, CoinIndexedVector * dj2, double referenceIn, double devex, // Array for exact devex to say what is in reference framework unsigned int * reference, double * weights, double scaleFactor); //@} /**@name Other */ //@{ /// Return starts of +1s inline CoinBigIndex * startPositive() const { return startPositive_; } /// Return starts of -1s inline CoinBigIndex * startNegative() const { return startNegative_; } //@} /**@name Constructors, destructor */ //@{ /** Default constructor. */ ClpPlusMinusOneMatrix(); /** Destructor */ virtual ~ClpPlusMinusOneMatrix(); //@} /**@name Copy method */ //@{ /** The copy constructor. */ ClpPlusMinusOneMatrix(const ClpPlusMinusOneMatrix&); /** The copy constructor from an CoinPlusMinusOneMatrix. If not a valid matrix then getIndices will be NULL and startPositive[0] will have number of +1, startPositive[1] will have number of -1, startPositive[2] will have number of others, */ ClpPlusMinusOneMatrix(const CoinPackedMatrix&); /// Constructor from arrays ClpPlusMinusOneMatrix(int numberRows, int numberColumns, bool columnOrdered, const int * indices, const CoinBigIndex * startPositive, const CoinBigIndex * startNegative); /** Subset constructor (without gaps). Duplicates are allowed and order is as given */ ClpPlusMinusOneMatrix (const ClpPlusMinusOneMatrix & wholeModel, int numberRows, const int * whichRows, int numberColumns, const int * whichColumns); ClpPlusMinusOneMatrix& operator=(const ClpPlusMinusOneMatrix&); /// Clone virtual ClpMatrixBase * clone() const ; /** Subset clone (without gaps). Duplicates are allowed and order is as given */ virtual ClpMatrixBase * subsetClone ( int numberRows, const int * whichRows, int numberColumns, const int * whichColumns) const ; /// pass in copy (object takes ownership) void passInCopy(int numberRows, int numberColumns, bool columnOrdered, int * indices, CoinBigIndex * startPositive, CoinBigIndex * startNegative); /// Says whether it can do partial pricing virtual bool canDoPartialPricing() const; /// Partial pricing virtual void partialPricing(ClpSimplex * model, double start, double end, int & bestSequence, int & numberWanted); //@} protected: /**@name Data members The data members are protected to allow access for derived classes. */ //@{ /// For fake CoinPackedMatrix mutable CoinPackedMatrix * matrix_; mutable int * lengths_; /// Start of +1's for each CoinBigIndex * COIN_RESTRICT startPositive_; /// Start of -1's for each CoinBigIndex * COIN_RESTRICT startNegative_; /// Data -1, then +1 rows in pairs (row==-1 if one entry) int * COIN_RESTRICT indices_; /// Number of rows int numberRows_; /// Number of columns int numberColumns_; #ifdef CLP_PLUS_ONE_MATRIX /** Other flags (could have columnOrdered_?) 1 bit - says just +1 */ mutable int otherFlags_; #endif /// True if column ordered bool columnOrdered_; //@} }; #endif