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 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 00098 00099 #define PRESOLVE_SMALL_INF 1.0e20 00100 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_; 01160 int presolveOptions_; 01166 bool anyProhibited_; 01168 01179 01180 int *usefulRowInt_ ; 01182 double *usefulRowDouble_ ; 01184 int *usefulColumnInt_ ; 01186 double *usefulColumnDouble_ ; 01188 double *randomNumber_ ; 01189 01191 int *infiniteUp_ ; 01193 double *sumUp_ ; 01195 int *infiniteDown_ ; 01197 double *sumDown_ ; 01199 01211 int recomputeSums(int whichRow) ; 01212 01214 void initializeStuff() ; 01216 void deleteStuff() ; 01217 01220 01226 void initColsToDo () ; 01227 01233 int stepColsToDo () ; 01234 01236 inline int numberColsToDo() 01237 { return (numberColsToDo_) ; } 01238 01240 inline bool colChanged(int i) const { 01241 return (colChanged_[i]&1)!=0; 01242 } 01244 inline void unsetColChanged(int i) { 01245 colChanged_[i] = static_cast<unsigned char>(colChanged_[i] & (~1)) ; 01246 } 01248 inline void setColChanged(int i) { 01249 colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (1)) ; 01250 } 01252 inline void addCol(int i) { 01253 if ((colChanged_[i]&1)==0) { 01254 colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (1)) ; 01255 nextColsToDo_[numberNextColsToDo_++] = i; 01256 } 01257 } 01259 inline bool colProhibited(int i) const { 01260 return (colChanged_[i]&2)!=0; 01261 } 01268 inline bool colProhibited2(int i) const { 01269 if (!anyProhibited_) 01270 return false; 01271 else 01272 return (colChanged_[i]&2)!=0; 01273 } 01275 inline void setColProhibited(int i) { 01276 colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (2)) ; 01277 } 01283 inline bool colUsed(int i) const { 01284 return (colChanged_[i]&4)!=0; 01285 } 01287 inline void setColUsed(int i) { 01288 colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (4)) ; 01289 } 01291 inline void unsetColUsed(int i) { 01292 colChanged_[i] = static_cast<unsigned char>(colChanged_[i] & (~4)) ; 01293 } 01295 inline bool colInfinite(int i) const { 01296 return (colChanged_[i]&8)!=0; 01297 } 01299 inline void unsetColInfinite(int i) { 01300 colChanged_[i] = static_cast<unsigned char>(colChanged_[i] & (~8)) ; 01301 } 01303 inline void setColInfinite(int i) { 01304 colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (8)) ; 01305 } 01306 01312 void initRowsToDo () ; 01313 01319 int stepRowsToDo () ; 01320 01322 inline int numberRowsToDo() 01323 { return (numberRowsToDo_) ; } 01324 01326 inline bool rowChanged(int i) const { 01327 return (rowChanged_[i]&1)!=0; 01328 } 01330 inline void unsetRowChanged(int i) { 01331 rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] & (~1)) ; 01332 } 01334 inline void setRowChanged(int i) { 01335 rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] | (1)) ; 01336 } 01338 inline void addRow(int i) { 01339 if ((rowChanged_[i]&1)==0) { 01340 rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] | (1)) ; 01341 nextRowsToDo_[numberNextRowsToDo_++] = i; 01342 } 01343 } 01345 inline bool rowProhibited(int i) const { 01346 return (rowChanged_[i]&2)!=0; 01347 } 01354 inline bool rowProhibited2(int i) const { 01355 if (!anyProhibited_) 01356 return false; 01357 else 01358 return (rowChanged_[i]&2)!=0; 01359 } 01361 inline void setRowProhibited(int i) { 01362 rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] | (2)) ; 01363 } 01369 inline bool rowUsed(int i) const { 01370 return (rowChanged_[i]&4)!=0; 01371 } 01373 inline void setRowUsed(int i) { 01374 rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] | (4)) ; 01375 } 01377 inline void unsetRowUsed(int i) { 01378 rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] & (~4)) ; 01379 } 01380 01381 01383 inline bool anyProhibited() const 01384 { return anyProhibited_;} 01386 inline void setAnyProhibited(bool val = true) 01387 { anyProhibited_ = val ; } 01389 01390 }; 01391 01420 class CoinPostsolveMatrix : public CoinPrePostsolveMatrix 01421 { 01422 public: 01423 01430 CoinPostsolveMatrix(int ncols_alloc, int nrows_alloc, 01431 CoinBigIndex nelems_alloc) ; 01432 01433 01438 CoinPostsolveMatrix(ClpSimplex * si, 01439 01440 int ncols0, 01441 int nrows0, 01442 CoinBigIndex nelems0, 01443 01444 double maxmin_, 01445 // end prepost members 01446 01447 double *sol, 01448 double *acts, 01449 01450 unsigned char *colstat, 01451 unsigned char *rowstat); 01452 01457 CoinPostsolveMatrix(OsiSolverInterface * si, 01458 01459 int ncols0, 01460 int nrows0, 01461 CoinBigIndex nelems0, 01462 01463 double maxmin_, 01464 // end prepost members 01465 01466 double *sol, 01467 double *acts, 01468 01469 unsigned char *colstat, 01470 unsigned char *rowstat); 01471 01482 void assignPresolveToPostsolve (CoinPresolveMatrix *&preObj) ; 01483 01485 ~CoinPostsolveMatrix(); 01486 01498 01500 CoinBigIndex free_list_; 01502 int maxlink_; 01507 CoinBigIndex *link_; 01508 01510 01518 char *cdone_; 01519 char *rdone_; 01521 01523 void check_nbasic(); 01524 01525 }; 01526 01527 01534 01539 void presolve_make_memlists(/*CoinBigIndex *starts,*/ int *lengths, 01540 presolvehlink *link, int n); 01541 01549 bool presolve_expand_major(CoinBigIndex *majstrts, double *majels, 01550 int *minndxs, int *majlens, 01551 presolvehlink *majlinks, int nmaj, int k) ; 01552 01558 inline bool presolve_expand_col(CoinBigIndex *mcstrt, double *colels, 01559 int *hrow, int *hincol, 01560 presolvehlink *clink, int ncols, int colx) 01561 { return presolve_expand_major(mcstrt,colels, 01562 hrow,hincol,clink,ncols,colx) ; } 01563 01569 inline bool presolve_expand_row(CoinBigIndex *mrstrt, double *rowels, 01570 int *hcol, int *hinrow, 01571 presolvehlink *rlink, int nrows, int rowx) 01572 { return presolve_expand_major(mrstrt,rowels, 01573 hcol,hinrow,rlink,nrows,rowx) ; } 01574 01575 01584 inline CoinBigIndex presolve_find_minor(int tgt, 01585 CoinBigIndex ks, CoinBigIndex ke, 01586 const int *minndxs) 01587 { CoinBigIndex k ; 01588 for (k = ks ; k < ke ; k++) 01589 #ifndef NDEBUG 01590 { if (minndxs[k] == tgt) 01591 return (k) ; } 01592 DIE("FIND_MINOR") ; 01593 01594 abort () ; return -1; 01595 #else 01596 { if (minndxs[k] == tgt) 01597 break ; } 01598 return (k) ; 01599 #endif 01600 } 01601 01608 inline CoinBigIndex presolve_find_row(int row, CoinBigIndex kcs, 01609 CoinBigIndex kce, const int *hrow) 01610 { return presolve_find_minor(row,kcs,kce,hrow) ; } 01611 01618 inline CoinBigIndex presolve_find_col(int col, CoinBigIndex krs, 01619 CoinBigIndex kre, const int *hcol) 01620 { return presolve_find_minor(col,krs,kre,hcol) ; } 01621 01622 01631 CoinBigIndex presolve_find_minor1(int tgt, CoinBigIndex ks, CoinBigIndex ke, 01632 const int *minndxs); 01633 01640 inline CoinBigIndex presolve_find_row1(int row, CoinBigIndex kcs, 01641 CoinBigIndex kce, const int *hrow) 01642 { return presolve_find_minor1(row,kcs,kce,hrow) ; } 01643 01650 inline CoinBigIndex presolve_find_col1(int col, CoinBigIndex krs, 01651 CoinBigIndex kre, const int *hcol) 01652 { return presolve_find_minor1(col,krs,kre,hcol) ; } 01653 01662 CoinBigIndex presolve_find_minor2(int tgt, CoinBigIndex ks, int majlen, 01663 const int *minndxs, 01664 const CoinBigIndex *majlinks) ; 01665 01673 inline CoinBigIndex presolve_find_row2(int row, CoinBigIndex kcs, int collen, 01674 const int *hrow, 01675 const CoinBigIndex *clinks) 01676 { return presolve_find_minor2(row,kcs,collen,hrow,clinks) ; } 01677 01686 CoinBigIndex presolve_find_minor3(int tgt, CoinBigIndex ks, int majlen, 01687 const int *minndxs, 01688 const CoinBigIndex *majlinks) ; 01689 01697 inline CoinBigIndex presolve_find_row3(int row, CoinBigIndex kcs, int collen, 01698 const int *hrow, 01699 const CoinBigIndex *clinks) 01700 { return presolve_find_minor3(row,kcs,collen,hrow,clinks) ; } 01701 01711 inline void presolve_delete_from_major(int majndx, int minndx, 01712 const CoinBigIndex *majstrts, 01713 int *majlens, int *minndxs, double *els) 01714 { 01715 const CoinBigIndex ks = majstrts[majndx] ; 01716 const CoinBigIndex ke = ks+majlens[majndx] ; 01717 01718 const CoinBigIndex kmi = presolve_find_minor(minndx,ks,ke,minndxs) ; 01719 01720 minndxs[kmi] = minndxs[ke-1] ; 01721 els[kmi] = els[ke-1] ; 01722 majlens[majndx]-- ; 01723 01724 return ; 01725 } 01726 01733 inline void presolve_delete_many_from_major(int majndx, char *marked, 01734 const CoinBigIndex *majstrts, 01735 int *majlens, int *minndxs, double *els) 01736 { 01737 const CoinBigIndex ks = majstrts[majndx] ; 01738 const CoinBigIndex ke = ks+majlens[majndx] ; 01739 CoinBigIndex put = ks ; 01740 for (CoinBigIndex k = ks ; k < ke ; k++) { 01741 int iMinor = minndxs[k] ; 01742 if (!marked[iMinor]) { 01743 minndxs[put] = iMinor ; 01744 els[put++] = els[k] ; 01745 } else { 01746 marked[iMinor] = 0 ; 01747 } 01748 } 01749 majlens[majndx] = put-ks ; 01750 return ; 01751 } 01752 01763 inline void presolve_delete_from_col(int row, int col, 01764 const CoinBigIndex *mcstrt, 01765 int *hincol, int *hrow, double *colels) 01766 { presolve_delete_from_major(col,row,mcstrt,hincol,hrow,colels) ; } 01767 01778 inline void presolve_delete_from_row(int row, int col, 01779 const CoinBigIndex *mrstrt, 01780 int *hinrow, int *hcol, double *rowels) 01781 { presolve_delete_from_major(row,col,mrstrt,hinrow,hcol,rowels) ; } 01782 01793 void presolve_delete_from_major2 (int majndx, int minndx, 01794 CoinBigIndex *majstrts, int *majlens, 01795 int *minndxs, int *majlinks, 01796 CoinBigIndex *free_listp) ; 01797 01808 inline void presolve_delete_from_col2(int row, int col, CoinBigIndex *mcstrt, 01809 int *hincol, int *hrow, 01810 int *clinks, CoinBigIndex *free_listp) 01811 { presolve_delete_from_major2(col,row,mcstrt,hincol,hrow,clinks,free_listp) ; } 01812 01814 01820 01832 double *presolve_dupmajor(const double *elems, const int *indices, 01833 int length, CoinBigIndex offset, int tgt = -1); 01834 01836 void coin_init_random_vec(double *work, int n); 01837 01839 01840 01841 #endif