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

Last change on this file since 1616 was 1616, checked in by forrest, 9 years ago

for partial skip of etas

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 15.7 KB
Line 
1/* $Id: ClpFactorization.hpp 1616 2010-11-01 13:05:15Z 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#define CLP_MULTIPLE_FACTORIZATIONS 4
17#endif
18#ifdef CLP_MULTIPLE_FACTORIZATIONS
19#include "CoinDenseFactorization.hpp"
20#include "ClpSimplex.hpp"
21#endif
22#ifndef COIN_FAST_CODE
23#define COIN_FAST_CODE
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();
133          else return coinFactorizationB_->numberElements() ;
134     }
135     /// Returns address of permute region
136     inline int *permute (  ) const {
137          if (coinFactorizationA_) return coinFactorizationA_->permute();
138          else return coinFactorizationB_->permute() ;
139     }
140     /// Returns address of pivotColumn region (also used for permuting)
141     inline int *pivotColumn (  ) const {
142          if (coinFactorizationA_) return coinFactorizationA_->pivotColumn();
143          else return coinFactorizationB_->permute() ;
144     }
145     /// Maximum number of pivots between factorizations
146     inline int maximumPivots (  ) const {
147          if (coinFactorizationA_) return coinFactorizationA_->maximumPivots();
148          else return coinFactorizationB_->maximumPivots() ;
149     }
150     /// Set maximum number of pivots between factorizations
151     inline void maximumPivots (  int value) {
152          if (coinFactorizationA_) coinFactorizationA_->maximumPivots(value);
153          else coinFactorizationB_->maximumPivots(value);
154     }
155     /// Returns number of pivots since factorization
156     inline int pivots (  ) const {
157          if (coinFactorizationA_) return coinFactorizationA_->pivots();
158          else return coinFactorizationB_->pivots() ;
159     }
160     /// Whether larger areas needed
161     inline double areaFactor (  ) const {
162          if (coinFactorizationA_) return coinFactorizationA_->areaFactor();
163          else return 0.0 ;
164     }
165     /// Set whether larger areas needed
166     inline void areaFactor ( double value) {
167          if (coinFactorizationA_) coinFactorizationA_->areaFactor(value);
168     }
169     /// Zero tolerance
170     inline double zeroTolerance (  ) const {
171          if (coinFactorizationA_) return coinFactorizationA_->zeroTolerance();
172          else return coinFactorizationB_->zeroTolerance() ;
173     }
174     /// Set zero tolerance
175     inline void zeroTolerance (  double value) {
176          if (coinFactorizationA_) coinFactorizationA_->zeroTolerance(value);
177          else coinFactorizationB_->zeroTolerance(value);
178     }
179     /// Set tolerances to safer of existing and given
180     void saferTolerances (  double zeroTolerance, double pivotTolerance);
181     /**  get sparse threshold */
182     inline int sparseThreshold ( ) const {
183          if (coinFactorizationA_) return coinFactorizationA_->sparseThreshold();
184          else return 0 ;
185     }
186     /**  Set sparse threshold */
187     inline void sparseThreshold ( int value) {
188          if (coinFactorizationA_) coinFactorizationA_->sparseThreshold(value);
189     }
190     /// Returns status
191     inline int status (  ) const {
192          if (coinFactorizationA_) return coinFactorizationA_->status();
193          else return coinFactorizationB_->status() ;
194     }
195     /// Sets status
196     inline void setStatus (  int value) {
197          if (coinFactorizationA_) coinFactorizationA_->setStatus(value);
198          else coinFactorizationB_->setStatus(value) ;
199     }
200     /// Returns number of dense rows
201     inline int numberDense() const {
202          if (coinFactorizationA_) return coinFactorizationA_->numberDense();
203          else return 0 ;
204     }
205#if 1
206     /// Returns number in U area
207     inline CoinBigIndex numberElementsU (  ) const {
208          if (coinFactorizationA_) return coinFactorizationA_->numberElementsU();
209          else return -1 ;
210     }
211     /// Returns number in L area
212     inline CoinBigIndex numberElementsL (  ) const {
213          if (coinFactorizationA_) return coinFactorizationA_->numberElementsL();
214          else return -1 ;
215     }
216     /// Returns number in R area
217     inline CoinBigIndex numberElementsR (  ) const {
218          if (coinFactorizationA_) return coinFactorizationA_->numberElementsR();
219          else return 0 ;
220     }
221#endif
222     inline bool timeToRefactorize() const {
223          if (coinFactorizationA_) {
224               return (coinFactorizationA_->pivots() * 3 > coinFactorizationA_->maximumPivots() * 2 &&
225                       coinFactorizationA_->numberElementsR() * 3 > (coinFactorizationA_->numberElementsL() +
226                                 coinFactorizationA_->numberElementsU()) * 2 + 1000 &&
227                       !coinFactorizationA_->numberDense());
228          } else {
229               return coinFactorizationB_->pivots() > coinFactorizationB_->numberRows() / 2.45 + 20;
230          }
231     }
232     /// Level of detail of messages
233     inline int messageLevel (  ) const {
234          if (coinFactorizationA_) return coinFactorizationA_->messageLevel();
235          else return 1 ;
236     }
237     /// Set level of detail of messages
238     inline void messageLevel (  int value) {
239          if (coinFactorizationA_) coinFactorizationA_->messageLevel(value);
240     }
241     /// Get rid of all memory
242     inline void clearArrays() {
243          if (coinFactorizationA_)
244               coinFactorizationA_->clearArrays();
245          else if (coinFactorizationB_)
246               coinFactorizationB_->clearArrays();
247     }
248     /// Number of Rows after factorization
249     inline int numberRows (  ) const {
250          if (coinFactorizationA_) return coinFactorizationA_->numberRows();
251          else return coinFactorizationB_->numberRows() ;
252     }
253     /// Gets dense threshold
254     inline int denseThreshold() const {
255          if (coinFactorizationA_) return coinFactorizationA_->denseThreshold();
256          else return 0 ;
257     }
258     /// Sets dense threshold
259     inline void setDenseThreshold(int value) {
260          if (coinFactorizationA_) coinFactorizationA_->setDenseThreshold(value);
261     }
262     /// Pivot tolerance
263     inline double pivotTolerance (  ) const {
264          if (coinFactorizationA_) return coinFactorizationA_->pivotTolerance();
265          else if (coinFactorizationB_) return coinFactorizationB_->pivotTolerance();
266          return 1.0e-8 ;
267     }
268     /// Set pivot tolerance
269     inline void pivotTolerance (  double value) {
270          if (coinFactorizationA_) coinFactorizationA_->pivotTolerance(value);
271          else if (coinFactorizationB_) coinFactorizationB_->pivotTolerance(value);
272     }
273     /// Allows change of pivot accuracy check 1.0 == none >1.0 relaxed
274     inline void relaxAccuracyCheck(double value) {
275          if (coinFactorizationA_) coinFactorizationA_->relaxAccuracyCheck(value);
276     }
277     /** Array persistence flag
278         If 0 then as now (delete/new)
279         1 then only do arrays if bigger needed
280         2 as 1 but give a bit extra if bigger needed
281     */
282     inline int persistenceFlag() const {
283          if (coinFactorizationA_) return coinFactorizationA_->persistenceFlag();
284          else return 0 ;
285     }
286     inline void setPersistenceFlag(int value) {
287          if (coinFactorizationA_) coinFactorizationA_->setPersistenceFlag(value);
288     }
289     /// Delete all stuff (leaves as after CoinFactorization())
290     inline void almostDestructor() {
291          if (coinFactorizationA_)
292               coinFactorizationA_->almostDestructor();
293          else if (coinFactorizationB_)
294               coinFactorizationB_->clearArrays();
295     }
296     /// Returns areaFactor but adjusted for dense
297     inline double adjustedAreaFactor() const {
298          if (coinFactorizationA_) return coinFactorizationA_->adjustedAreaFactor();
299          else return 0.0 ;
300     }
301     inline void setBiasLU(int value) {
302          if (coinFactorizationA_) coinFactorizationA_->setBiasLU(value);
303     }
304     /// true if Forrest Tomlin update, false if PFI
305     inline void setForrestTomlin(bool value) {
306          if (coinFactorizationA_) coinFactorizationA_->setForrestTomlin(value);
307     }
308     /// Sets default values
309     inline void setDefaultValues() {
310          if (coinFactorizationA_) {
311               // row activities have negative sign
312#ifndef COIN_FAST_CODE
313               coinFactorizationA_->slackValue(-1.0);
314#endif
315               coinFactorizationA_->zeroTolerance(1.0e-13);
316          }
317     }
318     /// If nonzero force use of 1,dense 2,small 3,osl
319     void forceOtherFactorization(int which);
320     /// Get switch to osl if number rows <= this
321     inline int goOslThreshold() const {
322          return goOslThreshold_;
323     }
324     /// Set switch to osl if number rows <= this
325     inline void setGoOslThreshold(int value) {
326          goOslThreshold_ = value;
327     }
328     /// Get switch to dense if number rows <= this
329     inline int goDenseThreshold() const {
330          return goDenseThreshold_;
331     }
332     /// Set switch to dense if number rows <= this
333     inline void setGoDenseThreshold(int value) {
334          goDenseThreshold_ = value;
335     }
336     /// Get switch to small if number rows <= this
337     inline int goSmallThreshold() const {
338          return goSmallThreshold_;
339     }
340     /// Set switch to small if number rows <= this
341     inline void setGoSmallThreshold(int value) {
342          goSmallThreshold_ = value;
343     }
344     /// Go over to dense or small code if small enough
345     void goDenseOrSmall(int numberRows) ;
346     /// Sets factorization
347     void setFactorization(ClpFactorization & factorization);
348     /// Return 1 if dense code
349     inline int isDenseOrSmall() const {
350          return coinFactorizationB_ ? 1 : 0;
351     }
352#else
353     inline bool timeToRefactorize() const {
354          return (pivots() * 3 > maximumPivots() * 2 &&
355                  numberElementsR() * 3 > (numberElementsL() + numberElementsU()) * 2 + 1000 &&
356                  !numberDense());
357     }
358     /// Sets default values
359     inline void setDefaultValues() {
360          // row activities have negative sign
361#ifndef COIN_FAST_CODE
362          slackValue(-1.0);
363#endif
364          zeroTolerance(1.0e-13);
365     }
366     /// Go over to dense code
367     inline void goDense() {}
368#endif
369     //@}
370
371     /**@name other stuff */
372     //@{
373     /** makes a row copy of L for speed and to allow very sparse problems */
374     void goSparse();
375     /// Cleans up i.e. gets rid of network basis
376     void cleanUp();
377     /// Says whether to redo pivot order
378     bool needToReorder() const;
379#ifndef SLIM_CLP
380     /// Says if a network basis
381     inline bool networkBasis() const {
382          return (networkBasis_ != NULL);
383     }
384#else
385     /// Says if a network basis
386     inline bool networkBasis() const {
387          return false;
388     }
389#endif
390     /// Fills weighted row list
391     void getWeights(int * weights) const;
392     //@}
393
394////////////////// data //////////////////
395private:
396
397     /**@name data */
398     //@{
399     /// Pointer to network basis
400#ifndef SLIM_CLP
401     ClpNetworkBasis * networkBasis_;
402#endif
403#ifdef CLP_MULTIPLE_FACTORIZATIONS
404     /// Pointer to CoinFactorization
405     CoinFactorization * coinFactorizationA_;
406     /// Pointer to CoinOtherFactorization
407     CoinOtherFactorization * coinFactorizationB_;
408#ifdef CLP_REUSE_ETAS
409     /// Pointer to model
410     ClpSimplex * model_;
411#endif
412     /// If nonzero force use of 1,dense 2,small 3,osl
413     int forceB_;
414     /// Switch to osl if number rows <= this
415     int goOslThreshold_;
416     /// Switch to small if number rows <= this
417     int goSmallThreshold_;
418     /// Switch to dense if number rows <= this
419     int goDenseThreshold_;
420#endif
421     //@}
422};
423
424#endif
Note: See TracBrowser for help on using the repository browser.