CoinUtils trunk
|
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