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

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

changes for cbc event handler and multiple factorizations

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.0 KB
Line 
1// Copyright (C) 2002, International Business Machines
2// Corporation and others.  All Rights Reserved.
3#ifndef ClpFactorization_H
4#define ClpFactorization_H
5
6
7#include "CoinPragma.hpp"
8
9#include "CoinFactorization.hpp"
10class ClpMatrixBase;
11class ClpSimplex;
12class ClpNetworkBasis;
13#ifndef CLP_MULTIPLE_FACTORIZATIONS
14#define CLP_MULTIPLE_FACTORIZATIONS 3
15#endif   
16#if CLP_MULTIPLE_FACTORIZATIONS == 1
17#include "CoinDenseFactorization.hpp"
18typedef CoinDenseFactorization CoinSmallFactorization;
19#elif CLP_MULTIPLE_FACTORIZATIONS == 2
20#include "CoinSimpFactorization.hpp"
21typedef CoinSimpFactorization CoinSmallFactorization;
22#elif CLP_MULTIPLE_FACTORIZATIONS == 3
23#include "CoinDenseFactorization.hpp"
24#include "CoinSimpFactorization.hpp"
25#endif
26
27/** This just implements CoinFactorization when an ClpMatrixBase object
28    is passed.  If a network then has a dummy CoinFactorization and
29    a genuine ClpNetworkBasis object
30*/
31class ClpFactorization 
32#ifndef CLP_MULTIPLE_FACTORIZATIONS   
33  : public CoinFactorization
34#endif
35{
36
37  //friend class CoinFactorization;
38 
39public:
40  /**@name factorization */
41   //@{
42  /** When part of LP - given by basic variables.
43  Actually does factorization.
44  Arrays passed in have non negative value to say basic.
45  If status is okay, basic variables have pivot row - this is only needed
46  if increasingRows_ >1.
47  Allows scaling
48  If status is singular, then basic variables have pivot row
49  and ones thrown out have -1
50  returns 0 -okay, -1 singular, -2 too many in basis, -99 memory */
51  int factorize (ClpSimplex * model,int solveType, bool valuesPass);
52   //@}
53
54
55  /**@name Constructors, destructor */
56   //@{
57   /** Default constructor. */
58   ClpFactorization();
59   /** Destructor */
60   ~ClpFactorization();
61   //@}
62
63   /**@name Copy method */
64   //@{
65   /** The copy constructor from an CoinFactorization. */
66   ClpFactorization(const CoinFactorization&);
67   /** The copy constructor. */
68  ClpFactorization(const ClpFactorization&,int denseIfSmaller=0);
69#ifdef CLP_MULTIPLE_FACTORIZATIONS   
70   /** The copy constructor from an CoinSmallFactorization. */
71   ClpFactorization(const CoinSmallFactorization&);
72#endif
73   ClpFactorization& operator=(const ClpFactorization&);
74   //@}
75   
76  /*  **** below here is so can use networkish basis */
77  /**@name rank one updates which do exist */
78  //@{
79
80  /** Replaces one Column to basis,
81   returns 0=OK, 1=Probably OK, 2=singular, 3=no room
82      If checkBeforeModifying is true will do all accuracy checks
83      before modifying factorization.  Whether to set this depends on
84      speed considerations.  You could just do this on first iteration
85      after factorization and thereafter re-factorize
86   partial update already in U */
87  int replaceColumn ( const ClpSimplex * model,
88                      CoinIndexedVector * regionSparse,
89                      CoinIndexedVector * tableauColumn,
90                      int pivotRow,
91                      double pivotCheck ,
92                      bool checkBeforeModifying=false);
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  /**  get sparse threshold */
171  inline int sparseThreshold ( ) const
172  { if (coinFactorizationA_) return coinFactorizationA_->sparseThreshold(); else return 0 ;}
173  /**  Set sparse threshold */
174  inline void sparseThreshold ( int value) 
175  { if (coinFactorizationA_) coinFactorizationA_->sparseThreshold(value); }
176  /// Returns status
177  inline int status (  ) const {
178    if (coinFactorizationA_) return coinFactorizationA_->status(); else return coinFactorizationB_->status() ;
179  }
180  /// Sets status
181  inline void setStatus (  int value) {
182    if (coinFactorizationA_) coinFactorizationA_->setStatus(value); else coinFactorizationB_->setStatus(value) ;
183  }
184  /// Returns number of dense rows
185  inline int numberDense() const
186  { if (coinFactorizationA_) return coinFactorizationA_->numberDense(); else return 0 ;}
187#if 1
188  /// Returns number in U area
189  inline CoinBigIndex numberElementsU (  ) const {
190    if (coinFactorizationA_) return coinFactorizationA_->numberElementsU(); else return -1 ;
191  }
192  /// Returns number in L area
193  inline CoinBigIndex numberElementsL (  ) const {
194    if (coinFactorizationA_) return coinFactorizationA_->numberElementsL(); else return -1 ;
195  }
196  /// Returns number in R area
197  inline CoinBigIndex numberElementsR (  ) const {
198    if (coinFactorizationA_) return coinFactorizationA_->numberElementsR(); else return 0 ;
199  }
200#endif
201  inline bool timeToRefactorize() const
202  {
203    if (coinFactorizationA_) {
204      return (coinFactorizationA_->pivots()*3>coinFactorizationA_->maximumPivots()*2&&
205              coinFactorizationA_->numberElementsR()*3>(coinFactorizationA_->numberElementsL()+
206                                                        coinFactorizationA_->numberElementsU())*2+1000&&
207              !coinFactorizationA_->numberDense());
208    } else {
209      return coinFactorizationB_->pivots()>coinFactorizationB_->numberRows()/2.45+20;
210    }
211  }
212  /// Level of detail of messages
213  inline int messageLevel (  ) const {
214    if (coinFactorizationA_) return coinFactorizationA_->messageLevel();  else return 0 ;
215  }
216  /// Set level of detail of messages
217  inline void messageLevel (  int value) {
218    if (coinFactorizationA_) coinFactorizationA_->messageLevel(value);
219  }
220  /// Get rid of all memory
221  inline void clearArrays()
222  { if (coinFactorizationA_) coinFactorizationA_->clearArrays();}
223  /// Number of Rows after factorization
224  inline int numberRows (  ) const {
225    if (coinFactorizationA_) return coinFactorizationA_->numberRows(); else return coinFactorizationB_->numberRows() ;
226  }
227  /// Gets dense threshold
228  inline int denseThreshold() const 
229  { if (coinFactorizationA_) return coinFactorizationA_->denseThreshold(); else return 0 ;}
230  /// Sets dense threshold
231  inline void setDenseThreshold(int value)
232  { if (coinFactorizationA_) coinFactorizationA_->setDenseThreshold(value);}
233  /// Pivot tolerance
234  inline double pivotTolerance (  ) const {
235    if (coinFactorizationA_) return coinFactorizationA_->pivotTolerance();  else return 1.0e-8 ;
236  }
237  /// Set pivot tolerance
238  inline void pivotTolerance (  double value) {
239    if (coinFactorizationA_) coinFactorizationA_->pivotTolerance(value);
240  }
241  /// Allows change of pivot accuracy check 1.0 == none >1.0 relaxed
242  inline void relaxAccuracyCheck(double value)
243  { if (coinFactorizationA_) coinFactorizationA_->relaxAccuracyCheck(value);}
244  /** Array persistence flag
245      If 0 then as now (delete/new)
246      1 then only do arrays if bigger needed
247      2 as 1 but give a bit extra if bigger needed
248  */
249  inline int persistenceFlag() const
250  { if (coinFactorizationA_) return coinFactorizationA_->persistenceFlag(); else return 0 ;}
251  inline void setPersistenceFlag(int value)
252  { if (coinFactorizationA_) coinFactorizationA_->setPersistenceFlag(value);}
253  /// Delete all stuff (leaves as after CoinFactorization())
254  inline void almostDestructor()
255  { if (coinFactorizationA_) coinFactorizationA_->almostDestructor(); }
256  /// Returns areaFactor but adjusted for dense
257  inline double adjustedAreaFactor() const
258  { if (coinFactorizationA_) return coinFactorizationA_->adjustedAreaFactor(); else return 0.0 ; }
259  inline void setBiasLU(int value)
260  { if (coinFactorizationA_) coinFactorizationA_->setBiasLU(value);}
261  /// true if Forrest Tomlin update, false if PFI
262  inline void setForrestTomlin(bool value)
263  { if (coinFactorizationA_) coinFactorizationA_->setForrestTomlin(value);}
264  /// Sets default values
265  inline void setDefaultValues() {
266    if (coinFactorizationA_) {
267      // row activities have negative sign
268#ifndef COIN_FAST_CODE
269      coinFactorizationA_->slackValue(-1.0);
270#endif
271      coinFactorizationA_->zeroTolerance(1.0e-13);
272    }
273  }
274  /// Get switch to dense if number rows <= this
275  inline int goDenseThreshold() const
276  { return goDenseThreshold_;}
277  /// Set switch to dense if number rows <= this
278  inline void setGoDenseThreshold(int value)
279  { goDenseThreshold_ = value;}
280  /// Get switch to small if number rows <= this
281  inline int goSmallThreshold() const
282  { return goSmallThreshold_;}
283  /// Set switch to small if number rows <= this
284  inline void setGoSmallThreshold(int value)
285  { goSmallThreshold_ = value;}
286  /// Go over to dense or small code if small enough
287  void goDenseOrSmall(int numberRows) ;
288  /// Return 1 if dense code
289  inline int isDenseOrSmall() const
290  { return coinFactorizationB_ ? 1 : 0;}
291#else
292  inline bool timeToRefactorize() const
293  {
294    return (pivots()*3>maximumPivots()*2&&
295            numberElementsR()*3>(numberElementsL()+numberElementsU())*2+1000&&
296            !numberDense());
297  }
298  /// Sets default values
299  inline void setDefaultValues() {
300    // row activities have negative sign
301#ifndef COIN_FAST_CODE
302    slackValue(-1.0);
303#endif
304    zeroTolerance(1.0e-13);
305  }
306  /// Go over to dense code
307  inline void goDense() {}
308#endif
309  //@}
310   
311  /**@name other stuff */
312  //@{
313  /** makes a row copy of L for speed and to allow very sparse problems */
314  void goSparse();
315  /// Cleans up i.e. gets rid of network basis
316  void cleanUp();
317  /// Says whether to redo pivot order
318  bool needToReorder() const;
319#ifndef SLIM_CLP
320  /// Says if a network basis
321  inline bool networkBasis() const
322  { return (networkBasis_!=NULL);}
323#else
324  /// Says if a network basis
325  inline bool networkBasis() const
326  { return false;}
327#endif
328  /// Fills weighted row list
329  void getWeights(int * weights) const;
330  //@}
331
332////////////////// data //////////////////
333private:
334
335  /**@name data */
336  //@{
337  /// Pointer to network basis
338#ifndef SLIM_CLP
339  ClpNetworkBasis * networkBasis_;
340#endif
341#ifdef CLP_MULTIPLE_FACTORIZATIONS   
342  /// Pointer to CoinFactorization
343  CoinFactorization * coinFactorizationA_;
344  /// Pointer to CoinSmallFactorization
345  CoinSmallFactorization * coinFactorizationB_;
346  /// Switch to small if number rows <= this
347  int goSmallThreshold_;
348  /// Switch to dense if number rows <= this
349  int goDenseThreshold_;
350#endif
351  //@}
352};
353
354#endif
Note: See TracBrowser for help on using the repository browser.