00001
00002
00003
00004
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
00030
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
00042 const double ZTOLDP2 = 1e-10;
00043
00044
00045
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
00061
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 #define PRESOLVE_INF COIN_DBL_MAX
00077
00078 class CoinPostsolveMatrix;
00079
00080
00081
00082
00083
00084
00085
00086
00087
00137 class CoinPresolveAction
00138 {
00139 public:
00146 static void throwCoinError(const char *error, const char *ps_routine)
00147 { throw CoinError(error, ps_routine, "CoinPresolve"); }
00148
00149
00154 const CoinPresolveAction *next;
00155
00161 CoinPresolveAction(const CoinPresolveAction *next) : next(next) {}
00163 inline void setNext(const CoinPresolveAction *nextAction)
00164 { next = nextAction;}
00165
00170 virtual const char *name() const = 0;
00171
00175 virtual void postsolve(CoinPostsolveMatrix *prob) const = 0;
00176
00178 virtual ~CoinPresolveAction() {}
00179 };
00180
00181
00182
00183
00184
00185 class ClpSimplex;
00186 class OsiSolverInterface;
00187
00188
00189
00190
00191
00192 class CoinWarmStartBasis ;
00193
00244 class CoinPrePostsolveMatrix
00245 {
00246 public:
00247
00257 CoinPrePostsolveMatrix(int ncols_alloc, int nrows_alloc,
00258 CoinBigIndex nelems_alloc) ;
00259
00264 CoinPrePostsolveMatrix(const OsiSolverInterface * si,
00265 int ncols_,
00266 int nrows_,
00267 CoinBigIndex nelems_);
00268
00273 CoinPrePostsolveMatrix(const ClpSimplex * si,
00274 int ncols_,
00275 int nrows_,
00276 CoinBigIndex nelems_,
00277 double bulkRatio);
00278
00280 ~CoinPrePostsolveMatrix();
00282
00292 enum Status {
00293 isFree = 0x00,
00294 basic = 0x01,
00295 atUpperBound = 0x02,
00296 atLowerBound = 0x03,
00297 superBasic = 0x04
00298 };
00299
00306
00308 inline void setRowStatus(int sequence, Status status)
00309 {
00310 unsigned char & st_byte = rowstat_[sequence];
00311 st_byte = static_cast<unsigned char>(st_byte & (~7)) ;
00312 st_byte = static_cast<unsigned char>(st_byte | status) ;
00313 }
00315 inline Status getRowStatus(int sequence) const
00316 {return static_cast<Status> (rowstat_[sequence]&7);}
00318 inline bool rowIsBasic(int sequence) const
00319 {return (static_cast<Status> (rowstat_[sequence]&7)==basic);}
00321 inline void setColumnStatus(int sequence, Status status)
00322 {
00323 unsigned char & st_byte = colstat_[sequence];
00324 st_byte = static_cast<unsigned char>(st_byte & (~7)) ;
00325 st_byte = static_cast<unsigned char>(st_byte | status) ;
00326
00327 # ifdef PRESOLVE_DEBUG
00328 switch (status)
00329 { case isFree:
00330 { if (clo_[sequence] > -PRESOLVE_INF || cup_[sequence] < PRESOLVE_INF)
00331 { std::cout << "Bad status: Var " << sequence
00332 << " isFree, lb = " << clo_[sequence]
00333 << ", ub = " << cup_[sequence] << std::endl ; }
00334 break ; }
00335 case basic:
00336 { break ; }
00337 case atUpperBound:
00338 { if (cup_[sequence] >= PRESOLVE_INF)
00339 { std::cout << "Bad status: Var " << sequence
00340 << " atUpperBound, lb = " << clo_[sequence]
00341 << ", ub = " << cup_[sequence] << std::endl ; }
00342 break ; }
00343 case atLowerBound:
00344 { if (clo_[sequence] <= -PRESOLVE_INF)
00345 { std::cout << "Bad status: Var " << sequence
00346 << " atLowerBound, lb = " << clo_[sequence]
00347 << ", ub = " << cup_[sequence] << std::endl ; }
00348 break ; }
00349 case superBasic:
00350 { if (clo_[sequence] <= -PRESOLVE_INF && cup_[sequence] >= PRESOLVE_INF)
00351 { std::cout << "Bad status: Var " << sequence
00352 << " superBasic, lb = " << clo_[sequence]
00353 << ", ub = " << cup_[sequence] << std::endl ; }
00354 break ; }
00355 default:
00356 { assert(false) ;
00357 break ; } }
00358 # endif
00359 }
00361 inline Status getColumnStatus(int sequence) const
00362 {return static_cast<Status> (colstat_[sequence]&7);}
00364 inline bool columnIsBasic(int sequence) const
00365 {return (static_cast<Status> (colstat_[sequence]&7)==basic);}
00369 void setRowStatusUsingValue(int iRow);
00373 void setColumnStatusUsingValue(int iColumn);
00375 void setStructuralStatus(const char *strucStatus, int lenParam) ;
00377 void setArtificialStatus(const char *artifStatus, int lenParam) ;
00379 void setStatus(const CoinWarmStartBasis *basis) ;
00381 CoinWarmStartBasis *getStatus() ;
00385 const char *columnStatusString(int j) const ;
00389 const char *rowStatusString(int i) const ;
00391
00399
00400 void setObjOffset(double offset) ;
00405 void setObjSense(double objSense) ;
00407 void setPrimalTolerance(double primTol) ;
00409 void setDualTolerance(double dualTol) ;
00411 void setColLower(const double *colLower, int lenParam) ;
00413 void setColUpper(const double *colUpper, int lenParam) ;
00415 void setColSolution(const double *colSol, int lenParam) ;
00417 void setCost(const double *cost, int lenParam) ;
00419 void setReducedCost(const double *redCost, int lenParam) ;
00421 void setRowLower(const double *rowLower, int lenParam) ;
00423 void setRowUpper(const double *rowUpper, int lenParam) ;
00425 void setRowPrice(const double *rowSol, int lenParam) ;
00427 void setRowActivity(const double *rowAct, int lenParam) ;
00429
00432
00433 inline int getNumCols()
00434 { return (ncols_) ; }
00436 inline int getNumRows()
00437 { return (nrows_) ; }
00439 inline int getNumElems()
00440 { return (nelems_) ; }
00442 inline const CoinBigIndex *getColStarts() const
00443 { return (mcstrt_) ; }
00445 inline const int *getColLengths() const
00446 { return (hincol_) ; }
00448 inline const int *getRowIndicesByCol() const
00449 { return (hrow_) ; }
00451 inline const double *getElementsByCol() const
00452 { return (colels_) ; }
00454 inline const double *getColLower() const
00455 { return (clo_) ; }
00457 inline const double *getColUpper() const
00458 { return (cup_) ; }
00460 inline const double *getCost() const
00461 { return (cost_) ; }
00463 inline const double *getRowLower() const
00464 { return (rlo_) ; }
00466 inline const double *getRowUpper() const
00467 { return (rup_) ; }
00469 inline const double *getColSolution() const
00470 { return (sol_) ; }
00472 inline const double *getRowActivity() const
00473 { return (acts_) ; }
00475 inline const double *getRowPrice() const
00476 { return (rowduals_) ; }
00478 inline const double *getReducedCost() const
00479 { return (rcosts_) ; }
00481 inline int countEmptyCols()
00482 { int empty = 0 ;
00483 for (int i = 0 ; i < ncols_ ; i++) if (hincol_[i] == 0) empty++ ;
00484 return (empty) ; }
00486
00487
00490
00491 inline CoinMessageHandler *messageHandler() const
00492 { return handler_; }
00498 inline void setMessageHandler(CoinMessageHandler *handler)
00499 { if (defaultHandler_ == true)
00500 { delete handler_ ;
00501 defaultHandler_ = false ; }
00502 handler_ = handler ; }
00504 inline CoinMessages messages() const
00505 { return messages_; }
00507
00517
00519 int ncols_;
00521 int nrows_;
00523 CoinBigIndex nelems_;
00524
00526 int ncols0_;
00528 int nrows0_ ;
00530 CoinBigIndex nelems0_ ;
00539 CoinBigIndex bulk0_ ;
00541 double bulkRatio_;
00543
00552
00553 CoinBigIndex *mcstrt_;
00555 int *hincol_;
00557 int *hrow_;
00559 double *colels_;
00560
00562 double *cost_;
00564 double originalOffset_;
00565
00567 double *clo_;
00569 double *cup_;
00570
00572 double *rlo_;
00574 double *rup_;
00575
00582 int * originalColumn_;
00589 int * originalRow_;
00590
00592 double ztolzb_;
00594 double ztoldj_;
00595
00597 double maxmin_;
00599
00620 double *sol_;
00626 double *rowduals_;
00632 double *acts_;
00638 double *rcosts_;
00639
00646 unsigned char *colstat_;
00647
00654 unsigned char *rowstat_;
00656
00665
00666 CoinMessageHandler *handler_;
00668 bool defaultHandler_;
00670 CoinMessage messages_;
00672
00673 };
00674
00675
00700 class presolvehlink
00701 { public:
00702 int pre, suc;
00703 } ;
00704
00705 #define NO_LINK -66666666
00706
00712 inline void PRESOLVE_REMOVE_LINK(presolvehlink *link, int i)
00713 {
00714 int ipre = link[i].pre;
00715 int isuc = link[i].suc;
00716 if (ipre >= 0) {
00717 link[ipre].suc = isuc;
00718 }
00719 if (isuc >= 0) {
00720 link[isuc].pre = ipre;
00721 }
00722 link[i].pre = NO_LINK, link[i].suc = NO_LINK;
00723 }
00724
00730 inline void PRESOLVE_INSERT_LINK(presolvehlink *link, int i, int j)
00731 {
00732 int isuc = link[j].suc;
00733 link[j].suc = i;
00734 link[i].pre = j;
00735 if (isuc >= 0) {
00736 link[isuc].pre = i;
00737 }
00738 link[i].suc = isuc;
00739 }
00740
00752 inline void PRESOLVE_MOVE_LINK(presolvehlink *link, int i, int j)
00753 {
00754 int ipre = link[i].pre;
00755 int isuc = link[i].suc;
00756 if (ipre >= 0) {
00757 link[ipre].suc = j;
00758 }
00759 if (isuc >= 0) {
00760 link[isuc].pre = j;
00761 }
00762 link[i].pre = NO_LINK, link[i].suc = NO_LINK;
00763 }
00764
00765
00787 class CoinPresolveMatrix : public CoinPrePostsolveMatrix
00788 {
00789 public:
00790
00797 CoinPresolveMatrix(int ncols_alloc, int nrows_alloc,
00798 CoinBigIndex nelems_alloc) ;
00799
00804 CoinPresolveMatrix(int ncols0,
00805 double maxmin,
00806
00807
00808 ClpSimplex * si,
00809
00810
00811 int nrows,
00812 CoinBigIndex nelems,
00813 bool doStatus,
00814 double nonLinearVariable,
00815 double bulkRatio);
00816
00818 void update_model(ClpSimplex * si,
00819 int nrows0,
00820 int ncols0,
00821 CoinBigIndex nelems0);
00826 CoinPresolveMatrix(int ncols0,
00827 double maxmin,
00828
00829 OsiSolverInterface * si,
00830
00831 int nrows,
00832 CoinBigIndex nelems,
00833 bool doStatus,
00834 double nonLinearVariable,
00835 const char * prohibited,
00836 const char * rowProhibited=NULL);
00837
00839 void update_model(OsiSolverInterface * si,
00840 int nrows0,
00841 int ncols0,
00842 CoinBigIndex nelems0);
00843
00845 ~CoinPresolveMatrix();
00846
00852 friend void assignPresolveToPostsolve (CoinPresolveMatrix *&preObj) ;
00853
00862 void setMatrix(const CoinPackedMatrix *mtx) ;
00863
00865 inline int countEmptyRows()
00866 { int empty = 0 ;
00867 for (int i = 0 ; i < nrows_ ; i++) if (hinrow_[i] == 0) empty++ ;
00868 return (empty) ; }
00869
00875 inline void setVariableType(int i, int variableType)
00876 { if (integerType_ == 0) integerType_ = new unsigned char [ncols0_] ;
00877 integerType_[i] = static_cast<unsigned char>(variableType) ; }
00878
00884 void setVariableType(const unsigned char *variableType, int lenParam) ;
00885
00891 void setVariableType (bool allIntegers, int lenParam) ;
00892
00894 inline void setAnyInteger (bool anyInteger = true)
00895 { anyInteger_ = anyInteger ; }
00897
00901
00903 inline const CoinBigIndex *getRowStarts() const
00904 { return (mrstrt_) ; }
00906 inline const int *getColIndicesByRow() const
00907 { return (hcol_) ; }
00909 inline const double *getElementsByRow() const
00910 { return (rowels_) ; }
00911
00917 inline bool isInteger (int i) const
00918 { if (integerType_ == 0)
00919 { return (anyInteger_) ; }
00920 else
00921 if (integerType_[i] == 1)
00922 { return (true) ; }
00923 else
00924 { return (false) ; } }
00925
00930 inline bool anyInteger () const
00931 { return (anyInteger_) ; }
00933 inline int presolveOptions() const
00934 { return presolveOptions_;}
00936 inline void setPresolveOptions(int value)
00937 { presolveOptions_=value;}
00939
00947
00948 presolvehlink *clink_;
00950 presolvehlink *rlink_;
00952
00954 double dobias_;
00955
00957 inline void change_bias(double change_amount)
00958 {
00959 dobias_ += change_amount;
00960 #if PRESOLVE_DEBUG
00961 assert(fabs(change_amount)<1.0e50);
00962 #endif
00963 if (change_amount)
00964 PRESOLVE_STMT(printf("changing bias by %g to %g\n",
00965 change_amount, dobias_));
00966 }
00967
00976
00977 CoinBigIndex *mrstrt_;
00979 int *hinrow_;
00981 double *rowels_;
00983 int *hcol_;
00985
00987 unsigned char *integerType_;
00993 bool anyInteger_ ;
00995 bool tuning_;
00997 void statistics();
00999 double startTime_;
01000
01002 double feasibilityTolerance_;
01004 inline double feasibilityTolerance()
01005 { return (feasibilityTolerance_) ; }
01007 inline void setFeasibilityTolerance (double val)
01008 { feasibilityTolerance_ = val ; }
01009
01015 int status_;
01017 inline int status()
01018 { return (status_) ; }
01020 inline void setStatus(int status)
01021 { status_ = (status&0x3) ; }
01022
01028 int pass_;
01030 inline void setPass (int pass = 0)
01031 { pass_ = pass ; }
01032
01037 int maxSubstLevel_;
01039 inline void setMaximumSubstitutionLevel (int level)
01040 { maxSubstLevel_ = level ; }
01041
01042
01066 unsigned char * colChanged_;
01068 int * colsToDo_;
01070 int numberColsToDo_;
01072 int * nextColsToDo_;
01074 int numberNextColsToDo_;
01075
01085 unsigned char * rowChanged_;
01087 int * rowsToDo_;
01089 int numberRowsToDo_;
01091 int * nextRowsToDo_;
01093 int numberNextRowsToDo_;
01102 int presolveOptions_;
01108 bool anyProhibited_;
01110 int * usefulRowInt_;
01112 double * usefulRowDouble_;
01114 int * usefulColumnInt_;
01116 double * usefulColumnDouble_;
01118 double * randomNumber_;
01120 int * infiniteUp_;
01122 double * sumUp_;
01124 int * infiniteDown_;
01126 double * sumDown_;
01128
01131
01137 void initColsToDo () ;
01138
01144 int stepColsToDo () ;
01145
01147 inline int numberColsToDo()
01148 { return (numberColsToDo_) ; }
01149
01151 inline bool colChanged(int i) const {
01152 return (colChanged_[i]&1)!=0;
01153 }
01155 inline void unsetColChanged(int i) {
01156 colChanged_[i] = static_cast<unsigned char>(colChanged_[i] & (~1)) ;
01157 }
01159 inline void setColChanged(int i) {
01160 colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (1)) ;
01161 }
01163 inline void addCol(int i) {
01164 if ((colChanged_[i]&1)==0) {
01165 colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (1)) ;
01166 nextColsToDo_[numberNextColsToDo_++] = i;
01167 }
01168 }
01170 inline bool colProhibited(int i) const {
01171 return (colChanged_[i]&2)!=0;
01172 }
01179 inline bool colProhibited2(int i) const {
01180 if (!anyProhibited_)
01181 return false;
01182 else
01183 return (colChanged_[i]&2)!=0;
01184 }
01186 inline void setColProhibited(int i) {
01187 colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (2)) ;
01188 }
01194 inline bool colUsed(int i) const {
01195 return (colChanged_[i]&4)!=0;
01196 }
01198 inline void setColUsed(int i) {
01199 colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (4)) ;
01200 }
01202 inline void unsetColUsed(int i) {
01203 colChanged_[i] = static_cast<unsigned char>(colChanged_[i] & (~4)) ;
01204 }
01206 inline bool colInfinite(int i) const {
01207 return (colChanged_[i]&8)!=0;
01208 }
01210 inline void unsetColInfinite(int i) {
01211 colChanged_[i] = static_cast<unsigned char>(colChanged_[i] & (~8)) ;
01212 }
01214 inline void setColInfinite(int i) {
01215 colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (8)) ;
01216 }
01217
01223 void initRowsToDo () ;
01224
01230 int stepRowsToDo () ;
01231
01233 inline int numberRowsToDo()
01234 { return (numberRowsToDo_) ; }
01235
01237 inline bool rowChanged(int i) const {
01238 return (rowChanged_[i]&1)!=0;
01239 }
01241 inline void unsetRowChanged(int i) {
01242 rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] & (~1)) ;
01243 }
01245 inline void setRowChanged(int i) {
01246 rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] | (1)) ;
01247 }
01249 inline void addRow(int i) {
01250 if ((rowChanged_[i]&1)==0) {
01251 rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] | (1)) ;
01252 nextRowsToDo_[numberNextRowsToDo_++] = i;
01253 }
01254 }
01256 inline bool rowProhibited(int i) const {
01257 return (rowChanged_[i]&2)!=0;
01258 }
01265 inline bool rowProhibited2(int i) const {
01266 if (!anyProhibited_)
01267 return false;
01268 else
01269 return (rowChanged_[i]&2)!=0;
01270 }
01272 inline void setRowProhibited(int i) {
01273 rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] | (2)) ;
01274 }
01280 inline bool rowUsed(int i) const {
01281 return (rowChanged_[i]&4)!=0;
01282 }
01284 inline void setRowUsed(int i) {
01285 rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] | (4)) ;
01286 }
01288 inline void unsetRowUsed(int i) {
01289 rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] & (~4)) ;
01290 }
01291
01292
01294 inline bool anyProhibited() const
01295 { return anyProhibited_;}
01297 inline void setAnyProhibited(bool val = true)
01298 { anyProhibited_ = val ; }
01301 int recomputeSums(int iRow);
01303 int initializeStuff();
01305 void deleteStuff();
01307
01308 };
01309
01334 class CoinPostsolveMatrix : public CoinPrePostsolveMatrix
01335 {
01336 public:
01337
01344 CoinPostsolveMatrix(int ncols_alloc, int nrows_alloc,
01345 CoinBigIndex nelems_alloc) ;
01346
01347
01352 CoinPostsolveMatrix(ClpSimplex * si,
01353
01354 int ncols0,
01355 int nrows0,
01356 CoinBigIndex nelems0,
01357
01358 double maxmin_,
01359
01360
01361 double *sol,
01362 double *acts,
01363
01364 unsigned char *colstat,
01365 unsigned char *rowstat);
01366
01371 CoinPostsolveMatrix(OsiSolverInterface * si,
01372
01373 int ncols0,
01374 int nrows0,
01375 CoinBigIndex nelems0,
01376
01377 double maxmin_,
01378
01379
01380 double *sol,
01381 double *acts,
01382
01383 unsigned char *colstat,
01384 unsigned char *rowstat);
01385
01396 void assignPresolveToPostsolve (CoinPresolveMatrix *&preObj) ;
01397
01399 ~CoinPostsolveMatrix();
01400
01412
01414 CoinBigIndex free_list_;
01416 int maxlink_;
01421 CoinBigIndex *link_;
01422
01424
01432 char *cdone_;
01433 char *rdone_;
01435
01437 void check_nbasic();
01438
01439 };
01440
01441
01442 #define PRESOLVEFINITE(n) (-PRESOLVE_INF < (n) && (n) < PRESOLVE_INF)
01443
01450
01455 void presolve_make_memlists( int *lengths,
01456 presolvehlink *link, int n);
01457
01465 bool presolve_expand_major(CoinBigIndex *majstrts, double *majels,
01466 int *minndxs, int *majlens,
01467 presolvehlink *majlinks, int nmaj, int k) ;
01468
01474 inline bool presolve_expand_col(CoinBigIndex *mcstrt, double *colels,
01475 int *hrow, int *hincol,
01476 presolvehlink *clink, int ncols, int colx)
01477 { return presolve_expand_major(mcstrt,colels,
01478 hrow,hincol,clink,ncols,colx) ; }
01479
01485 inline bool presolve_expand_row(CoinBigIndex *mrstrt, double *rowels,
01486 int *hcol, int *hinrow,
01487 presolvehlink *rlink, int nrows, int rowx)
01488 { return presolve_expand_major(mrstrt,rowels,
01489 hcol,hinrow,rlink,nrows,rowx) ; }
01490
01491
01500 inline CoinBigIndex presolve_find_minor(int tgt, CoinBigIndex ks, CoinBigIndex ke,
01501 const int *minndxs)
01502 { CoinBigIndex k ;
01503 for (k = ks ; k < ke ; k++)
01504 #ifndef NDEBUG
01505 { if (minndxs[k] == tgt)
01506 return (k) ; }
01507 DIE("FIND_MINOR") ;
01508
01509 abort () ; return -1;
01510 #else
01511 { if (minndxs[k] == tgt)
01512 break ; }
01513 return (k) ;
01514 #endif
01515 }
01516
01523 inline CoinBigIndex presolve_find_row(int row, CoinBigIndex kcs,
01524 CoinBigIndex kce, const int *hrow)
01525 { return presolve_find_minor(row,kcs,kce,hrow) ; }
01526
01533 inline CoinBigIndex presolve_find_col(int col, CoinBigIndex krs,
01534 CoinBigIndex kre, const int *hcol)
01535 { return presolve_find_minor(col,krs,kre,hcol) ; }
01536
01537
01546 CoinBigIndex presolve_find_minor1(int tgt, CoinBigIndex ks, CoinBigIndex ke,
01547 const int *minndxs);
01548
01555 inline CoinBigIndex presolve_find_row1(int row, CoinBigIndex kcs,
01556 CoinBigIndex kce, const int *hrow)
01557 { return presolve_find_minor1(row,kcs,kce,hrow) ; }
01558
01565 inline CoinBigIndex presolve_find_col1(int col, CoinBigIndex krs,
01566 CoinBigIndex kre, const int *hcol)
01567 { return presolve_find_minor1(col,krs,kre,hcol) ; }
01568
01577 CoinBigIndex presolve_find_minor2(int tgt, CoinBigIndex ks, int majlen,
01578 const int *minndxs,
01579 const CoinBigIndex *majlinks) ;
01580
01588 inline CoinBigIndex presolve_find_row2(int row, CoinBigIndex kcs, int collen,
01589 const int *hrow,
01590 const CoinBigIndex *clinks)
01591 { return presolve_find_minor2(row,kcs,collen,hrow,clinks) ; }
01592
01601 CoinBigIndex presolve_find_minor3(int tgt, CoinBigIndex ks, int majlen,
01602 const int *minndxs,
01603 const CoinBigIndex *majlinks) ;
01604
01612 inline CoinBigIndex presolve_find_row3(int row, CoinBigIndex kcs, int collen,
01613 const int *hrow,
01614 const CoinBigIndex *clinks)
01615 { return presolve_find_minor3(row,kcs,collen,hrow,clinks) ; }
01616
01626 inline void presolve_delete_from_major(int majndx, int minndx,
01627 const CoinBigIndex *majstrts,
01628 int *majlens, int *minndxs, double *els)
01629 { CoinBigIndex ks = majstrts[majndx] ;
01630 CoinBigIndex ke = ks + majlens[majndx] ;
01631
01632 CoinBigIndex kmi = presolve_find_minor(minndx,ks,ke,minndxs) ;
01633
01634 minndxs[kmi] = minndxs[ke-1] ;
01635 els[kmi] = els[ke-1] ;
01636 majlens[majndx]-- ;
01637
01638 return ; }
01639
01640 inline void presolve_delete_many_from_major(int majndx, char * marked,
01641 const CoinBigIndex *majstrts,
01642 int *majlens, int *minndxs, double *els)
01643 {
01644 CoinBigIndex ks = majstrts[majndx] ;
01645 CoinBigIndex ke = ks + majlens[majndx] ;
01646 CoinBigIndex put=ks;
01647 for (CoinBigIndex k=ks;k<ke;k++) {
01648 int iMinor = minndxs[k];
01649 if (!marked[iMinor]) {
01650 minndxs[put]=iMinor;
01651 els[put++]=els[k];
01652 } else {
01653 marked[iMinor]=0;
01654 }
01655 }
01656 majlens[majndx] = put-ks ;
01657 return ;
01658 }
01659
01670 inline void presolve_delete_from_col(int row, int col,
01671 const CoinBigIndex *mcstrt,
01672 int *hincol, int *hrow, double *colels)
01673 { presolve_delete_from_major(col,row,mcstrt,hincol,hrow,colels) ; }
01674
01685 inline void presolve_delete_from_row(int row, int col,
01686 const CoinBigIndex *mrstrt,
01687 int *hinrow, int *hcol, double *rowels)
01688 { presolve_delete_from_major(row,col,mrstrt,hinrow,hcol,rowels) ; }
01689
01700 void presolve_delete_from_major2 (int majndx, int minndx,
01701 CoinBigIndex *majstrts, int *majlens,
01702 int *minndxs, int *majlinks,
01703 CoinBigIndex *free_listp) ;
01704
01715 inline void presolve_delete_from_col2(int row, int col, CoinBigIndex *mcstrt,
01716 int *hincol, int *hrow,
01717 int *clinks,
01718 CoinBigIndex *free_listp)
01719 { presolve_delete_from_major2(col,row,mcstrt,hincol,hrow,clinks,
01720 free_listp) ; }
01721
01723
01729
01741 double *presolve_dupmajor(const double *elems, const int *indices,
01742 int length, CoinBigIndex offset, int tgt = -1);
01744 void coin_init_random_vec(double *work, int n);
01746
01747
01748 #endif