source: trunk/Clp/src/ClpPlusMinusOneMatrix.hpp @ 2470

Last change on this file since 2470 was 2385, checked in by unxusr, 10 months ago

formatting

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 21.1 KB
Line 
1/* $Id: ClpPlusMinusOneMatrix.hpp 2385 2019-01-06 19:43:06Z stefan $ */
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#include "CoinPragma.hpp"
10
11#include "ClpMatrixBase.hpp"
12
13/** This implements a simple +- one matrix as derived from ClpMatrixBase.
14
15*/
16
17class ClpPlusMinusOneMatrix : public ClpMatrixBase {
18
19public:
20  /**@name Useful methods */
21  //@{
22  /// Return a complete CoinPackedMatrix
23  virtual CoinPackedMatrix *getPackedMatrix() const;
24  /** Whether the packed matrix is column major ordered or not. */
25  virtual bool isColOrdered() const;
26  /** Number of entries in the packed matrix. */
27  virtual CoinBigIndex getNumElements() const;
28  /** Number of columns. */
29  virtual int getNumCols() const
30  {
31    return numberColumns_;
32  }
33  /** Number of rows. */
34  virtual int getNumRows() const
35  {
36    return numberRows_;
37  }
38
39  /** A vector containing the elements in the packed matrix. Note that there
40      might be gaps in this list, entries that do not belong to any
41      major-dimension vector. To get the actual elements one should look at
42      this vector together with vectorStarts and vectorLengths. */
43  virtual const double *getElements() const;
44  /** A vector containing the minor indices of the elements in the packed
45          matrix. Note that there might be gaps in this list, entries that do not
46          belong to any major-dimension vector. To get the actual elements one
47          should look at this vector together with vectorStarts and
48          vectorLengths. */
49  virtual const int *getIndices() const
50  {
51    return indices_;
52  }
53  // and for advanced use
54  int *getMutableIndices() const
55  {
56    return indices_;
57  }
58
59  virtual const CoinBigIndex *getVectorStarts() const;
60  /** The lengths of the major-dimension vectors. */
61  virtual const int *getVectorLengths() const;
62
63  /** Delete the columns whose indices are listed in <code>indDel</code>. */
64  virtual void deleteCols(const int numDel, const int *indDel);
65  /** Delete the rows whose indices are listed in <code>indDel</code>. */
66  virtual void deleteRows(const int numDel, const int *indDel);
67  /// Append Columns
68  virtual void appendCols(int number, const CoinPackedVectorBase *const *columns);
69  /// Append Rows
70  virtual void appendRows(int number, const CoinPackedVectorBase *const *rows);
71#ifndef SLIM_CLP
72  /** Append a set of rows/columns to the end of the matrix. Returns number of errors
73         i.e. if any of the new rows/columns contain an index that's larger than the
74         number of columns-1/rows-1 (if numberOther>0) or duplicates
75         If 0 then rows, 1 if columns */
76  virtual int appendMatrix(int number, int type,
77    const CoinBigIndex *starts, const int *index,
78    const double *element, int numberOther = -1);
79#endif
80  /** Returns a new matrix in reverse order without gaps */
81  virtual ClpMatrixBase *reverseOrderedCopy() const;
82  /// Returns number of elements in column part of basis
83  virtual int countBasis(
84    const int *whichColumn,
85    int &numberColumnBasic);
86  /// Fills in column part of basis
87  virtual void fillBasis(ClpSimplex *model,
88    const int *whichColumn,
89    int &numberColumnBasic,
90    int *row, int *start,
91    int *rowCount, int *columnCount,
92    CoinFactorizationDouble *element);
93  /** Given positive integer weights for each row fills in sum of weights
94         for each column (and slack).
95         Returns weights vector
96     */
97  virtual CoinBigIndex *dubiousWeights(const ClpSimplex *model, int *inputWeights) const;
98  /** Returns largest and smallest elements of both signs.
99         Largest refers to largest absolute value.
100     */
101  virtual void rangeOfElements(double &smallestNegative, double &largestNegative,
102    double &smallestPositive, double &largestPositive);
103  /** Unpacks a column into an CoinIndexedvector
104      */
105  virtual void unpack(const ClpSimplex *model, CoinIndexedVector *rowArray,
106    int column) const;
107  /** Unpacks a column into an CoinIndexedvector
108      ** in packed foramt
109         Note that model is NOT const.  Bounds and objective could
110         be modified if doing column generation (just for this variable) */
111  virtual void unpackPacked(ClpSimplex *model,
112    CoinIndexedVector *rowArray,
113    int column) const;
114  /** Adds multiple of a column into an CoinIndexedvector
115         You can use quickAdd to add to vector */
116  virtual void add(const ClpSimplex *model, CoinIndexedVector *rowArray,
117    int column, double multiplier) const;
118  /** Adds multiple of a column into an array */
119  virtual void add(const ClpSimplex *model, double *array,
120    int column, double multiplier) const;
121  /// Allow any parts of a created CoinMatrix to be deleted
122  virtual void releasePackedMatrix() const;
123  /** Set the dimensions of the matrix. In effect, append new empty
124         columns/rows to the matrix. A negative number for either dimension
125         means that that dimension doesn't change. Otherwise the new dimensions
126         MUST be at least as large as the current ones otherwise an exception
127         is thrown. */
128  virtual void setDimensions(int numrows, int numcols);
129  /// Just checks matrix valid - will say if dimensions not quite right if detail
130  void checkValid(bool detail) const;
131  //@}
132
133  /**@name Matrix times vector methods */
134  //@{
135  /** Return <code>y + A * scalar *x</code> in <code>y</code>.
136         @pre <code>x</code> must be of size <code>numColumns()</code>
137         @pre <code>y</code> must be of size <code>numRows()</code> */
138  virtual void times(double scalar,
139    const double *x, double *y) const;
140  /// And for scaling
141  virtual void times(double scalar,
142    const double *x, double *y,
143    const double *rowScale,
144    const double *columnScale) const;
145  /** Return <code>y + x * scalar * A</code> in <code>y</code>.
146         @pre <code>x</code> must be of size <code>numRows()</code>
147         @pre <code>y</code> must be of size <code>numColumns()</code> */
148  virtual void transposeTimes(double scalar,
149    const double *x, double *y) const;
150  /// And for scaling
151  virtual void transposeTimes(double scalar,
152    const double *x, double *y,
153    const double *rowScale,
154    const double *columnScale, double *spare = NULL) const;
155  /** Return <code>x * scalar * A + y</code> in <code>z</code>.
156     Can use y as temporary array (will be empty at end)
157     Note - If x packed mode - then z packed mode
158     Squashes small elements and knows about ClpSimplex */
159  virtual void transposeTimes(const ClpSimplex *model, double scalar,
160    const CoinIndexedVector *x,
161    CoinIndexedVector *y,
162    CoinIndexedVector *z) const;
163  /** Return <code>x * scalar * A + y</code> in <code>z</code>.
164     Can use y as temporary array (will be empty at end)
165     Note - If x packed mode - then z packed mode
166     Squashes small elements and knows about ClpSimplex.
167     This version uses row copy*/
168  virtual void transposeTimesByRow(const ClpSimplex *model, double scalar,
169    const CoinIndexedVector *x,
170    CoinIndexedVector *y,
171    CoinIndexedVector *z) const;
172  /** Return <code>x *A</code> in <code>z</code> but
173     just for indices in y.
174     Note - z always packed mode */
175  virtual void subsetTransposeTimes(const ClpSimplex *model,
176    const CoinIndexedVector *x,
177    const CoinIndexedVector *y,
178    CoinIndexedVector *z) const;
179  /** Returns true if can combine transposeTimes and subsetTransposeTimes
180         and if it would be faster */
181  virtual bool canCombine(const ClpSimplex *model,
182    const CoinIndexedVector *pi) const;
183  /** Updates two arrays for steepest and does devex weights
184         Returns nonzero if updates reduced cost and infeas -
185         new infeas in dj1 */
186  virtual int transposeTimes2(const ClpSimplex *model,
187    const CoinIndexedVector *pi1, CoinIndexedVector *dj1,
188    const CoinIndexedVector *pi2,
189    CoinIndexedVector *spare,
190    double *infeas, double *reducedCost,
191    double referenceIn, double devex,
192    // Array for exact devex to say what is in reference framework
193    unsigned int *reference,
194    double *weights, double scaleFactor);
195  /// Updates second array for steepest and does devex weights
196  virtual void subsetTimes2(const ClpSimplex *model,
197    CoinIndexedVector *dj1,
198    const CoinIndexedVector *pi2, CoinIndexedVector *dj2,
199    double referenceIn, double devex,
200    // Array for exact devex to say what is in reference framework
201    unsigned int *reference,
202    double *weights, double scaleFactor);
203  //@}
204
205  /**@name Other */
206  //@{
207  /// Return starts of +1s
208  inline CoinBigIndex *startPositive() const
209  {
210    return startPositive_;
211  }
212  /// Return starts of -1s
213  inline CoinBigIndex *startNegative() const
214  {
215    return startNegative_;
216  }
217  //@}
218
219  /**@name Constructors, destructor */
220  //@{
221  /** Default constructor. */
222  ClpPlusMinusOneMatrix();
223  /** Destructor */
224  virtual ~ClpPlusMinusOneMatrix();
225  //@}
226
227  /**@name Copy method */
228  //@{
229  /** The copy constructor. */
230  ClpPlusMinusOneMatrix(const ClpPlusMinusOneMatrix &);
231  /** The copy constructor from an CoinPlusMinusOneMatrix.
232         If not a valid matrix then getIndices will be NULL and
233         startPositive[0] will have number of +1,
234         startPositive[1] will have number of -1,
235         startPositive[2] will have number of others,
236     */
237  ClpPlusMinusOneMatrix(const CoinPackedMatrix &);
238  /// Constructor from arrays
239  ClpPlusMinusOneMatrix(int numberRows, int numberColumns,
240    bool columnOrdered, const int *indices,
241    const CoinBigIndex *startPositive, const CoinBigIndex *startNegative);
242  /** Subset constructor (without gaps).  Duplicates are allowed
243         and order is as given */
244  ClpPlusMinusOneMatrix(const ClpPlusMinusOneMatrix &wholeModel,
245    int numberRows, const int *whichRows,
246    int numberColumns, const int *whichColumns);
247
248  ClpPlusMinusOneMatrix &operator=(const ClpPlusMinusOneMatrix &);
249  /// Clone
250  virtual ClpMatrixBase *clone() const;
251  /** Subset clone (without gaps).  Duplicates are allowed
252         and order is as given */
253  virtual ClpMatrixBase *subsetClone(
254    int numberRows, const int *whichRows,
255    int numberColumns, const int *whichColumns) const;
256  /// pass in copy (object takes ownership)
257  void passInCopy(int numberRows, int numberColumns,
258    bool columnOrdered, int *indices,
259    CoinBigIndex *startPositive, CoinBigIndex *startNegative);
260  /// Says whether it can do partial pricing
261  virtual bool canDoPartialPricing() const;
262  /// Partial pricing
263  virtual void partialPricing(ClpSimplex *model, double start, double end,
264    int &bestSequence, int &numberWanted);
265  //@}
266
267protected:
268  /**@name Data members
269        The data members are protected to allow access for derived classes. */
270  //@{
271  /// For fake CoinPackedMatrix
272  mutable CoinPackedMatrix *matrix_;
273  mutable int *lengths_;
274  /// Start of +1's for each
275  CoinBigIndex *COIN_RESTRICT startPositive_;
276  /// Start of -1's for each
277  CoinBigIndex *COIN_RESTRICT startNegative_;
278  /// Data -1, then +1 rows in pairs (row==-1 if one entry)
279  int *COIN_RESTRICT indices_;
280  /// Number of rows
281  int numberRows_;
282  /// Number of columns
283  int numberColumns_;
284#ifdef CLP_PLUS_ONE_MATRIX
285  /** Other flags (could have columnOrdered_?)
286         1 bit - says just +1
287     */
288  mutable int otherFlags_;
289#endif
290  /// True if column ordered
291  bool columnOrdered_;
292
293  //@}
294};
295#if CLP_POOL_MATRIX
296/** This implements a matrix with few different coefficients
297    as derived from ClpMatrixBase.  This version only up to 65K rows
298*/
299#define CLP_POOL_SIZE 32 - CLP_POOL_MATRIX
300#if CLP_POOL_MATRIX == 16
301typedef struct {
302  unsigned short row_;
303  unsigned short pool_;
304} poolInfo;
305#else
306typedef struct {
307  unsigned int row_ : CLP_POOL_MATRIX;
308  unsigned short pool_ : CLP_POOL_SIZE;
309} poolInfo;
310#endif
311#include "ClpPackedMatrix.hpp"
312class ClpPoolMatrix : public ClpMatrixBase {
313
314public:
315  /**@name Useful methods */
316  //@{
317  /// Return a complete CoinPackedMatrix
318  virtual CoinPackedMatrix *getPackedMatrix() const;
319  /** Whether the packed matrix is column major ordered or not. */
320  virtual bool isColOrdered() const;
321  /** Number of entries in the packed matrix. */
322  virtual CoinBigIndex getNumElements() const;
323  /** Number of different entries in the packed matrix. */
324  inline int getNumDifferentElements() const
325  {
326    return numberDifferent_;
327  }
328  /** Number of columns. */
329  virtual int getNumCols() const
330  {
331    return numberColumns_;
332  }
333  /** Number of rows. */
334  virtual int getNumRows() const
335  {
336    return numberRows_;
337  }
338
339  /** A vector containing the elements in the packed matrix. Note that there
340      might be gaps in this list, entries that do not belong to any
341      major-dimension vector. To get the actual elements one should look at
342      this vector together with vectorStarts and vectorLengths. */
343  virtual const double *getElements() const;
344  /** A vector containing the minor indices of the elements in the packed
345          matrix. Note that there might be gaps in this list, entries that do not
346          belong to any major-dimension vector. To get the actual elements one
347          should look at this vector together with vectorStarts and
348          vectorLengths. */
349  virtual const int *getIndices() const;
350  // and for advanced use
351  int *getMutableIndices() const;
352
353  virtual const CoinBigIndex *getVectorStarts() const;
354  /** The lengths of the major-dimension vectors. */
355  virtual const int *getVectorLengths() const;
356  /** The length of a major-dimension vector. */
357  virtual int getVectorLength(int index) const;
358  /** Delete the columns whose indices are listed in <code>indDel</code>. */
359  virtual void deleteCols(const int numDel, const int *indDel);
360  /** Delete the rows whose indices are listed in <code>indDel</code>. */
361  virtual void deleteRows(const int numDel, const int *indDel);
362  /** Returns a new matrix in reverse order without gaps */
363  virtual ClpMatrixBase *reverseOrderedCopy() const;
364  /// Returns number of elements in column part of basis
365  virtual int countBasis(
366    const int *whichColumn,
367    int &numberColumnBasic);
368  /// Fills in column part of basis
369  virtual void fillBasis(ClpSimplex *model,
370    const int *whichColumn,
371    int &numberColumnBasic,
372    int *row, int *start,
373    int *rowCount, int *columnCount,
374    CoinFactorizationDouble *element);
375  /** Returns largest and smallest elements of both signs.
376         Largest refers to largest absolute value.
377     */
378  virtual void rangeOfElements(double &smallestNegative, double &largestNegative,
379    double &smallestPositive, double &largestPositive);
380  /** Unpacks a column into an CoinIndexedvector
381      */
382  virtual void unpack(const ClpSimplex *model, CoinIndexedVector *rowArray,
383    int column) const;
384  /** Unpacks a column into an CoinIndexedvector
385      ** in packed foramt
386         Note that model is NOT const.  Bounds and objective could
387         be modified if doing column generation (just for this variable) */
388  virtual void unpackPacked(ClpSimplex *model,
389    CoinIndexedVector *rowArray,
390    int column) const;
391  /** Adds multiple of a column into an CoinIndexedvector
392         You can use quickAdd to add to vector */
393  virtual void add(const ClpSimplex *model, CoinIndexedVector *rowArray,
394    int column, double multiplier) const;
395  /** Adds multiple of a column into an array */
396  virtual void add(const ClpSimplex *model, double *array,
397    int column, double multiplier) const;
398  /// Allow any parts of a created CoinMatrix to be deleted
399  virtual void releasePackedMatrix() const;
400  /** Set the dimensions of the matrix. In effect, append new empty
401         columns/rows to the matrix. A negative number for either dimension
402         means that that dimension doesn't change. Otherwise the new dimensions
403         MUST be at least as large as the current ones otherwise an exception
404         is thrown. */
405  virtual void setDimensions(int numrows, int numcols);
406  /// Just checks matrix valid - will say if dimensions not quite right if detail
407  void checkValid(bool detail) const;
408  //@}
409
410  /**@name Matrix times vector methods */
411  //@{
412  /** Return <code>y + A * scalar *x</code> in <code>y</code>.
413         @pre <code>x</code> must be of size <code>numColumns()</code>
414         @pre <code>y</code> must be of size <code>numRows()</code> */
415  virtual void times(double scalar,
416    const double *x, double *y) const;
417  /// And for scaling
418  virtual void times(double scalar,
419    const double *x, double *y,
420    const double *rowScale,
421    const double *columnScale) const;
422  /** Return <code>y + x * scalar * A</code> in <code>y</code>.
423         @pre <code>x</code> must be of size <code>numRows()</code>
424         @pre <code>y</code> must be of size <code>numColumns()</code> */
425  virtual void transposeTimes(double scalar,
426    const double *x, double *y) const;
427  /// And for scaling
428  virtual void transposeTimes(double scalar,
429    const double *x, double *y,
430    const double *rowScale,
431    const double *columnScale, double *spare = NULL) const;
432  /** Return <code>x * scalar * A + y</code> in <code>z</code>.
433     Can use y as temporary array (will be empty at end)
434     Note - If x packed mode - then z packed mode
435     Squashes small elements and knows about ClpSimplex */
436  virtual void transposeTimes(const ClpSimplex *model, double scalar,
437    const CoinIndexedVector *x,
438    CoinIndexedVector *y,
439    CoinIndexedVector *z) const;
440  /** Return <code>x * scalar * A + y</code> in <code>z</code>.
441     Can use y as temporary array (will be empty at end)
442     Note - If x packed mode - then z packed mode
443     Squashes small elements and knows about ClpSimplex.
444     This version uses row copy*/
445  virtual void transposeTimesByRow(const ClpSimplex *model, double scalar,
446    const CoinIndexedVector *x,
447    CoinIndexedVector *y,
448    CoinIndexedVector *z) const;
449  /** Return <code>x *A</code> in <code>z</code> but
450     just for indices in y.
451     Note - z always packed mode */
452  virtual void subsetTransposeTimes(const ClpSimplex *model,
453    const CoinIndexedVector *x,
454    const CoinIndexedVector *y,
455    CoinIndexedVector *z) const;
456  /** Returns true if can combine transposeTimes and subsetTransposeTimes
457         and if it would be faster */
458  virtual bool canCombine(const ClpSimplex *model,
459    const CoinIndexedVector *pi) const
460  {
461    return true;
462  }
463  /** Updates two arrays for steepest and does devex weights
464         Returns nonzero if updates reduced cost and infeas -
465         new infeas in dj1 */
466  virtual int transposeTimes2(const ClpSimplex *model,
467    const CoinIndexedVector *pi1, CoinIndexedVector *dj1,
468    const CoinIndexedVector *pi2,
469    CoinIndexedVector *spare,
470    double *infeas, double *reducedCost,
471    double referenceIn, double devex,
472    // Array for exact devex to say what is in reference framework
473    unsigned int *reference,
474    double *weights, double scaleFactor);
475  /// Updates second array for steepest and does devex weights
476  virtual void subsetTimes2(const ClpSimplex *model,
477    CoinIndexedVector *dj1,
478    const CoinIndexedVector *pi2, CoinIndexedVector *dj2,
479    double referenceIn, double devex,
480    // Array for exact devex to say what is in reference framework
481    unsigned int *reference,
482    double *weights, double scaleFactor);
483  //@}
484
485  /**@name Other */
486  //@{
487  /// Return column starts
488  inline CoinBigIndex *columnStart() const
489  {
490    return columnStart_;
491  }
492  //@}
493
494  /**@name Constructors, destructor */
495  //@{
496  /** Default constructor. */
497  ClpPoolMatrix();
498  /** Destructor */
499  virtual ~ClpPoolMatrix();
500  //@}
501
502  /**@name Copy method */
503  //@{
504  /** The copy constructor. */
505  ClpPoolMatrix(const ClpPoolMatrix &);
506  /** The copy constructor from an CoinPoolMatrix.
507     */
508  ClpPoolMatrix(const CoinPackedMatrix &);
509  /// Constructor from arrays
510  ClpPoolMatrix(int numberRows, int numberColumns,
511    const int *indices, const double *elements,
512    const CoinBigIndex *columnStart);
513  /// Constructor from arrays - handing over ownership
514  ClpPoolMatrix(int numberColumns, CoinBigIndex *columnStart,
515    poolInfo *stuff, double *elements);
516  /** Subset constructor (without gaps).  Duplicates are allowed
517         and order is as given */
518  ClpPoolMatrix(const ClpPoolMatrix &wholeModel,
519    int numberRows, const int *whichRows,
520    int numberColumns, const int *whichColumns);
521
522  ClpPoolMatrix &operator=(const ClpPoolMatrix &);
523  /// Clone
524  virtual ClpMatrixBase *clone() const;
525  /** Subset clone (without gaps).  Duplicates are allowed
526         and order is as given */
527  virtual ClpMatrixBase *subsetClone(
528    int numberRows, const int *whichRows,
529    int numberColumns, const int *whichColumns) const;
530  /// Says whether it can do partial pricing
531  virtual bool canDoPartialPricing() const;
532  /// Partial pricing
533  virtual void partialPricing(ClpSimplex *model, double start, double end,
534    int &bestSequence, int &numberWanted);
535  //@}
536
537protected:
538  /// Create matrix_
539  ClpPackedMatrix *createMatrix() const;
540  /**@name Data members
541        The data members are protected to allow access for derived classes. */
542  //@{
543  /// For fake ClpPackedMatrix
544  mutable ClpPackedMatrix *matrix_;
545  mutable int *lengths_;
546  /// Unique values
547  double *COIN_RESTRICT elements_;
548  /// Column starts
549  CoinBigIndex *COIN_RESTRICT columnStart_;
550  /// Rows and values
551  poolInfo *COIN_RESTRICT stuff_;
552  /// Number of rows
553  int numberRows_;
554  /// Number of columns
555  int numberColumns_;
556  /// Number of different elements
557  int numberDifferent_;
558
559  //@}
560};
561#endif
562#endif
563
564/* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
565*/
Note: See TracBrowser for help on using the repository browser.