CoinUtils trunk
CoinPresolveMatrix.hpp
Go to the documentation of this file.
00001 /* $Id$ */
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 
00028 #if defined(_MSC_VER)
00029 // Avoid MS Compiler problem in recognizing type to delete
00030 // by casting to type.
00031 #define deleteAction(array,type) delete [] ((type) array)
00032 #else
00033 #define deleteAction(array,type) delete [] array
00034 #endif
00035 
00040 const double ZTOLDP      = 1e-12;
00041 // But use a different one if we are doing doubletons etc
00042 const double ZTOLDP2      = 1e-10;
00043 //#define PRESOLVE_DEBUG 1
00044 //#define PRESOLVE_CONSISTENCY 1
00045 // Debugging macros/functions
00046 #ifndef PRESOLVE_DETAIL
00047 #define PRESOLVE_DETAIL_PRINT(s) {}
00048 #else
00049 #define PRESOLVE_DETAIL_PRINT(s) s
00050 #endif
00051 #if PRESOLVE_DEBUG || PRESOLVE_CONSISTENCY
00052 #define PRESOLVE_STMT(s)        s
00053 #define PRESOLVEASSERT(x) \
00054   ((x) ? 1 : \
00055         ((std::cerr << "FAILED ASSERTION at line " \
00056                     << __LINE__ << ":  " #x "\n"), abort(), 0))
00057 
00058 inline void DIE(const char *s)  { std::cout<<s; abort(); }
00059 
00060 // This code is used in [cr]done for columns and rows that are present in
00061 // the presolved system.
00062 #define PRESENT_IN_REDUCED      '\377'
00063 
00064 #else
00065 
00066 #define PRESOLVEASSERT(x) {} 
00067 #define PRESOLVE_STMT(s) {}
00068 
00069 inline void DIE(const char *)   {}
00070 
00071 #endif
00072 
00073 inline int ALIGN(int n, int m)  { return (((n + m - 1) / m) * m); }
00074 inline int ALIGN_DOUBLE(int n)  { return ALIGN(n,sizeof(double)); }
00075 
00076 // Plus infinity
00077 #ifndef COIN_DBL_MAX
00078 #define COIN_DBL_MAX DBL_MAX
00079 #endif
00080 #define PRESOLVE_INF COIN_DBL_MAX
00081 
00082 class CoinPostsolveMatrix;
00083 
00084 // Note 77
00085 // "Members and bases are constructed in order of declaration
00086 //  in the class and destroyed in the reverse order."  C++PL 3d Ed. p. 307
00087 //
00088 // That's why I put integer members (such as ncols) before the array members;
00089 // I like to use those integer values during initialization.
00090 // NOT ANYMORE
00091 
00141 class CoinPresolveAction
00142 {
00143  public:
00150   static void throwCoinError(const char *error, const char *ps_routine)
00151   { throw CoinError(error, ps_routine, "CoinPresolve"); } 
00152 
00153 
00158   const CoinPresolveAction *next;
00159   
00165   CoinPresolveAction(const CoinPresolveAction *next) : next(next) {}
00167   inline void setNext(const CoinPresolveAction *nextAction)
00168   { next = nextAction;}
00169 
00174   virtual const char *name() const = 0;
00175 
00179   virtual void postsolve(CoinPostsolveMatrix *prob) const = 0;
00180 
00182   virtual ~CoinPresolveAction() {}
00183 };
00184 
00185 /*
00186   These are needed for OSI-aware constructors associated with
00187   CoinPrePostsolveMatrix, CoinPresolveMatrix, and CoinPostsolveMatrix.
00188 */
00189   class ClpSimplex;
00190   class OsiSolverInterface;
00191 
00192 /*
00193   CoinWarmStartBasis is required for methods in CoinPrePostsolveMatrix
00194   that accept/return a CoinWarmStartBasis object.
00195 */
00196   class CoinWarmStartBasis ;
00197 
00248 class CoinPrePostsolveMatrix
00249 {
00250  public:
00251 
00261   CoinPrePostsolveMatrix(int ncols_alloc, int nrows_alloc,
00262                          CoinBigIndex nelems_alloc) ;
00263 
00268   CoinPrePostsolveMatrix(const OsiSolverInterface * si,
00269                         int ncols_,
00270                         int nrows_,
00271                         CoinBigIndex nelems_);
00272 
00277   CoinPrePostsolveMatrix(const ClpSimplex * si,
00278                         int ncols_,
00279                         int nrows_,
00280                         CoinBigIndex nelems_,
00281                          double bulkRatio);
00282 
00284   ~CoinPrePostsolveMatrix();
00286 
00296   enum Status {
00297     isFree = 0x00,
00298     basic = 0x01,
00299     atUpperBound = 0x02,
00300     atLowerBound = 0x03,
00301     superBasic = 0x04
00302   };
00303 
00310   
00312   inline void setRowStatus(int sequence, Status status)
00313   {
00314     unsigned char & st_byte = rowstat_[sequence];
00315     st_byte = static_cast<unsigned char>(st_byte & (~7)) ;
00316     st_byte = static_cast<unsigned char>(st_byte | status) ;
00317   }
00319   inline Status getRowStatus(int sequence) const
00320   {return static_cast<Status> (rowstat_[sequence]&7);}
00322   inline bool rowIsBasic(int sequence) const
00323   {return (static_cast<Status> (rowstat_[sequence]&7)==basic);}
00325   inline void setColumnStatus(int sequence, Status status)
00326   {
00327     unsigned char & st_byte = colstat_[sequence];
00328     st_byte = static_cast<unsigned char>(st_byte & (~7)) ;
00329     st_byte = static_cast<unsigned char>(st_byte | status) ;
00330 
00331 #   ifdef PRESOLVE_DEBUG
00332     switch (status)
00333     { case isFree:
00334       { if (clo_[sequence] > -PRESOLVE_INF || cup_[sequence] < PRESOLVE_INF)
00335         { std::cout << "Bad status: Var " << sequence
00336                     << " isFree, lb = " << clo_[sequence]
00337                     << ", ub = " << cup_[sequence] << std::endl ; }
00338         break ; }
00339       case basic:
00340       { break ; }
00341       case atUpperBound:
00342       { if (cup_[sequence] >= PRESOLVE_INF)
00343         { std::cout << "Bad status: Var " << sequence
00344                     << " atUpperBound, lb = " << clo_[sequence]
00345                     << ", ub = " << cup_[sequence] << std::endl ; }
00346         break ; }
00347       case atLowerBound:
00348       { if (clo_[sequence] <= -PRESOLVE_INF)
00349         { std::cout << "Bad status: Var " << sequence
00350                     << " atLowerBound, lb = " << clo_[sequence]
00351                     << ", ub = " << cup_[sequence] << std::endl ; }
00352         break ; }
00353       case superBasic:
00354       { if (clo_[sequence] <= -PRESOLVE_INF && cup_[sequence] >= PRESOLVE_INF)
00355         { std::cout << "Bad status: Var " << sequence
00356                     << " superBasic, lb = " << clo_[sequence]
00357                     << ", ub = " << cup_[sequence] << std::endl ; }
00358         break ; }
00359       default:
00360       { assert(false) ;
00361         break ; } }
00362 #   endif
00363   }
00365   inline Status getColumnStatus(int sequence) const
00366   {return static_cast<Status> (colstat_[sequence]&7);}
00368   inline bool columnIsBasic(int sequence) const
00369   {return (static_cast<Status> (colstat_[sequence]&7)==basic);}
00373   void setRowStatusUsingValue(int iRow);
00377   void setColumnStatusUsingValue(int iColumn);
00379   void setStructuralStatus(const char *strucStatus, int lenParam) ;
00381   void setArtificialStatus(const char *artifStatus, int lenParam) ;
00383   void setStatus(const CoinWarmStartBasis *basis) ;
00385   CoinWarmStartBasis *getStatus() ;
00389   const char *columnStatusString(int j) const ;
00393   const char *rowStatusString(int i) const ;
00395 
00403 
00404   void setObjOffset(double offset) ;
00409   void setObjSense(double objSense) ;
00411   void setPrimalTolerance(double primTol) ;
00413   void setDualTolerance(double dualTol) ;
00415   void setColLower(const double *colLower, int lenParam) ;
00417   void setColUpper(const double *colUpper, int lenParam) ;
00419   void setColSolution(const double *colSol, int lenParam) ;
00421   void setCost(const double *cost, int lenParam) ;
00423   void setReducedCost(const double *redCost, int lenParam) ;
00425   void setRowLower(const double *rowLower, int lenParam) ;
00427   void setRowUpper(const double *rowUpper, int lenParam) ;
00429   void setRowPrice(const double *rowSol, int lenParam) ;
00431   void setRowActivity(const double *rowAct, int lenParam) ;
00433 
00436 
00437   inline int getNumCols()
00438   { return (ncols_) ; } 
00440   inline int getNumRows()
00441   { return (nrows_) ; } 
00443   inline int getNumElems()
00444   { return (nelems_) ; } 
00446   inline const CoinBigIndex *getColStarts() const
00447   { return (mcstrt_) ; } 
00449   inline const int *getColLengths() const
00450   { return (hincol_) ; } 
00452   inline const int *getRowIndicesByCol() const
00453   { return (hrow_) ; } 
00455   inline const double *getElementsByCol() const
00456   { return (colels_) ; } 
00458   inline const double *getColLower() const
00459   { return (clo_) ; } 
00461   inline const double *getColUpper() const
00462   { return (cup_) ; } 
00464   inline const double *getCost() const
00465   { return (cost_) ; } 
00467   inline const double *getRowLower() const
00468   { return (rlo_) ; } 
00470   inline const double *getRowUpper() const
00471   { return (rup_) ; } 
00473   inline const double *getColSolution() const
00474   { return (sol_) ; }
00476   inline const double *getRowActivity() const
00477   { return (acts_) ; }
00479   inline const double *getRowPrice() const
00480   { return (rowduals_) ; }
00482   inline const double *getReducedCost() const
00483   { return (rcosts_) ; }
00485   inline int countEmptyCols()
00486   { int empty = 0 ;
00487     for (int i = 0 ; i < ncols_ ; i++) if (hincol_[i] == 0) empty++ ;
00488     return (empty) ; }
00490 
00491 
00494 
00495   inline CoinMessageHandler *messageHandler() const 
00496   { return handler_; }
00502   inline void setMessageHandler(CoinMessageHandler *handler)
00503   { if (defaultHandler_ == true)
00504     { delete handler_ ;
00505       defaultHandler_ = false ; }
00506     handler_ = handler ; }
00508   inline CoinMessages messages() const 
00509   { return messages_; }
00511 
00521 
00523   int ncols_;
00525   int nrows_;
00527   CoinBigIndex nelems_;
00528 
00530   int ncols0_;
00532   int nrows0_ ;
00534   CoinBigIndex nelems0_ ;
00543   CoinBigIndex bulk0_ ;
00545   double bulkRatio_;
00547 
00556 
00557   CoinBigIndex *mcstrt_;
00559   int *hincol_;
00561   int *hrow_;
00563   double *colels_;
00564 
00566   double *cost_;
00568   double originalOffset_;
00569 
00571   double *clo_;
00573   double *cup_;
00574 
00576   double *rlo_;
00578   double *rup_;
00579 
00586   int * originalColumn_;
00593   int * originalRow_;
00594 
00596   double ztolzb_;
00598   double ztoldj_;
00599 
00601   double maxmin_;
00603 
00624   double *sol_;
00630   double *rowduals_;
00636   double *acts_;
00642   double *rcosts_;
00643 
00650   unsigned char *colstat_;
00651 
00658   unsigned char *rowstat_;
00660 
00669 
00670   CoinMessageHandler *handler_; 
00672   bool defaultHandler_;
00674   CoinMessage messages_; 
00676 
00677 };
00678 
00679 
00704 class presolvehlink
00705 { public:
00706   int pre, suc;
00707 } ;
00708 
00709 #define NO_LINK -66666666
00710 
00716 inline void PRESOLVE_REMOVE_LINK(presolvehlink *link, int i)
00717 { 
00718   int ipre = link[i].pre;
00719   int isuc = link[i].suc;
00720   if (ipre >= 0) {
00721     link[ipre].suc = isuc;
00722   }
00723   if (isuc >= 0) {
00724     link[isuc].pre = ipre;
00725   }
00726   link[i].pre = NO_LINK, link[i].suc = NO_LINK;
00727 }
00728 
00734 inline void PRESOLVE_INSERT_LINK(presolvehlink *link, int i, int j)
00735 {
00736   int isuc = link[j].suc;
00737   link[j].suc = i;
00738   link[i].pre = j;
00739   if (isuc >= 0) {
00740     link[isuc].pre = i;
00741   }
00742   link[i].suc = isuc;
00743 }
00744 
00756 inline void PRESOLVE_MOVE_LINK(presolvehlink *link, int i, int j)
00757 { 
00758   int ipre = link[i].pre;
00759   int isuc = link[i].suc;
00760   if (ipre >= 0) {
00761     link[ipre].suc = j;
00762   }
00763   if (isuc >= 0) {
00764     link[isuc].pre = j;
00765   }
00766   link[i].pre = NO_LINK, link[i].suc = NO_LINK;
00767 }
00768 
00769 
00791 class CoinPresolveMatrix : public CoinPrePostsolveMatrix
00792 {
00793  public:
00794 
00801   CoinPresolveMatrix(int ncols_alloc, int nrows_alloc,
00802                      CoinBigIndex nelems_alloc) ;
00803 
00808   CoinPresolveMatrix(int ncols0,
00809                     double maxmin,
00810                     // end prepost members
00811 
00812                     ClpSimplex * si,
00813 
00814                     // rowrep
00815                     int nrows,
00816                     CoinBigIndex nelems,
00817                  bool doStatus,
00818                  double nonLinearVariable,
00819                      double bulkRatio);
00820 
00822   void update_model(ClpSimplex * si,
00823                             int nrows0,
00824                             int ncols0,
00825                             CoinBigIndex nelems0);
00830   CoinPresolveMatrix(int ncols0,
00831                      double maxmin,
00832                      // end prepost members
00833                      OsiSolverInterface * si,
00834                      // rowrep
00835                      int nrows,
00836                      CoinBigIndex nelems,
00837                      bool doStatus,
00838                      double nonLinearVariable,
00839                      const char * prohibited,
00840                      const char * rowProhibited=NULL);
00841 
00843   void update_model(OsiSolverInterface * si,
00844                             int nrows0,
00845                             int ncols0,
00846                             CoinBigIndex nelems0);
00847 
00849   ~CoinPresolveMatrix();
00850 
00856   friend void assignPresolveToPostsolve (CoinPresolveMatrix *&preObj) ;
00857 
00866   void setMatrix(const CoinPackedMatrix *mtx) ;
00867 
00869   inline int countEmptyRows()
00870   { int empty = 0 ;
00871     for (int i = 0 ; i < nrows_ ; i++) if (hinrow_[i] == 0) empty++ ;
00872     return (empty) ; }
00873 
00879   inline void setVariableType(int i, int variableType)
00880   { if (integerType_ == 0) integerType_ = new unsigned char [ncols0_] ;
00881     integerType_[i] = static_cast<unsigned char>(variableType) ; }
00882 
00888   void setVariableType(const unsigned char *variableType, int lenParam) ;
00889 
00895   void setVariableType (bool allIntegers, int lenParam) ;
00896 
00898   inline void setAnyInteger (bool anyInteger = true)
00899   { anyInteger_ = anyInteger ; }
00901 
00905 
00907   inline const CoinBigIndex *getRowStarts() const
00908   { return (mrstrt_) ; }
00910   inline const int *getColIndicesByRow() const
00911   { return (hcol_) ; }
00913   inline const double *getElementsByRow() const
00914   { return (rowels_) ; }
00915 
00921   inline bool isInteger (int i) const
00922   { if (integerType_ == 0)
00923     { return (anyInteger_) ; }
00924     else
00925     if (integerType_[i] == 1)
00926     { return (true) ; }
00927     else
00928     { return (false) ; } }
00929 
00934   inline bool anyInteger () const
00935   { return (anyInteger_) ; }
00937   inline int presolveOptions() const
00938   { return presolveOptions_;}
00940   inline void setPresolveOptions(int value)
00941   { presolveOptions_=value;}
00943 
00951 
00952   presolvehlink *clink_;
00954   presolvehlink *rlink_;
00956 
00958   double dobias_;
00959 
00961   inline void change_bias(double change_amount)
00962   {
00963     dobias_ += change_amount;
00964   #if PRESOLVE_DEBUG
00965     assert(fabs(change_amount)<1.0e50);
00966   #endif
00967     if (change_amount)
00968       PRESOLVE_STMT(printf("changing bias by %g to %g\n",
00969                             change_amount, dobias_));
00970   }
00971 
00980 
00981   CoinBigIndex *mrstrt_;
00983   int *hinrow_;
00985   double *rowels_;
00987   int *hcol_;
00989 
00991   unsigned char *integerType_;
00997   bool anyInteger_ ;
00999   bool tuning_;
01001   void statistics();
01003   double startTime_;
01004 
01006   double feasibilityTolerance_;
01008   inline double feasibilityTolerance()
01009   { return (feasibilityTolerance_) ; }
01011   inline void setFeasibilityTolerance (double val)
01012   { feasibilityTolerance_ = val ; }
01013 
01019   int status_;
01021   inline int status()
01022   { return (status_) ; }
01024   inline void setStatus(int status)
01025   { status_ = (status&0x3) ; }
01026 
01032   int pass_;
01034   inline void setPass (int pass = 0)
01035   { pass_ = pass ; }
01036 
01041   int maxSubstLevel_;
01043   inline void setMaximumSubstitutionLevel (int level)
01044   { maxSubstLevel_ = level ; }
01045 
01046 
01069   unsigned char * colChanged_;
01071   int * colsToDo_;
01073   int numberColsToDo_;
01075   int * nextColsToDo_;
01077   int numberNextColsToDo_;
01078 
01088   unsigned char * rowChanged_;
01090   int * rowsToDo_;
01092   int numberRowsToDo_;
01094   int * nextRowsToDo_;
01096   int numberNextRowsToDo_;
01105   int presolveOptions_;
01111   bool anyProhibited_;
01113   int * usefulRowInt_;
01115   double * usefulRowDouble_;
01117   int * usefulColumnInt_;
01119   double * usefulColumnDouble_;
01121   double * randomNumber_;
01123   int * infiniteUp_;
01125   double * sumUp_;
01127   int * infiniteDown_;
01129   double * sumDown_;
01131 
01134 
01140   void initColsToDo () ;
01141 
01147   int stepColsToDo () ;
01148 
01150   inline int numberColsToDo()
01151   { return (numberColsToDo_) ; }
01152 
01154   inline bool colChanged(int i) const {
01155     return (colChanged_[i]&1)!=0;
01156   }
01158   inline void unsetColChanged(int i) {
01159     colChanged_[i] = static_cast<unsigned char>(colChanged_[i] & (~1)) ;
01160   }
01162   inline void setColChanged(int i) {
01163     colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (1)) ;
01164   }
01166   inline void addCol(int i) {
01167     if ((colChanged_[i]&1)==0) {
01168       colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (1)) ;
01169       nextColsToDo_[numberNextColsToDo_++] = i;
01170     }
01171   }
01173   inline bool colProhibited(int i) const {
01174     return (colChanged_[i]&2)!=0;
01175   }
01182   inline bool colProhibited2(int i) const {
01183     if (!anyProhibited_)
01184       return false;
01185     else
01186       return (colChanged_[i]&2)!=0;
01187   }
01189   inline void setColProhibited(int i) {
01190     colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (2)) ;
01191   }
01197   inline bool colUsed(int i) const {
01198     return (colChanged_[i]&4)!=0;
01199   }
01201   inline void setColUsed(int i) {
01202     colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (4)) ;
01203   }
01205   inline void unsetColUsed(int i) {
01206     colChanged_[i] = static_cast<unsigned char>(colChanged_[i] & (~4)) ;
01207   }
01208 
01214   void initRowsToDo () ;
01215 
01221   int stepRowsToDo () ;
01222 
01224   inline int numberRowsToDo()
01225   { return (numberRowsToDo_) ; }
01226 
01228   inline bool rowChanged(int i) const {
01229     return (rowChanged_[i]&1)!=0;
01230   }
01232   inline void unsetRowChanged(int i) {
01233     rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] & (~1)) ;
01234   }
01236   inline void setRowChanged(int i) {
01237     rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] | (1)) ;
01238   }
01240   inline void addRow(int i) {
01241     if ((rowChanged_[i]&1)==0) {
01242       rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] | (1)) ;
01243       nextRowsToDo_[numberNextRowsToDo_++] = i;
01244     }
01245   }
01247   inline bool rowProhibited(int i) const {
01248     return (rowChanged_[i]&2)!=0;
01249   }
01256   inline bool rowProhibited2(int i) const {
01257     if (!anyProhibited_)
01258       return false;
01259     else
01260       return (rowChanged_[i]&2)!=0;
01261   }
01263   inline void setRowProhibited(int i) {
01264     rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] | (2)) ;
01265   }
01271   inline bool rowUsed(int i) const {
01272     return (rowChanged_[i]&4)!=0;
01273   }
01275   inline void setRowUsed(int i) {
01276     rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] | (4)) ;
01277   }
01279   inline void unsetRowUsed(int i) {
01280     rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] & (~4)) ;
01281   }
01282 
01283 
01285   inline bool anyProhibited() const
01286   { return anyProhibited_;}
01288   inline void setAnyProhibited(bool val = true)
01289   { anyProhibited_ = val ; }
01292   int recomputeSums(int iRow);
01294   int initializeStuff();
01296   void deleteStuff();
01298 
01299 };
01300 
01325 class CoinPostsolveMatrix : public CoinPrePostsolveMatrix
01326 {
01327  public:
01328 
01335   CoinPostsolveMatrix(int ncols_alloc, int nrows_alloc,
01336                       CoinBigIndex nelems_alloc) ;
01337 
01338 
01343   CoinPostsolveMatrix(ClpSimplex * si,
01344 
01345                    int ncols0,
01346                    int nrows0,
01347                    CoinBigIndex nelems0,
01348                      
01349                    double maxmin_,
01350                    // end prepost members
01351 
01352                    double *sol,
01353                    double *acts,
01354 
01355                    unsigned char *colstat,
01356                    unsigned char *rowstat);
01357 
01362   CoinPostsolveMatrix(OsiSolverInterface * si,
01363 
01364                    int ncols0,
01365                    int nrows0,
01366                    CoinBigIndex nelems0,
01367                      
01368                    double maxmin_,
01369                    // end prepost members
01370 
01371                    double *sol,
01372                    double *acts,
01373 
01374                    unsigned char *colstat,
01375                    unsigned char *rowstat);
01376 
01387   void assignPresolveToPostsolve (CoinPresolveMatrix *&preObj) ;
01388 
01390   ~CoinPostsolveMatrix();
01391 
01403 
01405   CoinBigIndex free_list_;
01407   int maxlink_;
01412   CoinBigIndex *link_;
01413 
01415 
01423   char *cdone_;
01424   char *rdone_;
01426 
01428   void check_nbasic();
01429 
01430 };
01431 
01432 
01433 #define PRESOLVEFINITE(n)       (-PRESOLVE_INF < (n) && (n) < PRESOLVE_INF)
01434 
01441 
01446 void presolve_make_memlists(/*CoinBigIndex *starts,*/ int *lengths,
01447                             presolvehlink *link, int n);
01448 
01456 bool presolve_expand_major(CoinBigIndex *majstrts, double *majels,
01457                            int *minndxs, int *majlens,
01458                            presolvehlink *majlinks, int nmaj, int k) ;
01459 
01465 inline bool presolve_expand_col(CoinBigIndex *mcstrt, double *colels,
01466                                 int *hrow, int *hincol,
01467                                 presolvehlink *clink, int ncols, int colx)
01468 { return presolve_expand_major(mcstrt,colels,
01469                                hrow,hincol,clink,ncols,colx) ; }
01470 
01476 inline bool presolve_expand_row(CoinBigIndex *mrstrt, double *rowels,
01477                                 int *hcol, int *hinrow,
01478                                 presolvehlink *rlink, int nrows, int rowx)
01479 { return presolve_expand_major(mrstrt,rowels,
01480                                hcol,hinrow,rlink,nrows,rowx) ; }
01481 
01482 
01491 inline CoinBigIndex presolve_find_minor(int tgt, CoinBigIndex ks, CoinBigIndex ke,
01492                                  const int *minndxs)
01493 { CoinBigIndex k ;
01494   for (k = ks ; k < ke ; k++)
01495 #ifndef NDEBUG
01496   { if (minndxs[k] == tgt)
01497       return (k) ; }
01498   DIE("FIND_MINOR") ;
01499 
01500   abort () ; return -1;
01501 #else
01502   { if (minndxs[k] == tgt)
01503       break ; }
01504   return (k) ;
01505 #endif
01506 }
01507 
01514 inline CoinBigIndex presolve_find_row(int row, CoinBigIndex kcs,
01515                                       CoinBigIndex kce, const int *hrow)
01516 { return presolve_find_minor(row,kcs,kce,hrow) ; }
01517 
01524 inline CoinBigIndex presolve_find_col(int col, CoinBigIndex krs,
01525                                       CoinBigIndex kre, const int *hcol)
01526 { return presolve_find_minor(col,krs,kre,hcol) ; }
01527 
01528 
01537 CoinBigIndex presolve_find_minor1(int tgt, CoinBigIndex ks, CoinBigIndex ke,
01538                                   const int *minndxs);
01539 
01546 inline CoinBigIndex presolve_find_row1(int row, CoinBigIndex kcs,
01547                                        CoinBigIndex kce, const int *hrow)
01548 { return presolve_find_minor1(row,kcs,kce,hrow) ; } 
01549 
01556 inline CoinBigIndex presolve_find_col1(int col, CoinBigIndex krs,
01557                                        CoinBigIndex kre, const int *hcol)
01558 { return presolve_find_minor1(col,krs,kre,hcol) ; } 
01559 
01568 CoinBigIndex presolve_find_minor2(int tgt, CoinBigIndex ks, int majlen,
01569                                   const int *minndxs,
01570                                   const CoinBigIndex *majlinks) ;
01571 
01579 inline CoinBigIndex presolve_find_row2(int row, CoinBigIndex kcs, int collen,
01580                                        const int *hrow,
01581                                        const CoinBigIndex *clinks)
01582 { return presolve_find_minor2(row,kcs,collen,hrow,clinks) ; }
01583 
01592 CoinBigIndex presolve_find_minor3(int tgt, CoinBigIndex ks, int majlen,
01593                                   const int *minndxs,
01594                                   const CoinBigIndex *majlinks) ;
01595 
01603 inline CoinBigIndex presolve_find_row3(int row, CoinBigIndex kcs, int collen,
01604                                        const int *hrow,
01605                                        const CoinBigIndex *clinks)
01606 { return presolve_find_minor3(row,kcs,collen,hrow,clinks) ; }
01607 
01617 inline void presolve_delete_from_major(int majndx, int minndx,
01618                                 const CoinBigIndex *majstrts,
01619                                 int *majlens, int *minndxs, double *els) 
01620 { CoinBigIndex ks = majstrts[majndx] ;
01621   CoinBigIndex ke = ks + majlens[majndx] ;
01622 
01623   CoinBigIndex kmi = presolve_find_minor(minndx,ks,ke,minndxs) ;
01624 
01625   minndxs[kmi] = minndxs[ke-1] ;
01626   els[kmi] = els[ke-1] ;
01627   majlens[majndx]-- ;
01628   
01629   return ; }
01630 // Delete all marked from major (and zero marked)
01631 inline void presolve_delete_many_from_major(int majndx, char * marked,
01632                                 const CoinBigIndex *majstrts,
01633                                 int *majlens, int *minndxs, double *els) 
01634 { 
01635   CoinBigIndex ks = majstrts[majndx] ;
01636   CoinBigIndex ke = ks + majlens[majndx] ;
01637   CoinBigIndex put=ks;
01638   for (CoinBigIndex k=ks;k<ke;k++) {
01639     int iMinor = minndxs[k];
01640     if (!marked[iMinor]) {
01641       minndxs[put]=iMinor;
01642       els[put++]=els[k];
01643     } else {
01644       marked[iMinor]=0;
01645     }
01646   } 
01647   majlens[majndx] = put-ks ;
01648   return ;
01649 }
01650 
01661 inline void presolve_delete_from_col(int row, int col,
01662                                      const CoinBigIndex *mcstrt,
01663                                      int *hincol, int *hrow, double *colels)
01664 { presolve_delete_from_major(col,row,mcstrt,hincol,hrow,colels) ; }
01665 
01676 inline void presolve_delete_from_row(int row, int col,
01677                                      const CoinBigIndex *mrstrt,
01678                                      int *hinrow, int *hcol, double *rowels)
01679 { presolve_delete_from_major(row,col,mrstrt,hinrow,hcol,rowels) ; }
01680 
01691 void presolve_delete_from_major2 (int majndx, int minndx,
01692                                   CoinBigIndex *majstrts, int *majlens,
01693                                   int *minndxs, /*double *els,*/ int *majlinks,
01694                                    CoinBigIndex *free_listp) ;
01695 
01706 inline void presolve_delete_from_col2(int row, int col, CoinBigIndex *mcstrt,
01707                                       int *hincol, int *hrow,
01708                                       /*double *colels,*/ int *clinks,
01709                                       CoinBigIndex *free_listp)
01710 { presolve_delete_from_major2(col,row,mcstrt,hincol,hrow,/*colels,*/clinks,
01711                               free_listp) ; }
01712 
01714 
01720 
01732 double *presolve_dupmajor(const double *elems, const int *indices,
01733                           int length, CoinBigIndex offset, int tgt = -1);
01735 void coin_init_random_vec(double *work, int n);
01737 
01738 
01739 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines