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

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

chnages for speed and alternate factorization

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