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

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

formatting

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 15.5 KB
Line 
1/* $Id: ClpFactorization.hpp 2385 2019-01-06 19:43:06Z stefan $ */
2// Copyright (C) 2002, 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 ClpFactorization_H
7#define ClpFactorization_H
8
9#include "CoinPragma.hpp"
10
11#include "CoinFactorization.hpp"
12class ClpMatrixBase;
13class ClpSimplex;
14class ClpNetworkBasis;
15class CoinOtherFactorization;
16#ifndef CLP_MULTIPLE_FACTORIZATIONS
17#define CLP_MULTIPLE_FACTORIZATIONS 4
18#endif
19#ifdef CLP_MULTIPLE_FACTORIZATIONS
20#include "CoinDenseFactorization.hpp"
21#include "ClpSimplex.hpp"
22#endif
23#ifndef COIN_FAST_CODE
24#define COIN_FAST_CODE
25#endif
26#ifndef CLP_FACTORIZATION_NEW_TIMING
27#define CLP_FACTORIZATION_NEW_TIMING 1
28#endif
29
30/** This just implements CoinFactorization when an ClpMatrixBase object
31    is passed.  If a network then has a dummy CoinFactorization and
32    a genuine ClpNetworkBasis object
33*/
34class ClpFactorization
35#ifndef CLP_MULTIPLE_FACTORIZATIONS
36  : public CoinFactorization
37#endif
38{
39
40  //friend class CoinFactorization;
41
42public:
43  /**@name factorization */
44  //@{
45  /** When part of LP - given by basic variables.
46     Actually does factorization.
47     Arrays passed in have non negative value to say basic.
48     If status is okay, basic variables have pivot row - this is only needed
49     if increasingRows_ >1.
50     Allows scaling
51     If status is singular, then basic variables have pivot row
52     and ones thrown out have -1
53     returns 0 -okay, -1 singular, -2 too many in basis, -99 memory */
54  int factorize(ClpSimplex *model, int solveType, bool valuesPass);
55  //@}
56
57  /**@name Constructors, destructor */
58  //@{
59  /** Default constructor. */
60  ClpFactorization();
61  /** Destructor */
62  ~ClpFactorization();
63  //@}
64
65  /**@name Copy method */
66  //@{
67  /** The copy constructor from an CoinFactorization. */
68  ClpFactorization(const CoinFactorization &);
69  /** The copy constructor. */
70  ClpFactorization(const ClpFactorization &, int denseIfSmaller = 0);
71#ifdef CLP_MULTIPLE_FACTORIZATIONS
72  /** The copy constructor from an CoinOtherFactorization. */
73  ClpFactorization(const CoinOtherFactorization &);
74#endif
75  ClpFactorization &operator=(const ClpFactorization &);
76  //@}
77
78  /*  **** below here is so can use networkish basis */
79  /**@name rank one updates which do exist */
80  //@{
81
82  /** Replaces one Column to basis,
83      returns 0=OK, 1=Probably OK, 2=singular, 3=no room
84         If checkBeforeModifying is true will do all accuracy checks
85         before modifying factorization.  Whether to set this depends on
86         speed considerations.  You could just do this on first iteration
87         after factorization and thereafter re-factorize
88      partial update already in U */
89  int replaceColumn(const ClpSimplex *model,
90    CoinIndexedVector *regionSparse,
91    CoinIndexedVector *tableauColumn,
92    int pivotRow,
93    double pivotCheck,
94    bool checkBeforeModifying = false,
95    double acceptablePivot = 1.0e-8);
96#if ABOCA_LITE_FACTORIZATION
97  /// Does btranU part of replaceColumn (skipping entries)
98  void replaceColumn1(CoinIndexedVector *regionSparse, int pivotRow);
99  /// Does replaceColumn - having already done btranU
100  int replaceColumn2(CoinIndexedVector *regionSparse,
101    int pivotRow,
102    double pivotCheck);
103#endif
104  //@}
105
106  /**@name various uses of factorization (return code number elements)
107      which user may want to know about */
108  //@{
109  /** Updates one column (FTRAN) from region2
110         Tries to do FT update
111         number returned is negative if no room
112         region1 starts as zero and is zero at end */
113  int updateColumnFT(CoinIndexedVector *regionSparse,
114    CoinIndexedVector *regionSparse2);
115  /** Updates one column (FTRAN) from region2
116         region1 starts as zero and is zero at end */
117  int updateColumn(CoinIndexedVector *regionSparse,
118    CoinIndexedVector *regionSparse2,
119    bool noPermute = false) const;
120  /** Updates one column (FTRAN) from region2
121         Tries to do FT update
122         number returned is negative if no room.
123         Also updates region3
124         region1 starts as zero and is zero at end */
125  int updateTwoColumnsFT(CoinIndexedVector *regionSparse1,
126    CoinIndexedVector *regionSparse2,
127    CoinIndexedVector *regionSparse3,
128    bool noPermuteRegion3 = false);
129  /// For debug (no statistics update)
130  int updateColumnForDebug(CoinIndexedVector *regionSparse,
131    CoinIndexedVector *regionSparse2,
132    bool noPermute = false) const;
133  /** Updates one column (BTRAN) from region2
134         region1 starts as zero and is zero at end */
135  int updateColumnTranspose(CoinIndexedVector *regionSparse,
136    CoinIndexedVector *regionSparse2) const;
137  /** Updates two columns (BTRAN) from regionSparse2 and 3
138         regionSparse starts as zero and is zero at end
139         Note - if regionSparse2 packed on input - will be packed on output - same for 3
140     */
141  void updateTwoColumnsTranspose(CoinIndexedVector *regionSparse,
142    CoinIndexedVector *regionSparse2,
143    CoinIndexedVector *regionSparse3) const;
144  //@}
145#ifdef CLP_MULTIPLE_FACTORIZATIONS
146  /**@name Lifted from CoinFactorization */
147  //@{
148  /// Total number of elements in factorization
149  inline int numberElements() const
150  {
151    if (coinFactorizationA_)
152      return coinFactorizationA_->numberElements();
153    else
154      return coinFactorizationB_->numberElements();
155  }
156  /// Returns address of permute region
157  inline int *permute() const
158  {
159    if (coinFactorizationA_)
160      return coinFactorizationA_->permute();
161    else
162      return coinFactorizationB_->permute();
163  }
164  /// Returns address of pivotColumn region (also used for permuting)
165  inline int *pivotColumn() const
166  {
167    if (coinFactorizationA_)
168      return coinFactorizationA_->pivotColumn();
169    else
170      return coinFactorizationB_->permute();
171  }
172  /// Maximum number of pivots between factorizations
173  inline int maximumPivots() const
174  {
175    if (coinFactorizationA_)
176      return coinFactorizationA_->maximumPivots();
177    else
178      return coinFactorizationB_->maximumPivots();
179  }
180  /// Set maximum number of pivots between factorizations
181  inline void maximumPivots(int value)
182  {
183    if (coinFactorizationA_)
184      coinFactorizationA_->maximumPivots(value);
185    else
186      coinFactorizationB_->maximumPivots(value);
187  }
188  /// Returns number of pivots since factorization
189  inline int pivots() const
190  {
191    if (coinFactorizationA_)
192      return coinFactorizationA_->pivots();
193    else
194      return coinFactorizationB_->pivots();
195  }
196  /// Whether larger areas needed
197  inline double areaFactor() const
198  {
199    if (coinFactorizationA_)
200      return coinFactorizationA_->areaFactor();
201    else
202      return 0.0;
203  }
204  /// Set whether larger areas needed
205  inline void areaFactor(double value)
206  {
207    if (coinFactorizationA_)
208      coinFactorizationA_->areaFactor(value);
209  }
210  /// Zero tolerance
211  inline double zeroTolerance() const
212  {
213    if (coinFactorizationA_)
214      return coinFactorizationA_->zeroTolerance();
215    else
216      return coinFactorizationB_->zeroTolerance();
217  }
218  /// Set zero tolerance
219  inline void zeroTolerance(double value)
220  {
221    if (coinFactorizationA_)
222      coinFactorizationA_->zeroTolerance(value);
223    else
224      coinFactorizationB_->zeroTolerance(value);
225  }
226  /// Set tolerances to safer of existing and given
227  void saferTolerances(double zeroTolerance, double pivotTolerance);
228  /**  get sparse threshold */
229  inline int sparseThreshold() const
230  {
231    if (coinFactorizationA_)
232      return coinFactorizationA_->sparseThreshold();
233    else
234      return 0;
235  }
236  /**  Set sparse threshold */
237  inline void sparseThreshold(int value)
238  {
239    if (coinFactorizationA_)
240      coinFactorizationA_->sparseThreshold(value);
241  }
242  /// Returns status
243  inline int status() const
244  {
245    if (coinFactorizationA_)
246      return coinFactorizationA_->status();
247    else
248      return coinFactorizationB_->status();
249  }
250  /// Sets status
251  inline void setStatus(int value)
252  {
253    if (coinFactorizationA_)
254      coinFactorizationA_->setStatus(value);
255    else
256      coinFactorizationB_->setStatus(value);
257  }
258  /// Returns number of dense rows
259  inline int numberDense() const
260  {
261    if (coinFactorizationA_)
262      return coinFactorizationA_->numberDense();
263    else
264      return 0;
265  }
266#if 1
267  /// Returns number in U area
268  inline CoinBigIndex numberElementsU() const
269  {
270    if (coinFactorizationA_)
271      return coinFactorizationA_->numberElementsU();
272    else
273      return -1;
274  }
275  /// Returns number in L area
276  inline CoinBigIndex numberElementsL() const
277  {
278    if (coinFactorizationA_)
279      return coinFactorizationA_->numberElementsL();
280    else
281      return -1;
282  }
283  /// Returns number in R area
284  inline CoinBigIndex numberElementsR() const
285  {
286    if (coinFactorizationA_)
287      return coinFactorizationA_->numberElementsR();
288    else
289      return 0;
290  }
291#endif
292  bool timeToRefactorize() const;
293#if CLP_FACTORIZATION_NEW_TIMING > 1
294  void statsRefactor(char when) const;
295#endif
296  /// Level of detail of messages
297  inline int messageLevel() const
298  {
299    if (coinFactorizationA_)
300      return coinFactorizationA_->messageLevel();
301    else
302      return 1;
303  }
304  /// Set level of detail of messages
305  inline void messageLevel(int value)
306  {
307    if (coinFactorizationA_)
308      coinFactorizationA_->messageLevel(value);
309  }
310  /// Get rid of all memory
311  inline void clearArrays()
312  {
313    if (coinFactorizationA_)
314      coinFactorizationA_->clearArrays();
315    else if (coinFactorizationB_)
316      coinFactorizationB_->clearArrays();
317  }
318  /// Number of Rows after factorization
319  inline int numberRows() const
320  {
321    if (coinFactorizationA_)
322      return coinFactorizationA_->numberRows();
323    else
324      return coinFactorizationB_->numberRows();
325  }
326  /// Gets dense threshold
327  inline int denseThreshold() const
328  {
329    if (coinFactorizationA_)
330      return coinFactorizationA_->denseThreshold();
331    else
332      return 0;
333  }
334  /// Sets dense threshold
335  inline void setDenseThreshold(int value)
336  {
337    if (coinFactorizationA_)
338      coinFactorizationA_->setDenseThreshold(value);
339  }
340  /// Pivot tolerance
341  inline double pivotTolerance() const
342  {
343    if (coinFactorizationA_)
344      return coinFactorizationA_->pivotTolerance();
345    else if (coinFactorizationB_)
346      return coinFactorizationB_->pivotTolerance();
347    return 1.0e-8;
348  }
349  /// Set pivot tolerance
350  inline void pivotTolerance(double value)
351  {
352    if (coinFactorizationA_)
353      coinFactorizationA_->pivotTolerance(value);
354    else if (coinFactorizationB_)
355      coinFactorizationB_->pivotTolerance(value);
356  }
357  /// Allows change of pivot accuracy check 1.0 == none >1.0 relaxed
358  inline void relaxAccuracyCheck(double value)
359  {
360    if (coinFactorizationA_)
361      coinFactorizationA_->relaxAccuracyCheck(value);
362  }
363  /** Array persistence flag
364         If 0 then as now (delete/new)
365         1 then only do arrays if bigger needed
366         2 as 1 but give a bit extra if bigger needed
367     */
368  inline int persistenceFlag() const
369  {
370    if (coinFactorizationA_)
371      return coinFactorizationA_->persistenceFlag();
372    else
373      return 0;
374  }
375  inline void setPersistenceFlag(int value)
376  {
377    if (coinFactorizationA_)
378      coinFactorizationA_->setPersistenceFlag(value);
379  }
380  /// Delete all stuff (leaves as after CoinFactorization())
381  inline void almostDestructor()
382  {
383    if (coinFactorizationA_)
384      coinFactorizationA_->almostDestructor();
385    else if (coinFactorizationB_)
386      coinFactorizationB_->clearArrays();
387  }
388  /// Returns areaFactor but adjusted for dense
389  inline double adjustedAreaFactor() const
390  {
391    if (coinFactorizationA_)
392      return coinFactorizationA_->adjustedAreaFactor();
393    else
394      return 0.0;
395  }
396  inline void setBiasLU(int value)
397  {
398    if (coinFactorizationA_)
399      coinFactorizationA_->setBiasLU(value);
400  }
401  /// true if Forrest Tomlin update, false if PFI
402  inline void setForrestTomlin(bool value)
403  {
404    if (coinFactorizationA_)
405      coinFactorizationA_->setForrestTomlin(value);
406  }
407  /// Sets default values
408  inline void setDefaultValues()
409  {
410    if (coinFactorizationA_) {
411      // row activities have negative sign
412#ifndef COIN_FAST_CODE
413      coinFactorizationA_->slackValue(-1.0);
414#endif
415      coinFactorizationA_->zeroTolerance(1.0e-13);
416    }
417  }
418  /// If nonzero force use of 1,dense 2,small 3,osl
419  void forceOtherFactorization(int which);
420  /// Get switch to osl if number rows <= this
421  inline int goOslThreshold() const
422  {
423    return goOslThreshold_;
424  }
425  /// Set switch to osl if number rows <= this
426  inline void setGoOslThreshold(int value)
427  {
428    goOslThreshold_ = value;
429  }
430  /// Get switch to dense if number rows <= this
431  inline int goDenseThreshold() const
432  {
433    return goDenseThreshold_;
434  }
435  /// Set switch to dense if number rows <= this
436  inline void setGoDenseThreshold(int value)
437  {
438    goDenseThreshold_ = value;
439  }
440  /// Get switch to small if number rows <= this
441  inline int goSmallThreshold() const
442  {
443    return goSmallThreshold_;
444  }
445  /// Set switch to small if number rows <= this
446  inline void setGoSmallThreshold(int value)
447  {
448    goSmallThreshold_ = value;
449  }
450  /// Go over to dense or small code if small enough
451  void goDenseOrSmall(int numberRows);
452  /// Sets factorization
453  void setFactorization(ClpFactorization &factorization);
454  /// Return 1 if dense code
455  inline int isDenseOrSmall() const
456  {
457    return coinFactorizationB_ ? 1 : 0;
458  }
459  /// Return coinFactorizationA_
460  inline CoinFactorization *coinFactorization() const
461  {
462    return coinFactorizationA_;
463  }
464#else
465  inline bool timeToRefactorize() const
466  {
467    return (pivots() * 3 > maximumPivots() * 2 && numberElementsR() * 3 > (numberElementsL() + numberElementsU()) * 2 + 1000 && !numberDense());
468  }
469  /// Sets default values
470  inline void setDefaultValues()
471  {
472    // row activities have negative sign
473#ifndef COIN_FAST_CODE
474    slackValue(-1.0);
475#endif
476    zeroTolerance(1.0e-13);
477  }
478  /// Go over to dense code
479  inline void goDense() {}
480#endif
481  //@}
482
483  /**@name other stuff */
484  //@{
485  /** makes a row copy of L for speed and to allow very sparse problems */
486  void goSparse();
487  /// Cleans up i.e. gets rid of network basis
488  void cleanUp();
489  /// Says whether to redo pivot order
490  bool needToReorder() const;
491  /// To switch statistics on or off
492  inline void doStatistics(bool trueFalse) const
493  {
494    doStatistics_ = trueFalse;
495  }
496#ifndef SLIM_CLP
497  /// Says if a network basis
498  inline bool networkBasis() const
499  {
500    return (networkBasis_ != NULL);
501  }
502#else
503  /// Says if a network basis
504  inline bool networkBasis() const
505  {
506    return false;
507  }
508#endif
509  /// Fills weighted row list
510  void getWeights(int *weights) const;
511  //@}
512
513  ////////////////// data //////////////////
514private:
515  /**@name data */
516  //@{
517  /// Pointer to network basis
518#ifndef SLIM_CLP
519  ClpNetworkBasis *networkBasis_;
520#endif
521#ifdef CLP_MULTIPLE_FACTORIZATIONS
522  /// Pointer to CoinFactorization
523  CoinFactorization *coinFactorizationA_;
524  /// Pointer to CoinOtherFactorization
525  CoinOtherFactorization *coinFactorizationB_;
526#ifdef CLP_REUSE_ETAS
527  /// Pointer to model
528  ClpSimplex *model_;
529#endif
530  /// If nonzero force use of 1,dense 2,small 3,osl
531  int forceB_;
532  /// Switch to osl if number rows <= this
533  int goOslThreshold_;
534  /// Switch to small if number rows <= this
535  int goSmallThreshold_;
536  /// Switch to dense if number rows <= this
537  int goDenseThreshold_;
538#endif
539#ifdef CLP_FACTORIZATION_NEW_TIMING
540  /// For guessing when to re-factorize
541  mutable double shortestAverage_;
542  mutable double totalInR_;
543  mutable double totalInIncreasingU_;
544  mutable int endLengthU_;
545  mutable int lastNumberPivots_;
546  mutable int effectiveStartNumberU_;
547#endif
548  /// To switch statistics on or off
549  mutable bool doStatistics_;
550  //@}
551};
552
553#endif
554
555/* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
556*/
Note: See TracBrowser for help on using the repository browser.