- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

# /home/coin/svn-release/Alps-1.4.8/CoinUtils/src/CoinPresolveMatrix.hpp

Go to the documentation of this file.

    00001 /* $Id: CoinPresolveMatrix.hpp 1581 2013-04-06 12:48:50Z stefan $ */
    00002 // Copyright (C) 2002, International Business Machines
    00003 // Corporation and others.  All Rights Reserved.
    00004 // This code is licensed under the terms of the Eclipse Public License (EPL).
    00005
    00006 #ifndef CoinPresolveMatrix_H
    00007 #define CoinPresolveMatrix_H
    00008
    00009 #include "CoinPragma.hpp"
    00010 #include "CoinPackedMatrix.hpp"
    00011 #include "CoinMessage.hpp"
    00012 #include "CoinTime.hpp"
    00013
    00014 #include <cmath>
    00015 #include <cassert>
    00016 #include <cfloat>
    00017 #include <cassert>
    00018 #include <cstdlib>
    00019
    00020 #if PRESOLVE_DEBUG > 0
    00021 #include "CoinFinite.hpp"
    00022 #endif
    00023
    00032 #if defined(_MSC_VER)
    00033 // Avoid MS Compiler problem in recognizing type to delete
    00034 // by casting to type.
    00035 // Is this still necessary? -- lh, 111202 --
    00036 #define deleteAction(array,type) delete [] ((type) array)
    00037 #else
    00038 #define deleteAction(array,type) delete [] array
    00039 #endif
    00040
    00041 /*
    00042   Define PRESOLVE_DEBUG and PRESOLVE_CONSISTENCY on the configure command
    00043   line or in a Makefile!  See comments in CoinPresolvePsdebug.hpp.
    00044 */
    00045 #if PRESOLVE_DEBUG > 0 || PRESOLVE_CONSISTENCY > 0
    00046
    00047 #define PRESOLVE_STMT(s) s
    00048
    00049 #define PRESOLVEASSERT(x) \
    00050   ((x) ? 1 : ((std::cerr << "FAILED ASSERTION at line " \
    00051                          << __LINE__ << ": " #x "\n"), abort(), 0))
    00052
    00053 inline void DIE(const char *s) { std::cout << s ; abort() ; }
    00054
    00065 #define PRESENT_IN_REDUCED      '\377'
    00066
    00067 #else
    00068
    00069 #define PRESOLVEASSERT(x) {}
    00070 #define PRESOLVE_STMT(s) {}
    00071
    00072 inline void DIE(const char *) {}
    00073
    00074 #endif
    00075
    00076 /*
    00077   Unclear why these are separate from standard debug.
    00078 */
    00079 #ifndef PRESOLVE_DETAIL
    00080 #define PRESOLVE_DETAIL_PRINT(s) {}
    00081 #else
    00082 #define PRESOLVE_DETAIL_PRINT(s) s
    00083 #endif
    00084
    00089 const double ZTOLDP = 1e-12 ;
    00094 const double ZTOLDP2 = 1e-10 ;
    00095
    00097 #define PRESOLVE_INF COIN_DBL_MAX
    00099 #define PRESOLVE_SMALL_INF 1.0e20
    00101 #define PRESOLVEFINITE(n) (-PRESOLVE_INF < (n) && (n) < PRESOLVE_INF)
    00102
    00103
    00104 class CoinPostsolveMatrix ;
    00105
    00155 class CoinPresolveAction
    00156 {
    00157  public:
    00164   static void throwCoinError(const char *error, const char *ps_routine)
    00165   { throw CoinError(error, ps_routine, "CoinPresolve"); }
    00166
    00171   const CoinPresolveAction *next;
    00172
    00178   CoinPresolveAction(const CoinPresolveAction *next) : next(next) {}
    00180   inline void setNext(const CoinPresolveAction *nextAction)
    00181   { next = nextAction;}
    00182
    00187   virtual const char *name() const = 0;
    00188
    00192   virtual void postsolve(CoinPostsolveMatrix *prob) const = 0;
    00193
    00195   virtual ~CoinPresolveAction() {}
    00196 };
    00197
    00198 /*
    00199   These are needed for OSI-aware constructors associated with
    00200   CoinPrePostsolveMatrix, CoinPresolveMatrix, and CoinPostsolveMatrix.
    00201 */
    00202 class ClpSimplex;
    00203 class OsiSolverInterface;
    00204
    00205 /*
    00206   CoinWarmStartBasis is required for methods in CoinPrePostsolveMatrix
    00207   that accept/return a CoinWarmStartBasis object.
    00208 */
    00209 class CoinWarmStartBasis ;
    00210
    00265 class CoinPrePostsolveMatrix
    00266 {
    00267  public:
    00268
    00278   CoinPrePostsolveMatrix(int ncols_alloc, int nrows_alloc,
    00279                          CoinBigIndex nelems_alloc) ;
    00280
    00285   CoinPrePostsolveMatrix(const OsiSolverInterface * si,
    00286                         int ncols_,
    00287                         int nrows_,
    00288                         CoinBigIndex nelems_);
    00289
    00294   CoinPrePostsolveMatrix(const ClpSimplex * si,
    00295                         int ncols_,
    00296                         int nrows_,
    00297                         CoinBigIndex nelems_,
    00298                          double bulkRatio);
    00299
    00301   ~CoinPrePostsolveMatrix();
    00303
    00313   enum Status {
    00314     isFree = 0x00,
    00315     basic = 0x01,
    00316     atUpperBound = 0x02,
    00317     atLowerBound = 0x03,
    00318     superBasic = 0x04
    00319   };
    00320
    00333
    00335   inline void setRowStatus(int sequence, Status status)
    00336   {
    00337     unsigned char & st_byte = rowstat_[sequence];
    00338     st_byte = static_cast<unsigned char>(st_byte & (~7)) ;
    00339     st_byte = static_cast<unsigned char>(st_byte | status) ;
    00340   }
    00342   inline Status getRowStatus(int sequence) const
    00343   {return static_cast<Status> (rowstat_[sequence]&7);}
    00345   inline bool rowIsBasic(int sequence) const
    00346   {return (static_cast<Status> (rowstat_[sequence]&7)==basic);}
    00348   inline void setColumnStatus(int sequence, Status status)
    00349   {
    00350     unsigned char & st_byte = colstat_[sequence];
    00351     st_byte = static_cast<unsigned char>(st_byte & (~7)) ;
    00352     st_byte = static_cast<unsigned char>(st_byte | status) ;
    00353
    00354 #   ifdef PRESOLVE_DEBUG
    00355     switch (status)
    00356     { case isFree:
    00357       { if (clo_[sequence] > -PRESOLVE_INF || cup_[sequence] < PRESOLVE_INF)
    00358         { std::cout << "Bad status: Var " << sequence
    00359                     << " isFree, lb = " << clo_[sequence]
    00360                     << ", ub = " << cup_[sequence] << std::endl ; }
    00361         break ; }
    00362       case basic:
    00363       { break ; }
    00364       case atUpperBound:
    00365       { if (cup_[sequence] >= PRESOLVE_INF)
    00366         { std::cout << "Bad status: Var " << sequence
    00367                     << " atUpperBound, lb = " << clo_[sequence]
    00368                     << ", ub = " << cup_[sequence] << std::endl ; }
    00369         break ; }
    00370       case atLowerBound:
    00371       { if (clo_[sequence] <= -PRESOLVE_INF)
    00372         { std::cout << "Bad status: Var " << sequence
    00373                     << " atLowerBound, lb = " << clo_[sequence]
    00374                     << ", ub = " << cup_[sequence] << std::endl ; }
    00375         break ; }
    00376       case superBasic:
    00377       { if (clo_[sequence] <= -PRESOLVE_INF && cup_[sequence] >= PRESOLVE_INF)
    00378         { std::cout << "Bad status: Var " << sequence
    00379                     << " superBasic, lb = " << clo_[sequence]
    00380                     << ", ub = " << cup_[sequence] << std::endl ; }
    00381         break ; }
    00382       default:
    00383       { assert(false) ;
    00384         break ; } }
    00385 #   endif
    00386   }
    00388   inline Status getColumnStatus(int sequence) const
    00389   {return static_cast<Status> (colstat_[sequence]&7);}
    00391   inline bool columnIsBasic(int sequence) const
    00392   {return (static_cast<Status> (colstat_[sequence]&7)==basic);}
    00396   void setRowStatusUsingValue(int iRow);
    00400   void setColumnStatusUsingValue(int iColumn);
    00402   void setStructuralStatus(const char *strucStatus, int lenParam) ;
    00404   void setArtificialStatus(const char *artifStatus, int lenParam) ;
    00406   void setStatus(const CoinWarmStartBasis *basis) ;
    00408   CoinWarmStartBasis *getStatus() ;
    00412   const char *columnStatusString(int j) const ;
    00416   const char *rowStatusString(int i) const ;
    00418
    00426
    00427   void setObjOffset(double offset) ;
    00434   void setObjSense(double objSense) ;
    00436   void setPrimalTolerance(double primTol) ;
    00438   void setDualTolerance(double dualTol) ;
    00440   void setColLower(const double *colLower, int lenParam) ;
    00442   void setColUpper(const double *colUpper, int lenParam) ;
    00444   void setColSolution(const double *colSol, int lenParam) ;
    00446   void setCost(const double *cost, int lenParam) ;
    00448   void setReducedCost(const double *redCost, int lenParam) ;
    00450   void setRowLower(const double *rowLower, int lenParam) ;
    00452   void setRowUpper(const double *rowUpper, int lenParam) ;
    00454   void setRowPrice(const double *rowSol, int lenParam) ;
    00456   void setRowActivity(const double *rowAct, int lenParam) ;
    00458
    00461
    00462   inline int getNumCols() const
    00463   { return (ncols_) ; }
    00465   inline int getNumRows() const
    00466   { return (nrows_) ; }
    00468   inline int getNumElems() const
    00469   { return (nelems_) ; }
    00471   inline const CoinBigIndex *getColStarts() const
    00472   { return (mcstrt_) ; }
    00474   inline const int *getColLengths() const
    00475   { return (hincol_) ; }
    00477   inline const int *getRowIndicesByCol() const
    00478   { return (hrow_) ; }
    00480   inline const double *getElementsByCol() const
    00481   { return (colels_) ; }
    00483   inline const double *getColLower() const
    00484   { return (clo_) ; }
    00486   inline const double *getColUpper() const
    00487   { return (cup_) ; }
    00489   inline const double *getCost() const
    00490   { return (cost_) ; }
    00492   inline const double *getRowLower() const
    00493   { return (rlo_) ; }
    00495   inline const double *getRowUpper() const
    00496   { return (rup_) ; }
    00498   inline const double *getColSolution() const
    00499   { return (sol_) ; }
    00501   inline const double *getRowActivity() const
    00502   { return (acts_) ; }
    00504   inline const double *getRowPrice() const
    00505   { return (rowduals_) ; }
    00507   inline const double *getReducedCost() const
    00508   { return (rcosts_) ; }
    00510   inline int countEmptyCols()
    00511   { int empty = 0 ;
    00512     for (int i = 0 ; i < ncols_ ; i++) if (hincol_[i] == 0) empty++ ;
    00513     return (empty) ; }
    00515
    00516
    00519
    00520   inline CoinMessageHandler *messageHandler() const
    00521   { return handler_; }
    00527   inline void setMessageHandler(CoinMessageHandler *handler)
    00528   { if (defaultHandler_ == true)
    00529     { delete handler_ ;
    00530       defaultHandler_ = false ; }
    00531     handler_ = handler ; }
    00533   inline CoinMessages messages() const
    00534   { return messages_; }
    00536
    00546
    00548   int ncols_;
    00550   int nrows_;
    00552   CoinBigIndex nelems_;
    00553
    00555   int ncols0_;
    00557   int nrows0_ ;
    00559   CoinBigIndex nelems0_ ;
    00568   CoinBigIndex bulk0_ ;
    00570   double bulkRatio_;
    00572
    00581
    00582   CoinBigIndex *mcstrt_;
    00584   int *hincol_;
    00586   int *hrow_;
    00588   double *colels_;
    00589
    00591   double *cost_;
    00593   double originalOffset_;
    00594
    00596   double *clo_;
    00598   double *cup_;
    00599
    00601   double *rlo_;
    00603   double *rup_;
    00604
    00611   int * originalColumn_;
    00618   int * originalRow_;
    00619
    00621   double ztolzb_;
    00623   double ztoldj_;
    00624
    00630   double maxmin_;
    00632
    00653   double *sol_;
    00659   double *rowduals_;
    00665   double *acts_;
    00671   double *rcosts_;
    00672
    00679   unsigned char *colstat_;
    00680
    00687   unsigned char *rowstat_;
    00689
    00698
    00699   CoinMessageHandler *handler_;
    00701   bool defaultHandler_;
    00703   CoinMessage messages_;
    00705
    00706 };
    00707
    00711 const char *statusName (CoinPrePostsolveMatrix::Status status) ;
    00712
    00713
    00738 class presolvehlink
    00739 { public:
    00740   int pre, suc;
    00741 } ;
    00742
    00743 #define NO_LINK -66666666
    00744
    00750 inline void PRESOLVE_REMOVE_LINK(presolvehlink *link, int i)
    00751 {
    00752   int ipre = link[i].pre;
    00753   int isuc = link[i].suc;
    00754   if (ipre >= 0) {
    00755     link[ipre].suc = isuc;
    00756   }
    00757   if (isuc >= 0) {
    00758     link[isuc].pre = ipre;
    00759   }
    00760   link[i].pre = NO_LINK, link[i].suc = NO_LINK;
    00761 }
    00762
    00768 inline void PRESOLVE_INSERT_LINK(presolvehlink *link, int i, int j)
    00769 {
    00770   int isuc = link[j].suc;
    00771   link[j].suc = i;
    00772   link[i].pre = j;
    00773   if (isuc >= 0) {
    00774     link[isuc].pre = i;
    00775   }
    00776   link[i].suc = isuc;
    00777 }
    00778
    00790 inline void PRESOLVE_MOVE_LINK(presolvehlink *link, int i, int j)
    00791 {
    00792   int ipre = link[i].pre;
    00793   int isuc = link[i].suc;
    00794   if (ipre >= 0) {
    00795     link[ipre].suc = j;
    00796   }
    00797   if (isuc >= 0) {
    00798     link[isuc].pre = j;
    00799   }
    00800   link[i].pre = NO_LINK, link[i].suc = NO_LINK;
    00801 }
    00802
    00803
    00835 class CoinPresolveMatrix : public CoinPrePostsolveMatrix
    00836 {
    00837  public:
    00838
    00845   CoinPresolveMatrix(int ncols_alloc, int nrows_alloc,
    00846                      CoinBigIndex nelems_alloc) ;
    00847
    00852   CoinPresolveMatrix(int ncols0,
    00853                     double maxmin,
    00854                     // end prepost members
    00855
    00856                     ClpSimplex * si,
    00857
    00858                     // rowrep
    00859                     int nrows,
    00860                     CoinBigIndex nelems,
    00861                  bool doStatus,
    00862                  double nonLinearVariable,
    00863                      double bulkRatio);
    00864
    00866   void update_model(ClpSimplex * si,
    00867                             int nrows0,
    00868                             int ncols0,
    00869                             CoinBigIndex nelems0);
    00874   CoinPresolveMatrix(int ncols0,
    00875                      double maxmin,
    00876                      // end prepost members
    00877                      OsiSolverInterface * si,
    00878                      // rowrep
    00879                      int nrows,
    00880                      CoinBigIndex nelems,
    00881                      bool doStatus,
    00882                      double nonLinearVariable,
    00883                      const char * prohibited,
    00884                      const char * rowProhibited=NULL);
    00885
    00887   void update_model(OsiSolverInterface * si,
    00888                             int nrows0,
    00889                             int ncols0,
    00890                             CoinBigIndex nelems0);
    00891
    00893   ~CoinPresolveMatrix();
    00894
    00900   friend void assignPresolveToPostsolve (CoinPresolveMatrix *&preObj) ;
    00901
    00910   void setMatrix(const CoinPackedMatrix *mtx) ;
    00911
    00913   inline int countEmptyRows()
    00914   { int empty = 0 ;
    00915     for (int i = 0 ; i < nrows_ ; i++) if (hinrow_[i] == 0) empty++ ;
    00916     return (empty) ; }
    00917
    00923   inline void setVariableType(int i, int variableType)
    00924   { if (integerType_ == 0) integerType_ = new unsigned char [ncols0_] ;
    00925     integerType_[i] = static_cast<unsigned char>(variableType) ; }
    00926
    00932   void setVariableType(const unsigned char *variableType, int lenParam) ;
    00933
    00939   void setVariableType (bool allIntegers, int lenParam) ;
    00940
    00942   inline void setAnyInteger (bool anyInteger = true)
    00943   { anyInteger_ = anyInteger ; }
    00945
    00949
    00951   inline const CoinBigIndex *getRowStarts() const
    00952   { return (mrstrt_) ; }
    00954   inline const int *getColIndicesByRow() const
    00955   { return (hcol_) ; }
    00957   inline const double *getElementsByRow() const
    00958   { return (rowels_) ; }
    00959
    00965   inline bool isInteger (int i) const
    00966   { if (integerType_ == 0)
    00967     { return (anyInteger_) ; }
    00968     else
    00969     if (integerType_[i] == 1)
    00970     { return (true) ; }
    00971     else
    00972     { return (false) ; } }
    00973
    00978   inline bool anyInteger () const
    00979   { return (anyInteger_) ; }
    00981   inline int presolveOptions() const
    00982   { return presolveOptions_;}
    00984   inline void setPresolveOptions(int value)
    00985   { presolveOptions_=value;}
    00987
    00995
    00996   presolvehlink *clink_;
    00998   presolvehlink *rlink_;
    01000
    01002   double dobias_ ;
    01003
    01005   inline void change_bias(double change_amount)
    01006   {
    01007     dobias_ += change_amount ;
    01008   # if PRESOLVE_DEBUG > 2
    01009     assert(fabs(change_amount)<1.0e50) ;
    01010     if (change_amount)
    01011       PRESOLVE_STMT(printf("changing bias by %g to %g\n",
    01012                             change_amount, dobias_)) ;
    01013   # endif
    01014   }
    01015
    01024
    01025   CoinBigIndex *mrstrt_;
    01027   int *hinrow_;
    01029   double *rowels_;
    01031   int *hcol_;
    01033
    01035   unsigned char *integerType_;
    01041   bool anyInteger_ ;
    01043   bool tuning_;
    01045   void statistics();
    01047   double startTime_;
    01048
    01050   double feasibilityTolerance_;
    01052   inline double feasibilityTolerance()
    01053   { return (feasibilityTolerance_) ; }
    01055   inline void setFeasibilityTolerance (double val)
    01056   { feasibilityTolerance_ = val ; }
    01057
    01063   int status_;
    01065   inline int status()
    01066   { return (status_) ; }
    01068   inline void setStatus(int status)
    01069   { status_ = (status&0x3) ; }
    01070
    01078   int pass_;
    01080   inline void setPass (int pass = 0)
    01081   { pass_ = pass ; }
    01082
    01087   int maxSubstLevel_;
    01089   inline void setMaximumSubstitutionLevel (int level)
    01090   { maxSubstLevel_ = level ; }
    01091
    01092
    01116   unsigned char * colChanged_;
    01118   int * colsToDo_;
    01120   int numberColsToDo_;
    01122   int * nextColsToDo_;
    01124   int numberNextColsToDo_;
    01125
    01135   unsigned char * rowChanged_;
    01137   int * rowsToDo_;
    01139   int numberRowsToDo_;
    01141   int * nextRowsToDo_;
    01143   int numberNextRowsToDo_;
    01161   int presolveOptions_;
    01167   bool anyProhibited_;
    01169
    01180
    01181   int *usefulRowInt_ ;
    01183   double *usefulRowDouble_ ;
    01185   int *usefulColumnInt_ ;
    01187   double *usefulColumnDouble_ ;
    01189   double *randomNumber_ ;
    01190
    01192   int *infiniteUp_ ;
    01194   double *sumUp_ ;
    01196   int *infiniteDown_ ;
    01198   double *sumDown_ ;
    01200
    01212   int recomputeSums(int whichRow) ;
    01213
    01215   void initializeStuff() ;
    01217   void deleteStuff() ;
    01218
    01221
    01227   void initColsToDo () ;
    01228
    01234   int stepColsToDo () ;
    01235
    01237   inline int numberColsToDo()
    01238   { return (numberColsToDo_) ; }
    01239
    01241   inline bool colChanged(int i) const {
    01242     return (colChanged_[i]&1)!=0;
    01243   }
    01245   inline void unsetColChanged(int i) {
    01246     colChanged_[i] = static_cast<unsigned char>(colChanged_[i] & (~1)) ;
    01247   }
    01249   inline void setColChanged(int i) {
    01250     colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (1)) ;
    01251   }
    01253   inline void addCol(int i) {
    01254     if ((colChanged_[i]&1)==0) {
    01255       colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (1)) ;
    01256       nextColsToDo_[numberNextColsToDo_++] = i;
    01257     }
    01258   }
    01260   inline bool colProhibited(int i) const {
    01261     return (colChanged_[i]&2)!=0;
    01262   }
    01269   inline bool colProhibited2(int i) const {
    01270     if (!anyProhibited_)
    01271       return false;
    01272     else
    01273       return (colChanged_[i]&2)!=0;
    01274   }
    01276   inline void setColProhibited(int i) {
    01277     colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (2)) ;
    01278   }
    01284   inline bool colUsed(int i) const {
    01285     return (colChanged_[i]&4)!=0;
    01286   }
    01288   inline void setColUsed(int i) {
    01289     colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (4)) ;
    01290   }
    01292   inline void unsetColUsed(int i) {
    01293     colChanged_[i] = static_cast<unsigned char>(colChanged_[i] & (~4)) ;
    01294   }
    01296   inline bool colInfinite(int i) const {
    01297     return (colChanged_[i]&8)!=0;
    01298   }
    01300   inline void unsetColInfinite(int i) {
    01301     colChanged_[i] = static_cast<unsigned char>(colChanged_[i] & (~8)) ;
    01302   }
    01304   inline void setColInfinite(int i) {
    01305     colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (8)) ;
    01306   }
    01307
    01313   void initRowsToDo () ;
    01314
    01320   int stepRowsToDo () ;
    01321
    01323   inline int numberRowsToDo()
    01324   { return (numberRowsToDo_) ; }
    01325
    01327   inline bool rowChanged(int i) const {
    01328     return (rowChanged_[i]&1)!=0;
    01329   }
    01331   inline void unsetRowChanged(int i) {
    01332     rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] & (~1)) ;
    01333   }
    01335   inline void setRowChanged(int i) {
    01336     rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] | (1)) ;
    01337   }
    01339   inline void addRow(int i) {
    01340     if ((rowChanged_[i]&1)==0) {
    01341       rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] | (1)) ;
    01342       nextRowsToDo_[numberNextRowsToDo_++] = i;
    01343     }
    01344   }
    01346   inline bool rowProhibited(int i) const {
    01347     return (rowChanged_[i]&2)!=0;
    01348   }
    01355   inline bool rowProhibited2(int i) const {
    01356     if (!anyProhibited_)
    01357       return false;
    01358     else
    01359       return (rowChanged_[i]&2)!=0;
    01360   }
    01362   inline void setRowProhibited(int i) {
    01363     rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] | (2)) ;
    01364   }
    01370   inline bool rowUsed(int i) const {
    01371     return (rowChanged_[i]&4)!=0;
    01372   }
    01374   inline void setRowUsed(int i) {
    01375     rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] | (4)) ;
    01376   }
    01378   inline void unsetRowUsed(int i) {
    01379     rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] & (~4)) ;
    01380   }
    01381
    01382
    01384   inline bool anyProhibited() const
    01385   { return anyProhibited_;}
    01387   inline void setAnyProhibited(bool val = true)
    01388   { anyProhibited_ = val ; }
    01390
    01391 };
    01392
    01421 class CoinPostsolveMatrix : public CoinPrePostsolveMatrix
    01422 {
    01423  public:
    01424
    01431   CoinPostsolveMatrix(int ncols_alloc, int nrows_alloc,
    01432                       CoinBigIndex nelems_alloc) ;
    01433
    01434
    01439   CoinPostsolveMatrix(ClpSimplex * si,
    01440
    01441                    int ncols0,
    01442                    int nrows0,
    01443                    CoinBigIndex nelems0,
    01444
    01445                    double maxmin_,
    01446                    // end prepost members
    01447
    01448                    double *sol,
    01449                    double *acts,
    01450
    01451                    unsigned char *colstat,
    01452                    unsigned char *rowstat);
    01453
    01458   CoinPostsolveMatrix(OsiSolverInterface * si,
    01459
    01460                    int ncols0,
    01461                    int nrows0,
    01462                    CoinBigIndex nelems0,
    01463
    01464                    double maxmin_,
    01465                    // end prepost members
    01466
    01467                    double *sol,
    01468                    double *acts,
    01469
    01470                    unsigned char *colstat,
    01471                    unsigned char *rowstat);
    01472
    01483   void assignPresolveToPostsolve (CoinPresolveMatrix *&preObj) ;
    01484
    01486   ~CoinPostsolveMatrix();
    01487
    01499
    01501   CoinBigIndex free_list_;
    01503   int maxlink_;
    01508   CoinBigIndex *link_;
    01509
    01511
    01519   char *cdone_;
    01520   char *rdone_;
    01522
    01524   void check_nbasic();
    01525
    01526 };
    01527
    01528
    01535
    01540 void presolve_make_memlists(/*CoinBigIndex *starts,*/ int *lengths,
    01541                             presolvehlink *link, int n);
    01542
    01550 bool presolve_expand_major(CoinBigIndex *majstrts, double *majels,
    01551                            int *minndxs, int *majlens,
    01552                            presolvehlink *majlinks, int nmaj, int k) ;
    01553
    01559 inline bool presolve_expand_col(CoinBigIndex *mcstrt, double *colels,
    01560                                 int *hrow, int *hincol,
    01561                                 presolvehlink *clink, int ncols, int colx)
    01562 { return presolve_expand_major(mcstrt,colels,
    01563                                hrow,hincol,clink,ncols,colx) ; }
    01564
    01570 inline bool presolve_expand_row(CoinBigIndex *mrstrt, double *rowels,
    01571                                 int *hcol, int *hinrow,
    01572                                 presolvehlink *rlink, int nrows, int rowx)
    01573 { return presolve_expand_major(mrstrt,rowels,
    01574                                hcol,hinrow,rlink,nrows,rowx) ; }
    01575
    01576
    01585 inline CoinBigIndex presolve_find_minor(int tgt,
    01586                                         CoinBigIndex ks, CoinBigIndex ke,
    01587                                         const int *minndxs)
    01588 { CoinBigIndex k ;
    01589   for (k = ks ; k < ke ; k++)
    01590 #ifndef NDEBUG
    01591   { if (minndxs[k] == tgt)
    01592       return (k) ; }
    01593   DIE("FIND_MINOR") ;
    01594
    01595   abort () ; return -1;
    01596 #else
    01597   { if (minndxs[k] == tgt)
    01598       break ; }
    01599   return (k) ;
    01600 #endif
    01601 }
    01602
    01609 inline CoinBigIndex presolve_find_row(int row, CoinBigIndex kcs,
    01610                                       CoinBigIndex kce, const int *hrow)
    01611 { return presolve_find_minor(row,kcs,kce,hrow) ; }
    01612
    01619 inline CoinBigIndex presolve_find_col(int col, CoinBigIndex krs,
    01620                                       CoinBigIndex kre, const int *hcol)
    01621 { return presolve_find_minor(col,krs,kre,hcol) ; }
    01622
    01623
    01632 CoinBigIndex presolve_find_minor1(int tgt, CoinBigIndex ks, CoinBigIndex ke,
    01633                                   const int *minndxs);
    01634
    01641 inline CoinBigIndex presolve_find_row1(int row, CoinBigIndex kcs,
    01642                                        CoinBigIndex kce, const int *hrow)
    01643 { return presolve_find_minor1(row,kcs,kce,hrow) ; }
    01644
    01651 inline CoinBigIndex presolve_find_col1(int col, CoinBigIndex krs,
    01652                                        CoinBigIndex kre, const int *hcol)
    01653 { return presolve_find_minor1(col,krs,kre,hcol) ; }
    01654
    01663 CoinBigIndex presolve_find_minor2(int tgt, CoinBigIndex ks, int majlen,
    01664                                   const int *minndxs,
    01665                                   const CoinBigIndex *majlinks) ;
    01666
    01674 inline CoinBigIndex presolve_find_row2(int row, CoinBigIndex kcs, int collen,
    01675                                        const int *hrow,
    01676                                        const CoinBigIndex *clinks)
    01677 { return presolve_find_minor2(row,kcs,collen,hrow,clinks) ; }
    01678
    01687 CoinBigIndex presolve_find_minor3(int tgt, CoinBigIndex ks, int majlen,
    01688                                   const int *minndxs,
    01689                                   const CoinBigIndex *majlinks) ;
    01690
    01698 inline CoinBigIndex presolve_find_row3(int row, CoinBigIndex kcs, int collen,
    01699                                        const int *hrow,
    01700                                        const CoinBigIndex *clinks)
    01701 { return presolve_find_minor3(row,kcs,collen,hrow,clinks) ; }
    01702
    01712 inline void presolve_delete_from_major(int majndx, int minndx,
    01713                                 const CoinBigIndex *majstrts,
    01714                                 int *majlens, int *minndxs, double *els)
    01715 {
    01716   const CoinBigIndex ks = majstrts[majndx] ;
    01717   const CoinBigIndex ke = ks+majlens[majndx] ;
    01718
    01719   const CoinBigIndex kmi = presolve_find_minor(minndx,ks,ke,minndxs) ;
    01720
    01721   minndxs[kmi] = minndxs[ke-1] ;
    01722   els[kmi] = els[ke-1] ;
    01723   majlens[majndx]-- ;
    01724
    01725   return ;
    01726 }
    01727
    01734 inline void presolve_delete_many_from_major(int majndx, char *marked,
    01735                                 const CoinBigIndex *majstrts,
    01736                                 int *majlens, int *minndxs, double *els)
    01737 {
    01738   const CoinBigIndex ks = majstrts[majndx] ;
    01739   const CoinBigIndex ke = ks+majlens[majndx] ;
    01740   CoinBigIndex put = ks ;
    01741   for (CoinBigIndex k = ks ; k < ke ; k++) {
    01742     int iMinor = minndxs[k] ;
    01743     if (!marked[iMinor]) {
    01744       minndxs[put] = iMinor ;
    01745       els[put++] = els[k] ;
    01746     } else {
    01747       marked[iMinor] = 0 ;
    01748     }
    01749   }
    01750   majlens[majndx] = put-ks ;
    01751   return ;
    01752 }
    01753
    01764 inline void presolve_delete_from_col(int row, int col,
    01765                                      const CoinBigIndex *mcstrt,
    01766                                      int *hincol, int *hrow, double *colels)
    01767 { presolve_delete_from_major(col,row,mcstrt,hincol,hrow,colels) ; }
    01768
    01779 inline void presolve_delete_from_row(int row, int col,
    01780                                      const CoinBigIndex *mrstrt,
    01781                                      int *hinrow, int *hcol, double *rowels)
    01782 { presolve_delete_from_major(row,col,mrstrt,hinrow,hcol,rowels) ; }
    01783
    01794 void presolve_delete_from_major2 (int majndx, int minndx,
    01795                                   CoinBigIndex *majstrts, int *majlens,
    01796                                   int *minndxs, int *majlinks,
    01797                                    CoinBigIndex *free_listp) ;
    01798
    01809 inline void presolve_delete_from_col2(int row, int col, CoinBigIndex *mcstrt,
    01810                                       int *hincol, int *hrow,
    01811                                       int *clinks, CoinBigIndex *free_listp)
    01812 { presolve_delete_from_major2(col,row,mcstrt,hincol,hrow,clinks,free_listp) ; }
    01813
    01815
    01821
    01833 double *presolve_dupmajor(const double *elems, const int *indices,
    01834                           int length, CoinBigIndex offset, int tgt = -1);
    01835
    01837 void coin_init_random_vec(double *work, int n);
    01838
    01840
    01841
    01842 #endif