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

Last change on this file since 1371 was 1371, checked in by forrest, 11 years ago

changes to try and make faster

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 14.0 KB
Line 
1/* $Id: ClpFactorization.hpp 1371 2009-06-12 16:29:04Z forrest $ */
2// Copyright (C) 2002, International Business Machines
3// Corporation and others.  All Rights Reserved.
4#ifndef ClpFactorization_H
5#define ClpFactorization_H
6
7
8#include "CoinPragma.hpp"
9
10#include "CoinFactorization.hpp"
11class ClpMatrixBase;
12class ClpSimplex;
13class ClpNetworkBasis;
14#ifndef CLP_MULTIPLE_FACTORIZATIONS
15#ifdef CLP_OSL
16#define CLP_MULTIPLE_FACTORIZATIONS 4
17#else
18#define CLP_MULTIPLE_FACTORIZATIONS 3
19#endif
20#endif   
21#if CLP_MULTIPLE_FACTORIZATIONS == 1
22#include "CoinDenseFactorization.hpp"
23typedef CoinDenseFactorization CoinSmallFactorization;
24typedef CoinOslFactorization CoinSmallFactorization;
25#elif CLP_MULTIPLE_FACTORIZATIONS == 2
26#include "CoinSimpFactorization.hpp"
27typedef CoinSimpFactorization CoinSmallFactorization;
28typedef CoinOslFactorization CoinSmallFactorization;
29#elif CLP_MULTIPLE_FACTORIZATIONS == 3
30#include "CoinDenseFactorization.hpp"
31#include "CoinSimpFactorization.hpp"
32#define CoinOslFactorization CoinDenseFactorization
33#elif CLP_MULTIPLE_FACTORIZATIONS == 4
34#include "CoinDenseFactorization.hpp"
35#include "CoinSimpFactorization.hpp"
36#include "CoinOslFactorization.hpp"
37#endif
38
39/** This just implements CoinFactorization when an ClpMatrixBase object
40    is passed.  If a network then has a dummy CoinFactorization and
41    a genuine ClpNetworkBasis object
42*/
43class ClpFactorization 
44#ifndef CLP_MULTIPLE_FACTORIZATIONS   
45  : public CoinFactorization
46#endif
47{
48
49  //friend class CoinFactorization;
50 
51public:
52  /**@name factorization */
53   //@{
54  /** When part of LP - given by basic variables.
55  Actually does factorization.
56  Arrays passed in have non negative value to say basic.
57  If status is okay, basic variables have pivot row - this is only needed
58  if increasingRows_ >1.
59  Allows scaling
60  If status is singular, then basic variables have pivot row
61  and ones thrown out have -1
62  returns 0 -okay, -1 singular, -2 too many in basis, -99 memory */
63  int factorize (ClpSimplex * model,int solveType, bool valuesPass);
64   //@}
65
66
67  /**@name Constructors, destructor */
68   //@{
69   /** Default constructor. */
70   ClpFactorization();
71   /** Destructor */
72   ~ClpFactorization();
73   //@}
74
75   /**@name Copy method */
76   //@{
77   /** The copy constructor from an CoinFactorization. */
78   ClpFactorization(const CoinFactorization&);
79   /** The copy constructor. */
80  ClpFactorization(const ClpFactorization&,int denseIfSmaller=0);
81#ifdef CLP_MULTIPLE_FACTORIZATIONS   
82   /** The copy constructor from an CoinSmallFactorization. */
83   ClpFactorization(const CoinSmallFactorization&);
84#endif
85   ClpFactorization& operator=(const ClpFactorization&);
86   //@}
87   
88  /*  **** below here is so can use networkish basis */
89  /**@name rank one updates which do exist */
90  //@{
91
92  /** Replaces one Column to basis,
93   returns 0=OK, 1=Probably OK, 2=singular, 3=no room
94      If checkBeforeModifying is true will do all accuracy checks
95      before modifying factorization.  Whether to set this depends on
96      speed considerations.  You could just do this on first iteration
97      after factorization and thereafter re-factorize
98   partial update already in U */
99  int replaceColumn ( const ClpSimplex * model,
100                      CoinIndexedVector * regionSparse,
101                      CoinIndexedVector * tableauColumn,
102                      int pivotRow,
103                      double pivotCheck ,
104                      bool checkBeforeModifying=false);
105  //@}
106
107  /**@name various uses of factorization (return code number elements)
108   which user may want to know about */
109  //@{
110  /** Updates one column (FTRAN) from region2
111      Tries to do FT update
112      number returned is negative if no room
113      region1 starts as zero and is zero at end */
114  int updateColumnFT ( CoinIndexedVector * regionSparse,
115                       CoinIndexedVector * regionSparse2);
116  /** Updates one column (FTRAN) from region2
117      region1 starts as zero and is zero at end */
118  int updateColumn ( CoinIndexedVector * regionSparse,
119                     CoinIndexedVector * regionSparse2,
120                     bool noPermute=false) const;
121  /** Updates one column (FTRAN) from region2
122      Tries to do FT update
123      number returned is negative if no room.
124      Also updates region3
125      region1 starts as zero and is zero at end */
126  int updateTwoColumnsFT ( CoinIndexedVector * regionSparse1,
127                           CoinIndexedVector * regionSparse2,
128                           CoinIndexedVector * regionSparse3,
129                           bool noPermuteRegion3=false) ;
130  /// For debug (no statistics update)
131  int updateColumnForDebug ( CoinIndexedVector * regionSparse,
132                     CoinIndexedVector * regionSparse2,
133                     bool noPermute=false) const;
134  /** Updates one column (BTRAN) from region2
135      region1 starts as zero and is zero at end */
136  int updateColumnTranspose ( CoinIndexedVector * regionSparse,
137                              CoinIndexedVector * regionSparse2) const;
138  //@}
139#ifdef CLP_MULTIPLE_FACTORIZATIONS   
140  /**@name Lifted from CoinFactorization */
141  //@{
142  /// Total number of elements in factorization
143  inline int numberElements (  ) const {
144    if (coinFactorizationA_) return coinFactorizationA_->numberElements(); else return coinFactorizationB_->numberElements() ;
145  }
146  /// Returns address of permute region
147  inline int *permute (  ) const {
148    if (coinFactorizationA_) return coinFactorizationA_->permute(); else return coinFactorizationB_->permute() ;
149  }
150  /// Returns address of pivotColumn region (also used for permuting)
151  inline int *pivotColumn (  ) const {
152    if (coinFactorizationA_) return coinFactorizationA_->pivotColumn(); else return coinFactorizationB_->permute() ;
153  }
154  /// Maximum number of pivots between factorizations
155  inline int maximumPivots (  ) const {
156    if (coinFactorizationA_) return coinFactorizationA_->maximumPivots();  else return coinFactorizationB_->maximumPivots() ;
157  }
158  /// Set maximum number of pivots between factorizations
159  inline void maximumPivots (  int value) {
160    if (coinFactorizationA_) coinFactorizationA_->maximumPivots(value); else coinFactorizationB_->maximumPivots(value);
161  }
162  /// Returns number of pivots since factorization
163  inline int pivots (  ) const {
164    if (coinFactorizationA_) return coinFactorizationA_->pivots(); else return coinFactorizationB_->pivots() ;
165  }
166  /// Whether larger areas needed
167  inline double areaFactor (  ) const {
168    if (coinFactorizationA_) return coinFactorizationA_->areaFactor(); else return 0.0 ;
169  }
170  /// Set whether larger areas needed
171  inline void areaFactor ( double value) {
172    if (coinFactorizationA_) coinFactorizationA_->areaFactor(value); 
173  }
174  /// Zero tolerance
175  inline double zeroTolerance (  ) const {
176    if (coinFactorizationA_) return coinFactorizationA_->zeroTolerance();  else return coinFactorizationB_->zeroTolerance() ;
177  }
178  /// Set zero tolerance
179  inline void zeroTolerance (  double value) {
180    if (coinFactorizationA_) coinFactorizationA_->zeroTolerance(value); else coinFactorizationB_->zeroTolerance(value);
181  }
182  /// Set tolerances to safer of existing and given
183  void saferTolerances (  double zeroTolerance, double pivotTolerance);
184  /**  get sparse threshold */
185  inline int sparseThreshold ( ) const
186  { if (coinFactorizationA_) return coinFactorizationA_->sparseThreshold(); else return 0 ;}
187  /**  Set sparse threshold */
188  inline void sparseThreshold ( int value) 
189  { if (coinFactorizationA_) coinFactorizationA_->sparseThreshold(value); }
190  /// Returns status
191  inline int status (  ) const {
192    if (coinFactorizationA_) return coinFactorizationA_->status(); else return coinFactorizationB_->status() ;
193  }
194  /// Sets status
195  inline void setStatus (  int value) {
196    if (coinFactorizationA_) coinFactorizationA_->setStatus(value); else coinFactorizationB_->setStatus(value) ;
197  }
198  /// Returns number of dense rows
199  inline int numberDense() const
200  { if (coinFactorizationA_) return coinFactorizationA_->numberDense(); else return 0 ;}
201#if 1
202  /// Returns number in U area
203  inline CoinBigIndex numberElementsU (  ) const {
204    if (coinFactorizationA_) return coinFactorizationA_->numberElementsU(); else return -1 ;
205  }
206  /// Returns number in L area
207  inline CoinBigIndex numberElementsL (  ) const {
208    if (coinFactorizationA_) return coinFactorizationA_->numberElementsL(); else return -1 ;
209  }
210  /// Returns number in R area
211  inline CoinBigIndex numberElementsR (  ) const {
212    if (coinFactorizationA_) return coinFactorizationA_->numberElementsR(); else return 0 ;
213  }
214#endif
215  inline bool timeToRefactorize() const
216  {
217    if (coinFactorizationA_) {
218      return (coinFactorizationA_->pivots()*3>coinFactorizationA_->maximumPivots()*2&&
219              coinFactorizationA_->numberElementsR()*3>(coinFactorizationA_->numberElementsL()+
220                                                        coinFactorizationA_->numberElementsU())*2+1000&&
221              !coinFactorizationA_->numberDense());
222    } else {
223      return coinFactorizationB_->pivots()>coinFactorizationB_->numberRows()/2.45+20;
224    }
225  }
226  /// Level of detail of messages
227  inline int messageLevel (  ) const {
228    if (coinFactorizationA_) return coinFactorizationA_->messageLevel();  else return 0 ;
229  }
230  /// Set level of detail of messages
231  inline void messageLevel (  int value) {
232    if (coinFactorizationA_) coinFactorizationA_->messageLevel(value);
233  }
234  /// Get rid of all memory
235  inline void clearArrays()
236  { if (coinFactorizationA_) coinFactorizationA_->clearArrays();}
237  /// Number of Rows after factorization
238  inline int numberRows (  ) const {
239    if (coinFactorizationA_) return coinFactorizationA_->numberRows(); else return coinFactorizationB_->numberRows() ;
240  }
241  /// Gets dense threshold
242  inline int denseThreshold() const 
243  { if (coinFactorizationA_) return coinFactorizationA_->denseThreshold(); else return 0 ;}
244  /// Sets dense threshold
245  inline void setDenseThreshold(int value)
246  { if (coinFactorizationA_) coinFactorizationA_->setDenseThreshold(value);}
247  /// Pivot tolerance
248  inline double pivotTolerance (  ) const {
249    if (coinFactorizationA_) return coinFactorizationA_->pivotTolerance();  else return 1.0e-8 ;
250  }
251  /// Set pivot tolerance
252  inline void pivotTolerance (  double value) {
253    if (coinFactorizationA_) coinFactorizationA_->pivotTolerance(value);
254  }
255  /// Allows change of pivot accuracy check 1.0 == none >1.0 relaxed
256  inline void relaxAccuracyCheck(double value)
257  { if (coinFactorizationA_) coinFactorizationA_->relaxAccuracyCheck(value);}
258  /** Array persistence flag
259      If 0 then as now (delete/new)
260      1 then only do arrays if bigger needed
261      2 as 1 but give a bit extra if bigger needed
262  */
263  inline int persistenceFlag() const
264  { if (coinFactorizationA_) return coinFactorizationA_->persistenceFlag(); else return 0 ;}
265  inline void setPersistenceFlag(int value)
266  { if (coinFactorizationA_) coinFactorizationA_->setPersistenceFlag(value);}
267  /// Delete all stuff (leaves as after CoinFactorization())
268  inline void almostDestructor()
269  { if (coinFactorizationA_) coinFactorizationA_->almostDestructor(); }
270  /// Returns areaFactor but adjusted for dense
271  inline double adjustedAreaFactor() const
272  { if (coinFactorizationA_) return coinFactorizationA_->adjustedAreaFactor(); else return 0.0 ; }
273  inline void setBiasLU(int value)
274  { if (coinFactorizationA_) coinFactorizationA_->setBiasLU(value);}
275  /// true if Forrest Tomlin update, false if PFI
276  inline void setForrestTomlin(bool value)
277  { if (coinFactorizationA_) coinFactorizationA_->setForrestTomlin(value);}
278  /// Sets default values
279  inline void setDefaultValues() {
280    if (coinFactorizationA_) {
281      // row activities have negative sign
282#ifndef COIN_FAST_CODE
283      coinFactorizationA_->slackValue(-1.0);
284#endif
285      coinFactorizationA_->zeroTolerance(1.0e-13);
286    }
287  }
288  /// If nonzero force use of 1,dense 2,small 3,osl
289  void forceOtherFactorization(int which);
290  /// Get switch to osl if number rows <= this
291  inline int goOslThreshold() const
292  { return goOslThreshold_;}
293  /// Set switch to osl if number rows <= this
294  inline void setGoOslThreshold(int value)
295  { goOslThreshold_ = value;}
296  /// Get switch to dense if number rows <= this
297  inline int goDenseThreshold() const
298  { return goDenseThreshold_;}
299  /// Set switch to dense if number rows <= this
300  inline void setGoDenseThreshold(int value)
301  { goDenseThreshold_ = value;}
302  /// Get switch to small if number rows <= this
303  inline int goSmallThreshold() const
304  { return goSmallThreshold_;}
305  /// Set switch to small if number rows <= this
306  inline void setGoSmallThreshold(int value)
307  { goSmallThreshold_ = value;}
308  /// Go over to dense or small code if small enough
309  void goDenseOrSmall(int numberRows) ;
310  /// Sets factorization
311  void setFactorization(ClpFactorization & factorization);
312  /// Return 1 if dense code
313  inline int isDenseOrSmall() const
314  { return coinFactorizationB_ ? 1 : 0;}
315#else
316  inline bool timeToRefactorize() const
317  {
318    return (pivots()*3>maximumPivots()*2&&
319            numberElementsR()*3>(numberElementsL()+numberElementsU())*2+1000&&
320            !numberDense());
321  }
322  /// Sets default values
323  inline void setDefaultValues() {
324    // row activities have negative sign
325#ifndef COIN_FAST_CODE
326    slackValue(-1.0);
327#endif
328    zeroTolerance(1.0e-13);
329  }
330  /// Go over to dense code
331  inline void goDense() {}
332#endif
333  //@}
334   
335  /**@name other stuff */
336  //@{
337  /** makes a row copy of L for speed and to allow very sparse problems */
338  void goSparse();
339  /// Cleans up i.e. gets rid of network basis
340  void cleanUp();
341  /// Says whether to redo pivot order
342  bool needToReorder() const;
343#ifndef SLIM_CLP
344  /// Says if a network basis
345  inline bool networkBasis() const
346  { return (networkBasis_!=NULL);}
347#else
348  /// Says if a network basis
349  inline bool networkBasis() const
350  { return false;}
351#endif
352  /// Fills weighted row list
353  void getWeights(int * weights) const;
354  //@}
355
356////////////////// data //////////////////
357private:
358
359  /**@name data */
360  //@{
361  /// Pointer to network basis
362#ifndef SLIM_CLP
363  ClpNetworkBasis * networkBasis_;
364#endif
365#ifdef CLP_MULTIPLE_FACTORIZATIONS   
366  /// Pointer to CoinFactorization
367  CoinFactorization * coinFactorizationA_;
368  /// Pointer to CoinSmallFactorization
369  CoinSmallFactorization * coinFactorizationB_;
370  /// If nonzero force use of 1,dense 2,small 3,osl
371  int forceB_;
372  /// Switch to osl if number rows <= this
373  int goOslThreshold_;
374  /// Switch to small if number rows <= this
375  int goSmallThreshold_;
376  /// Switch to dense if number rows <= this
377  int goDenseThreshold_;
378#endif
379  //@}
380};
381
382#endif
Note: See TracBrowser for help on using the repository browser.