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

Last change on this file since 1525 was 1525, checked in by mjs, 10 years ago

Formatted .cpp, .hpp, .c, .h files with "astyle -A4 -p". This matches the formatting used in the grand CBC reorganization.

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