1/* $Id: ClpPlusMinusOneMatrix.hpp 1665 2011-01-04 17:55:54Z lou $ */
2// Copyright (C) 2003, International Business Machines
3// Corporation and others. All Rights Reserved.
4// This code is licensed under the terms of the Eclipse Public License (EPL).
5
6#ifndef ClpPlusMinusOneMatrix_H
7#define ClpPlusMinusOneMatrix_H
8
9
10#include "CoinPragma.hpp"
11
12#include "ClpMatrixBase.hpp"
13
14/** This implements a simple +- one matrix as derived from ClpMatrixBase.
15
16*/
17
18class ClpPlusMinusOneMatrix : public ClpMatrixBase {
19
20public:
21 /**@name Useful methods */
22 //@{
23 /// Return a complete CoinPackedMatrix
24 virtual CoinPackedMatrix * getPackedMatrix() const override;
25 /** Whether the packed matrix is column major ordered or not. */
26 virtual bool isColOrdered() const override ;
27 /** Number of entries in the packed matrix. */
28 virtual CoinBigIndex getNumElements() const override;
29 /** Number of columns. */
30 virtual int getNumCols() const override {
31 return numberColumns_;
32 }
33 /** Number of rows. */
34 virtual int getNumRows() const override {
35 return numberRows_;
36 }
37
38 /** A vector containing the elements in the packed matrix. Note that there
39 might be gaps in this list, entries that do not belong to any
40 major-dimension vector. To get the actual elements one should look at
41 this vector together with vectorStarts and vectorLengths. */
42 virtual const double * getElements() const override;
43 /** A vector containing the minor indices of the elements in the packed
44 matrix. Note that there might be gaps in this list, entries that do not
45 belong to any major-dimension vector. To get the actual elements one
46 should look at this vector together with vectorStarts and
47 vectorLengths. */
48 virtual const int * getIndices() const override {
49 return indices_;
50 }
51 // and for advanced use
52 int * getMutableIndices() const {
53 return indices_;
54 }
55
56 virtual const CoinBigIndex * getVectorStarts() const override;
57 /** The lengths of the major-dimension vectors. */
58 virtual const int * getVectorLengths() const override;
59
60 /** Delete the columns whose indices are listed in <code>indDel</code>. */
61 virtual void deleteCols(const int numDel, const int * indDel) override;
62 /** Delete the rows whose indices are listed in <code>indDel</code>. */
63 virtual void deleteRows(const int numDel, const int * indDel) override;
64 /// Append Columns
65 virtual void appendCols(int number, const CoinPackedVectorBase * const * columns) override;
66 /// Append Rows
67 virtual void appendRows(int number, const CoinPackedVectorBase * const * rows) override;
68#ifndef SLIM_CLP
69 /** Append a set of rows/columns to the end of the matrix. Returns number of errors
70 i.e. if any of the new rows/columns contain an index that's larger than the
71 number of columns-1/rows-1 (if numberOther>0) or duplicates
72 If 0 then rows, 1 if columns */
73 virtual int appendMatrix(int number, int type,
74 const CoinBigIndex * starts, const int * index,
75 const double * element, int numberOther = -1) override;
76#endif
77 /** Returns a new matrix in reverse order without gaps */
78 virtual ClpMatrixBase * reverseOrderedCopy() const override;
79 /// Returns number of elements in column part of basis
80 virtual CoinBigIndex countBasis(
81 const int * whichColumn,
82 int & numberColumnBasic) override;
83 /// Fills in column part of basis
84 virtual void fillBasis(ClpSimplex * model,
85 const int * whichColumn,
86 int & numberColumnBasic,
87 int * row, int * start,
88 int * rowCount, int * columnCount,
89 CoinFactorizationDouble * element) override;
90 /** Given positive integer weights for each row fills in sum of weights
91 for each column (and slack).
92 Returns weights vector
93 */
94 virtual CoinBigIndex * dubiousWeights(const ClpSimplex * model, int * inputWeights) const override;
95 /** Returns largest and smallest elements of both signs.
96 Largest refers to largest absolute value.
97 */
98 virtual void rangeOfElements(double & smallestNegative, double & largestNegative,
99 double & smallestPositive, double & largestPositive) override;
100 /** Unpacks a column into an CoinIndexedvector
101 */
102 virtual void unpack(const ClpSimplex * model, CoinIndexedVector * rowArray,
103 int column) const override ;
104 /** Unpacks a column into an CoinIndexedvector
105 ** in packed foramt
106 Note that model is NOT const. Bounds and objective could
107 be modified if doing column generation (just for this variable) */
108 virtual void unpackPacked(ClpSimplex * model,
109 CoinIndexedVector * rowArray,
110 int column) const override;
111 /** Adds multiple of a column into an CoinIndexedvector
112 You can use quickAdd to add to vector */
113 virtual void add(const ClpSimplex * model, CoinIndexedVector * rowArray,
114 int column, double multiplier) const override ;
115 /** Adds multiple of a column into an array */
116 virtual void add(const ClpSimplex * model, double * array,
117 int column, double multiplier) const override;
118 /// Allow any parts of a created CoinMatrix to be deleted
119 virtual void releasePackedMatrix() const override;
120 /** Set the dimensions of the matrix. In effect, append new empty
121 columns/rows to the matrix. A negative number for either dimension
122 means that that dimension doesn't change. Otherwise the new dimensions
123 MUST be at least as large as the current ones otherwise an exception
124 is thrown. */
125 virtual void setDimensions(int numrows, int numcols) override;
126 /// Just checks matrix valid - will say if dimensions not quite right if detail
127 void checkValid(bool detail) const;
128 //@}
129
130 /**@name Matrix times vector methods */
131 //@{
132 /** Return <code>y + A * scalar *x</code> in <code>y</code>.
133 @pre <code>x</code> must be of size <code>numColumns()</code>
134 @pre <code>y</code> must be of size <code>numRows()</code> */
135 virtual void times(double scalar,
136 const double * x, double * y) const override;
137 /// And for scaling
138 virtual void times(double scalar,
139 const double * x, double * y,
140 const double * rowScale,
141 const double * columnScale) const override;
142 /** Return <code>y + x * scalar * A</code> in <code>y</code>.
143 @pre <code>x</code> must be of size <code>numRows()</code>
144 @pre <code>y</code> must be of size <code>numColumns()</code> */
145 virtual void transposeTimes(double scalar,
146 const double * x, double * y) const override;
147 /// And for scaling
148 virtual void transposeTimes(double scalar,
149 const double * x, double * y,
150 const double * rowScale,
151 const double * columnScale, double * spare = nullptr) const override;
152 /** Return <code>x * scalar * A + y</code> in <code>z</code>.
153 Can use y as temporary array (will be empty at end)
154 Note - If x packed mode - then z packed mode
155 Squashes small elements and knows about ClpSimplex */
156 virtual void transposeTimes(const ClpSimplex * model, double scalar,
157 const CoinIndexedVector * x,
158 CoinIndexedVector * y,
159 CoinIndexedVector * z) const override;
160 /** Return <code>x * scalar * A + y</code> in <code>z</code>.
161 Can use y as temporary array (will be empty at end)
162 Note - If x packed mode - then z packed mode
163 Squashes small elements and knows about ClpSimplex.
164 This version uses row copy*/
165 virtual void transposeTimesByRow(const ClpSimplex * model, double scalar,
166 const CoinIndexedVector * x,
167 CoinIndexedVector * y,
168 CoinIndexedVector * z) const;
169 /** Return <code>x *A</code> in <code>z</code> but
170 just for indices in y.
171 Note - z always packed mode */
172 virtual void subsetTransposeTimes(const ClpSimplex * model,
173 const CoinIndexedVector * x,
174 const CoinIndexedVector * y,
175 CoinIndexedVector * z) const override;
176 /** Returns true if can combine transposeTimes and subsetTransposeTimes
177 and if it would be faster */
178 virtual bool canCombine(const ClpSimplex * model,
179 const CoinIndexedVector * pi) const override;
180 /// Updates two arrays for steepest
181 virtual void transposeTimes2(const ClpSimplex * model,
182 const CoinIndexedVector * pi1, CoinIndexedVector * dj1,
183 const CoinIndexedVector * pi2,
184 CoinIndexedVector * spare,
185 double referenceIn, double devex,
186 // Array for exact devex to say what is in reference framework
187 unsigned int * reference,
188 double * weights, double scaleFactor) override;
189 /// Updates second array for steepest and does devex weights
190 virtual void subsetTimes2(const ClpSimplex * model,
191 CoinIndexedVector * dj1,
192 const CoinIndexedVector * pi2, CoinIndexedVector * dj2,
193 double referenceIn, double devex,
194 // Array for exact devex to say what is in reference framework
195 unsigned int * reference,
196 double * weights, double scaleFactor) override;
197 //@}
198
199 /**@name Other */
200 //@{
201 /// Return starts of +1s
202 inline CoinBigIndex * startPositive() const {
203 return startPositive_;
204 }
205 /// Return starts of -1s
206 inline CoinBigIndex * startNegative() const {
207 return startNegative_;
208 }
209 //@}
210
211
212 /**@name Constructors, destructor */
213 //@{
214 /** Default constructor. */
215 ClpPlusMinusOneMatrix();
216 /** Destructor */
217 virtual ~ClpPlusMinusOneMatrix();
218 //@}
219
220 /**@name Copy method */
221 //@{
222 /** The copy constructor. */
223 ClpPlusMinusOneMatrix(const ClpPlusMinusOneMatrix&);
224 /** The copy constructor from an CoinPlusMinusOneMatrix.
225 If not a valid matrix then getIndices will be NULL and
226 startPositive[0] will have number of +1,
227 startPositive[1] will have number of -1,
228 startPositive[2] will have number of others,
229 */
230 ClpPlusMinusOneMatrix(const CoinPackedMatrix&);
231 /// Constructor from arrays
232 ClpPlusMinusOneMatrix(int numberRows, int numberColumns,
233 bool columnOrdered, const int * indices,
234 const CoinBigIndex * startPositive, const CoinBigIndex * startNegative);
235 /** Subset constructor (without gaps). Duplicates are allowed
236 and order is as given */
237 ClpPlusMinusOneMatrix (const ClpPlusMinusOneMatrix & wholeModel,
238 int numberRows, const int * whichRows,
239 int numberColumns, const int * whichColumns);
240
241 ClpPlusMinusOneMatrix& operator=(const ClpPlusMinusOneMatrix&);
242 /// Clone
243 virtual ClpMatrixBase * clone() const override ;
244 /** Subset clone (without gaps). Duplicates are allowed
245 and order is as given */
246 virtual ClpMatrixBase * subsetClone (
247 int numberRows, const int * whichRows,
248 int numberColumns, const int * whichColumns) const override ;
249 /// pass in copy (object takes ownership)
250 void passInCopy(int numberRows, int numberColumns,
251 bool columnOrdered, int * indices,
252 CoinBigIndex * startPositive, CoinBigIndex * startNegative);
253 /// Says whether it can do partial pricing
254 virtual bool canDoPartialPricing() const override;
255 /// Partial pricing
256 virtual void partialPricing(ClpSimplex * model, double start, double end,
257 int & bestSequence, int & numberWanted) override;
258 //@}
259
260
261protected:
262 /**@name Data members
263 The data members are protected to allow access for derived classes. */
264 //@{
265 /// For fake CoinPackedMatrix
266 mutable CoinPackedMatrix * matrix_;
267 mutable int * lengths_;
268 /// Start of +1's for each
269 CoinBigIndex * startPositive_;
270 /// Start of -1's for each
271 CoinBigIndex * startNegative_;
272 /// Data -1, then +1 rows in pairs (row==-1 if one entry)
273 int * indices_;
274 /// Number of rows
275 int numberRows_;
276 /// Number of columns
277 int numberColumns_;
278 /// True if column ordered
279 bool columnOrdered_;
280
281 //@}
282};
283
284#endif
285