00001
00002
00003
00004 #ifndef CoinPresolveMatrix_H
00005 #define CoinPresolveMatrix_H
00006
00007 #include "CoinPragma.hpp"
00008 #include "CoinPackedMatrix.hpp"
00009 #include "CoinMessage.hpp"
00010 #include "CoinTime.hpp"
00011
00012 #include <cmath>
00013 #include <cassert>
00014 #include <cfloat>
00015 #include <cassert>
00016
00025 #if defined(_MSC_VER)
00026
00027
00028 #define deleteAction(array,type) delete [] ((type) array)
00029 #else
00030 #define deleteAction(array,type) delete [] array
00031 #endif
00032
00037 const double ZTOLDP = 1e-12;
00038
00039 const double ZTOLDP2 = 1e-10;
00040
00041
00042
00043 #if PRESOLVE_DEBUG || PRESOLVE_CONSISTENCY
00044 #define PRESOLVE_STMT(s) s
00045 #define PRESOLVEASSERT(x) \
00046 ((x) ? 1 : \
00047 ((std::cerr << "FAILED ASSERTION at line " \
00048 << __LINE__ << ": " #x "\n"), abort(), 0))
00049
00050 inline void DIE(const char *s) { std::cout<<s; abort(); }
00051
00052
00053
00054 #define PRESENT_IN_REDUCED '\377'
00055
00056 #else
00057
00058 #define PRESOLVEASSERT(x) {}
00059 #define PRESOLVE_STMT(s) {}
00060
00061 inline void DIE(const char *) {}
00062
00063 #endif
00064
00065 inline int ALIGN(int n, int m) { return (((n + m - 1) / m) * m); }
00066 inline int ALIGN_DOUBLE(int n) { return ALIGN(n,sizeof(double)); }
00067
00068
00069 #ifndef COIN_DBL_MAX
00070 #define COIN_DBL_MAX DBL_MAX
00071 #endif
00072 #define PRESOLVE_INF COIN_DBL_MAX
00073
00074 class CoinPostsolveMatrix;
00075
00076
00077
00078
00079
00080
00081
00082
00083
00133 class CoinPresolveAction
00134 {
00135 public:
00142 static void throwCoinError(const char *error, const char *ps_routine)
00143 { throw CoinError(error, ps_routine, "CoinPresolve"); }
00144
00145
00150 const CoinPresolveAction *next;
00151
00157 CoinPresolveAction(const CoinPresolveAction *next) : next(next) {}
00159 inline void setNext(const CoinPresolveAction *nextAction)
00160 { next = nextAction;}
00161
00166 virtual const char *name() const = 0;
00167
00171 virtual void postsolve(CoinPostsolveMatrix *prob) const = 0;
00172
00174 virtual ~CoinPresolveAction() {}
00175 };
00176
00177
00178
00179
00180
00181 class ClpSimplex;
00182 class OsiSolverInterface;
00183
00184
00185
00186
00187
00188 class CoinWarmStartBasis ;
00189
00240 class CoinPrePostsolveMatrix
00241 {
00242 public:
00243
00253 CoinPrePostsolveMatrix(int ncols_alloc, int nrows_alloc,
00254 CoinBigIndex nelems_alloc) ;
00255
00260 CoinPrePostsolveMatrix(const OsiSolverInterface * si,
00261 int ncols_,
00262 int nrows_,
00263 CoinBigIndex nelems_);
00264
00269 CoinPrePostsolveMatrix(const ClpSimplex * si,
00270 int ncols_,
00271 int nrows_,
00272 CoinBigIndex nelems_,
00273 double bulkRatio);
00274
00276 ~CoinPrePostsolveMatrix();
00278
00288 enum Status {
00289 isFree = 0x00,
00290 basic = 0x01,
00291 atUpperBound = 0x02,
00292 atLowerBound = 0x03,
00293 superBasic = 0x04
00294 };
00295
00302
00304 inline void setRowStatus(int sequence, Status status)
00305 {
00306 unsigned char & st_byte = rowstat_[sequence];
00307 st_byte = static_cast<unsigned char>(st_byte & (~7)) ;
00308 st_byte = static_cast<unsigned char>(st_byte | status) ;
00309 }
00311 inline Status getRowStatus(int sequence) const
00312 {return static_cast<Status> (rowstat_[sequence]&7);}
00314 inline bool rowIsBasic(int sequence) const
00315 {return (static_cast<Status> (rowstat_[sequence]&7)==basic);}
00317 inline void setColumnStatus(int sequence, Status status)
00318 {
00319 unsigned char & st_byte = colstat_[sequence];
00320 st_byte = static_cast<unsigned char>(st_byte & (~7)) ;
00321 st_byte = static_cast<unsigned char>(st_byte | status) ;
00322
00323 # ifdef PRESOLVE_DEBUG
00324 switch (status)
00325 { case isFree:
00326 { if (clo_[sequence] > -PRESOLVE_INF || cup_[sequence] < PRESOLVE_INF)
00327 { std::cout << "Bad status: Var " << sequence
00328 << " isFree, lb = " << clo_[sequence]
00329 << ", ub = " << cup_[sequence] << std::endl ; }
00330 break ; }
00331 case basic:
00332 { break ; }
00333 case atUpperBound:
00334 { if (cup_[sequence] >= PRESOLVE_INF)
00335 { std::cout << "Bad status: Var " << sequence
00336 << " atUpperBound, lb = " << clo_[sequence]
00337 << ", ub = " << cup_[sequence] << std::endl ; }
00338 break ; }
00339 case atLowerBound:
00340 { if (clo_[sequence] <= -PRESOLVE_INF)
00341 { std::cout << "Bad status: Var " << sequence
00342 << " atLowerBound, lb = " << clo_[sequence]
00343 << ", ub = " << cup_[sequence] << std::endl ; }
00344 break ; }
00345 case superBasic:
00346 { if (clo_[sequence] <= -PRESOLVE_INF && cup_[sequence] >= PRESOLVE_INF)
00347 { std::cout << "Bad status: Var " << sequence
00348 << " superBasic, lb = " << clo_[sequence]
00349 << ", ub = " << cup_[sequence] << std::endl ; }
00350 break ; }
00351 default:
00352 { assert(false) ;
00353 break ; } }
00354 # endif
00355 }
00357 inline Status getColumnStatus(int sequence) const
00358 {return static_cast<Status> (colstat_[sequence]&7);}
00360 inline bool columnIsBasic(int sequence) const
00361 {return (static_cast<Status> (colstat_[sequence]&7)==basic);}
00365 void setRowStatusUsingValue(int iRow);
00369 void setColumnStatusUsingValue(int iColumn);
00371 void setStructuralStatus(const char *strucStatus, int lenParam) ;
00373 void setArtificialStatus(const char *artifStatus, int lenParam) ;
00375 void setStatus(const CoinWarmStartBasis *basis) ;
00377 CoinWarmStartBasis *getStatus() ;
00381 const char *columnStatusString(int j) const ;
00385 const char *rowStatusString(int i) const ;
00387
00395
00396 void setObjOffset(double offset) ;
00401 void setObjSense(double objSense) ;
00403 void setPrimalTolerance(double primTol) ;
00405 void setDualTolerance(double dualTol) ;
00407 void setColLower(const double *colLower, int lenParam) ;
00409 void setColUpper(const double *colUpper, int lenParam) ;
00411 void setColSolution(const double *colSol, int lenParam) ;
00413 void setCost(const double *cost, int lenParam) ;
00415 void setReducedCost(const double *redCost, int lenParam) ;
00417 void setRowLower(const double *rowLower, int lenParam) ;
00419 void setRowUpper(const double *rowUpper, int lenParam) ;
00421 void setRowPrice(const double *rowSol, int lenParam) ;
00423 void setRowActivity(const double *rowAct, int lenParam) ;
00425
00428
00429 inline int getNumCols()
00430 { return (ncols_) ; }
00432 inline int getNumRows()
00433 { return (nrows_) ; }
00435 inline int getNumElems()
00436 { return (nelems_) ; }
00438 inline const CoinBigIndex *getColStarts() const
00439 { return (mcstrt_) ; }
00441 inline const int *getColLengths() const
00442 { return (hincol_) ; }
00444 inline const int *getRowIndicesByCol() const
00445 { return (hrow_) ; }
00447 inline const double *getElementsByCol() const
00448 { return (colels_) ; }
00450 inline const double *getColLower() const
00451 { return (clo_) ; }
00453 inline const double *getColUpper() const
00454 { return (cup_) ; }
00456 inline const double *getCost() const
00457 { return (cost_) ; }
00459 inline const double *getRowLower() const
00460 { return (rlo_) ; }
00462 inline const double *getRowUpper() const
00463 { return (rup_) ; }
00465 inline const double *getColSolution() const
00466 { return (sol_) ; }
00468 inline const double *getRowActivity() const
00469 { return (acts_) ; }
00471 inline const double *getRowPrice() const
00472 { return (rowduals_) ; }
00474 inline const double *getReducedCost() const
00475 { return (rcosts_) ; }
00477 inline int countEmptyCols()
00478 { int empty = 0 ;
00479 for (int i = 0 ; i < ncols_ ; i++) if (hincol_[i] == 0) empty++ ;
00480 return (empty) ; }
00482
00483
00486
00487 inline CoinMessageHandler *messageHandler() const
00488 { return handler_; }
00494 inline void setMessageHandler(CoinMessageHandler *handler)
00495 { if (defaultHandler_ == true)
00496 { delete handler_ ;
00497 defaultHandler_ = false ; }
00498 handler_ = handler ; }
00500 inline CoinMessages messages() const
00501 { return messages_; }
00503
00513
00515 int ncols_;
00517 int nrows_;
00519 CoinBigIndex nelems_;
00520
00522 int ncols0_;
00524 int nrows0_ ;
00526 CoinBigIndex nelems0_ ;
00535 CoinBigIndex bulk0_ ;
00537 double bulkRatio_;
00539
00548
00549 CoinBigIndex *mcstrt_;
00551 int *hincol_;
00553 int *hrow_;
00555 double *colels_;
00556
00558 double *cost_;
00560 double originalOffset_;
00561
00563 double *clo_;
00565 double *cup_;
00566
00568 double *rlo_;
00570 double *rup_;
00571
00573 int * originalColumn_;
00575 int * originalRow_;
00576
00578 double ztolzb_;
00580 double ztoldj_;
00581
00583 double maxmin_;
00585
00606 double *sol_;
00612 double *rowduals_;
00618 double *acts_;
00624 double *rcosts_;
00625
00632 unsigned char *colstat_;
00633
00640 unsigned char *rowstat_;
00642
00651
00652 CoinMessageHandler *handler_;
00654 bool defaultHandler_;
00656 CoinMessage messages_;
00658
00659 };
00660
00661
00686 class presolvehlink
00687 { public:
00688 int pre, suc;
00689 } ;
00690
00691 #define NO_LINK -66666666
00692
00698 inline void PRESOLVE_REMOVE_LINK(presolvehlink *link, int i)
00699 {
00700 int ipre = link[i].pre;
00701 int isuc = link[i].suc;
00702 if (ipre >= 0) {
00703 link[ipre].suc = isuc;
00704 }
00705 if (isuc >= 0) {
00706 link[isuc].pre = ipre;
00707 }
00708 link[i].pre = NO_LINK, link[i].suc = NO_LINK;
00709 }
00710
00716 inline void PRESOLVE_INSERT_LINK(presolvehlink *link, int i, int j)
00717 {
00718 int isuc = link[j].suc;
00719 link[j].suc = i;
00720 link[i].pre = j;
00721 if (isuc >= 0) {
00722 link[isuc].pre = i;
00723 }
00724 link[i].suc = isuc;
00725 }
00726
00738 inline void PRESOLVE_MOVE_LINK(presolvehlink *link, int i, int j)
00739 {
00740 int ipre = link[i].pre;
00741 int isuc = link[i].suc;
00742 if (ipre >= 0) {
00743 link[ipre].suc = j;
00744 }
00745 if (isuc >= 0) {
00746 link[isuc].pre = j;
00747 }
00748 link[i].pre = NO_LINK, link[i].suc = NO_LINK;
00749 }
00750
00751
00773 class CoinPresolveMatrix : public CoinPrePostsolveMatrix
00774 {
00775 public:
00776
00783 CoinPresolveMatrix(int ncols_alloc, int nrows_alloc,
00784 CoinBigIndex nelems_alloc) ;
00785
00790 CoinPresolveMatrix(int ncols0,
00791 double maxmin,
00792
00793
00794 ClpSimplex * si,
00795
00796
00797 int nrows,
00798 CoinBigIndex nelems,
00799 bool doStatus,
00800 double nonLinearVariable,
00801 double bulkRatio);
00802
00804 void update_model(ClpSimplex * si,
00805 int nrows0,
00806 int ncols0,
00807 CoinBigIndex nelems0);
00812 CoinPresolveMatrix(int ncols0,
00813 double maxmin,
00814
00815 OsiSolverInterface * si,
00816
00817 int nrows,
00818 CoinBigIndex nelems,
00819 bool doStatus,
00820 double nonLinearVariable,
00821 const char * prohibited,
00822 const char * rowProhibited=NULL);
00823
00825 void update_model(OsiSolverInterface * si,
00826 int nrows0,
00827 int ncols0,
00828 CoinBigIndex nelems0);
00829
00831 ~CoinPresolveMatrix();
00832
00838 friend void assignPresolveToPostsolve (CoinPresolveMatrix *&preObj) ;
00839
00848 void setMatrix(const CoinPackedMatrix *mtx) ;
00849
00851 inline int countEmptyRows()
00852 { int empty = 0 ;
00853 for (int i = 0 ; i < nrows_ ; i++) if (hinrow_[i] == 0) empty++ ;
00854 return (empty) ; }
00855
00861 inline void setVariableType(int i, int variableType)
00862 { if (integerType_ == 0) integerType_ = new unsigned char [ncols0_] ;
00863 integerType_[i] = static_cast<unsigned char>(variableType) ; }
00864
00870 void setVariableType(const unsigned char *variableType, int lenParam) ;
00871
00877 void setVariableType (bool allIntegers, int lenParam) ;
00878
00880 inline void setAnyInteger (bool anyInteger = true)
00881 { anyInteger_ = anyInteger ; }
00883
00887
00889 inline const CoinBigIndex *getRowStarts() const
00890 { return (mrstrt_) ; }
00892 inline const int *getColIndicesByRow() const
00893 { return (hcol_) ; }
00895 inline const double *getElementsByRow() const
00896 { return (rowels_) ; }
00897
00903 inline bool isInteger (int i) const
00904 { if (integerType_ == 0)
00905 { return (anyInteger_) ; }
00906 else
00907 if (integerType_[i] == 1)
00908 { return (true) ; }
00909 else
00910 { return (false) ; } }
00911
00916 inline bool anyInteger () const
00917 { return (anyInteger_) ; }
00919 inline int presolveOptions() const
00920 { return presolveOptions_;}
00922 inline void setPresolveOptions(int value)
00923 { presolveOptions_=value;}
00925
00933
00934 presolvehlink *clink_;
00936 presolvehlink *rlink_;
00938
00940 double dobias_;
00941
00943 inline void change_bias(double change_amount)
00944 {
00945 dobias_ += change_amount;
00946 #if PRESOLVE_DEBUG
00947 assert(fabs(change_amount)<1.0e50);
00948 #endif
00949 if (change_amount)
00950 PRESOLVE_STMT(printf("changing bias by %g to %g\n",
00951 change_amount, dobias_));
00952 }
00953
00962
00963 CoinBigIndex *mrstrt_;
00965 int *hinrow_;
00967 double *rowels_;
00969 int *hcol_;
00971
00973 unsigned char *integerType_;
00979 bool anyInteger_ ;
00981 bool tuning_;
00983 void statistics();
00985 double startTime_;
00986
00988 double feasibilityTolerance_;
00990 inline double feasibilityTolerance()
00991 { return (feasibilityTolerance_) ; }
00993 inline void setFeasibilityTolerance (double val)
00994 { feasibilityTolerance_ = val ; }
00995
01001 int status_;
01003 inline int status()
01004 { return (status_) ; }
01006 inline void setStatus(int status)
01007 { status_ = (status&0x3) ; }
01008
01014 int pass_;
01016 inline void setPass (int pass = 0)
01017 { pass_ = pass ; }
01018
01023 int maxSubstLevel_;
01025 inline void setMaximumSubstitutionLevel (int level)
01026 { maxSubstLevel_ = level ; }
01027
01028
01051 unsigned char * colChanged_;
01053 int * colsToDo_;
01055 int numberColsToDo_;
01057 int * nextColsToDo_;
01059 int numberNextColsToDo_;
01060
01070 unsigned char * rowChanged_;
01072 int * rowsToDo_;
01074 int numberRowsToDo_;
01076 int * nextRowsToDo_;
01078 int numberNextRowsToDo_;
01086 int presolveOptions_;
01092 bool anyProhibited_;
01094 int * usefulRowInt_;
01096 double * usefulRowDouble_;
01098 int * usefulColumnInt_;
01100 double * usefulColumnDouble_;
01102 double * randomNumber_;
01104 int * infiniteUp_;
01106 double * sumUp_;
01108 int * infiniteDown_;
01110 double * sumDown_;
01112
01115
01121 void initColsToDo () ;
01122
01128 int stepColsToDo () ;
01129
01131 inline int numberColsToDo()
01132 { return (numberColsToDo_) ; }
01133
01135 inline bool colChanged(int i) const {
01136 return (colChanged_[i]&1)!=0;
01137 }
01139 inline void unsetColChanged(int i) {
01140 colChanged_[i] = static_cast<unsigned char>(colChanged_[i] & (~1)) ;
01141 }
01143 inline void setColChanged(int i) {
01144 colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (1)) ;
01145 }
01147 inline void addCol(int i) {
01148 if ((colChanged_[i]&1)==0) {
01149 colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (1)) ;
01150 nextColsToDo_[numberNextColsToDo_++] = i;
01151 }
01152 }
01154 inline bool colProhibited(int i) const {
01155 return (colChanged_[i]&2)!=0;
01156 }
01163 inline bool colProhibited2(int i) const {
01164 if (!anyProhibited_)
01165 return false;
01166 else
01167 return (colChanged_[i]&2)!=0;
01168 }
01170 inline void setColProhibited(int i) {
01171 colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (2)) ;
01172 }
01178 inline bool colUsed(int i) const {
01179 return (colChanged_[i]&4)!=0;
01180 }
01182 inline void setColUsed(int i) {
01183 colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (4)) ;
01184 }
01186 inline void unsetColUsed(int i) {
01187 colChanged_[i] = static_cast<unsigned char>(colChanged_[i] & (~4)) ;
01188 }
01189
01195 void initRowsToDo () ;
01196
01202 int stepRowsToDo () ;
01203
01205 inline int numberRowsToDo()
01206 { return (numberRowsToDo_) ; }
01207
01209 inline bool rowChanged(int i) const {
01210 return (rowChanged_[i]&1)!=0;
01211 }
01213 inline void unsetRowChanged(int i) {
01214 rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] & (~1)) ;
01215 }
01217 inline void setRowChanged(int i) {
01218 rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] | (1)) ;
01219 }
01221 inline void addRow(int i) {
01222 if ((rowChanged_[i]&1)==0) {
01223 rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] | (1)) ;
01224 nextRowsToDo_[numberNextRowsToDo_++] = i;
01225 }
01226 }
01228 inline bool rowProhibited(int i) const {
01229 return (rowChanged_[i]&2)!=0;
01230 }
01237 inline bool rowProhibited2(int i) const {
01238 if (!anyProhibited_)
01239 return false;
01240 else
01241 return (rowChanged_[i]&2)!=0;
01242 }
01244 inline void setRowProhibited(int i) {
01245 rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] | (2)) ;
01246 }
01252 inline bool rowUsed(int i) const {
01253 return (rowChanged_[i]&4)!=0;
01254 }
01256 inline void setRowUsed(int i) {
01257 rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] | (4)) ;
01258 }
01260 inline void unsetRowUsed(int i) {
01261 rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] & (~4)) ;
01262 }
01263
01264
01266 inline bool anyProhibited() const
01267 { return anyProhibited_;}
01269 inline void setAnyProhibited(bool val = true)
01270 { anyProhibited_ = val ; }
01273 int recomputeSums(int iRow);
01275 int initializeStuff();
01277 void deleteStuff();
01279
01280 };
01281
01306 class CoinPostsolveMatrix : public CoinPrePostsolveMatrix
01307 {
01308 public:
01309
01316 CoinPostsolveMatrix(int ncols_alloc, int nrows_alloc,
01317 CoinBigIndex nelems_alloc) ;
01318
01319
01324 CoinPostsolveMatrix(ClpSimplex * si,
01325
01326 int ncols0,
01327 int nrows0,
01328 CoinBigIndex nelems0,
01329
01330 double maxmin_,
01331
01332
01333 double *sol,
01334 double *acts,
01335
01336 unsigned char *colstat,
01337 unsigned char *rowstat);
01338
01343 CoinPostsolveMatrix(OsiSolverInterface * si,
01344
01345 int ncols0,
01346 int nrows0,
01347 CoinBigIndex nelems0,
01348
01349 double maxmin_,
01350
01351
01352 double *sol,
01353 double *acts,
01354
01355 unsigned char *colstat,
01356 unsigned char *rowstat);
01357
01368 void assignPresolveToPostsolve (CoinPresolveMatrix *&preObj) ;
01369
01371 ~CoinPostsolveMatrix();
01372
01384
01386 CoinBigIndex free_list_;
01388 int maxlink_;
01393 CoinBigIndex *link_;
01394
01396
01404 char *cdone_;
01405 char *rdone_;
01407
01409 void check_nbasic();
01410
01411 };
01412
01413
01414 #define PRESOLVEFINITE(n) (-PRESOLVE_INF < (n) && (n) < PRESOLVE_INF)
01415
01422
01427 void presolve_make_memlists( int *lengths,
01428 presolvehlink *link, int n);
01429
01437 bool presolve_expand_major(CoinBigIndex *majstrts, double *majels,
01438 int *minndxs, int *majlens,
01439 presolvehlink *majlinks, int nmaj, int k) ;
01440
01446 inline bool presolve_expand_col(CoinBigIndex *mcstrt, double *colels,
01447 int *hrow, int *hincol,
01448 presolvehlink *clink, int ncols, int colx)
01449 { return presolve_expand_major(mcstrt,colels,
01450 hrow,hincol,clink,ncols,colx) ; }
01451
01457 inline bool presolve_expand_row(CoinBigIndex *mrstrt, double *rowels,
01458 int *hcol, int *hinrow,
01459 presolvehlink *rlink, int nrows, int rowx)
01460 { return presolve_expand_major(mrstrt,rowels,
01461 hcol,hinrow,rlink,nrows,rowx) ; }
01462
01463
01472 inline CoinBigIndex presolve_find_minor(int tgt, CoinBigIndex ks, CoinBigIndex ke,
01473 const int *minndxs)
01474 { CoinBigIndex k ;
01475 for (k = ks ; k < ke ; k++)
01476 #ifndef NDEBUG
01477 { if (minndxs[k] == tgt)
01478 return (k) ; }
01479 DIE("FIND_MINOR") ;
01480
01481 abort () ; return -1;
01482 #else
01483 { if (minndxs[k] == tgt)
01484 break ; }
01485 return (k) ;
01486 #endif
01487 }
01488
01495 inline CoinBigIndex presolve_find_row(int row, CoinBigIndex kcs,
01496 CoinBigIndex kce, const int *hrow)
01497 { return presolve_find_minor(row,kcs,kce,hrow) ; }
01498
01505 inline CoinBigIndex presolve_find_col(int col, CoinBigIndex krs,
01506 CoinBigIndex kre, const int *hcol)
01507 { return presolve_find_minor(col,krs,kre,hcol) ; }
01508
01509
01518 CoinBigIndex presolve_find_minor1(int tgt, CoinBigIndex ks, CoinBigIndex ke,
01519 const int *minndxs);
01520
01527 inline CoinBigIndex presolve_find_row1(int row, CoinBigIndex kcs,
01528 CoinBigIndex kce, const int *hrow)
01529 { return presolve_find_minor1(row,kcs,kce,hrow) ; }
01530
01537 inline CoinBigIndex presolve_find_col1(int col, CoinBigIndex krs,
01538 CoinBigIndex kre, const int *hcol)
01539 { return presolve_find_minor1(col,krs,kre,hcol) ; }
01540
01549 CoinBigIndex presolve_find_minor2(int tgt, CoinBigIndex ks, int majlen,
01550 const int *minndxs,
01551 const CoinBigIndex *majlinks) ;
01552
01560 inline CoinBigIndex presolve_find_row2(int row, CoinBigIndex kcs, int collen,
01561 const int *hrow,
01562 const CoinBigIndex *clinks)
01563 { return presolve_find_minor2(row,kcs,collen,hrow,clinks) ; }
01564
01573 CoinBigIndex presolve_find_minor3(int tgt, CoinBigIndex ks, int majlen,
01574 const int *minndxs,
01575 const CoinBigIndex *majlinks) ;
01576
01584 inline CoinBigIndex presolve_find_row3(int row, CoinBigIndex kcs, int collen,
01585 const int *hrow,
01586 const CoinBigIndex *clinks)
01587 { return presolve_find_minor3(row,kcs,collen,hrow,clinks) ; }
01588
01598 inline void presolve_delete_from_major(int majndx, int minndx,
01599 const CoinBigIndex *majstrts,
01600 int *majlens, int *minndxs, double *els)
01601 { CoinBigIndex ks = majstrts[majndx] ;
01602 CoinBigIndex ke = ks + majlens[majndx] ;
01603
01604 CoinBigIndex kmi = presolve_find_minor(minndx,ks,ke,minndxs) ;
01605
01606 minndxs[kmi] = minndxs[ke-1] ;
01607 els[kmi] = els[ke-1] ;
01608 majlens[majndx]-- ;
01609
01610 return ; }
01611
01612 inline void presolve_delete_many_from_major(int majndx, char * marked,
01613 const CoinBigIndex *majstrts,
01614 int *majlens, int *minndxs, double *els)
01615 {
01616 CoinBigIndex ks = majstrts[majndx] ;
01617 CoinBigIndex ke = ks + majlens[majndx] ;
01618 CoinBigIndex put=ks;
01619 for (CoinBigIndex k=ks;k<ke;k++) {
01620 int iMinor = minndxs[k];
01621 if (!marked[iMinor]) {
01622 minndxs[put]=iMinor;
01623 els[put++]=els[k];
01624 } else {
01625 marked[iMinor]=0;
01626 }
01627 }
01628 majlens[majndx] = put-ks ;
01629 return ;
01630 }
01631
01642 inline void presolve_delete_from_col(int row, int col,
01643 const CoinBigIndex *mcstrt,
01644 int *hincol, int *hrow, double *colels)
01645 { presolve_delete_from_major(col,row,mcstrt,hincol,hrow,colels) ; }
01646
01657 inline void presolve_delete_from_row(int row, int col,
01658 const CoinBigIndex *mrstrt,
01659 int *hinrow, int *hcol, double *rowels)
01660 { presolve_delete_from_major(row,col,mrstrt,hinrow,hcol,rowels) ; }
01661
01672 void presolve_delete_from_major2 (int majndx, int minndx,
01673 CoinBigIndex *majstrts, int *majlens,
01674 int *minndxs, int *majlinks,
01675 CoinBigIndex *free_listp) ;
01676
01687 inline void presolve_delete_from_col2(int row, int col, CoinBigIndex *mcstrt,
01688 int *hincol, int *hrow,
01689 int *clinks,
01690 CoinBigIndex *free_listp)
01691 { presolve_delete_from_major2(col,row,mcstrt,hincol,hrow,clinks,
01692 free_listp) ; }
01693
01695
01701
01713 double *presolve_dupmajor(const double *elems, const int *indices,
01714 int length, CoinBigIndex offset, int tgt = -1);
01716 void coin_init_random_vec(double *work, int n);
01718
01719
01720 #endif