1 /* $Id: CoinAbcBaseFactorization.hpp 2385 2019-01-06 19:43:06Z unxusr $ */ 2 // Copyright (C) 2002, International Business Machines 3 // Corporation and others, Copyright (C) 2012, FasterCoin. All Rights Reserved. 4 // This code is licensed under the terms of the Eclipse Public License (EPL). 5 6 /* 7 Authors 8 9 John Forrest 10 11 */ 12 /** This deals with Factorization and Updates 13 14 I am assuming that 32 bits is enough for number of rows or columns, but CoinBigIndex 15 may be redefined to get 64 bits. 16 */ 17 18 #include "AbcCommon.hpp" 19 #include "CoinAbcHelperFunctions.hpp" 20 #if ABC_PARALLEL 21 #define FACTOR_CPU 4 22 #else 23 #define FACTOR_CPU 1 24 #endif 25 #define LARGE_SET COIN_INT_MAX - 10 26 #define LARGE_UNSET (LARGE_SET + 1) 27 28 class CoinAbcTypeFactorization : public CoinAbcAnyFactorization { 29 friend void CoinAbcFactorizationUnitTest(const std::string &mpsDir); 30 31 public: 32 /**@name Constructors and destructor and copy */ 33 //@{ 34 /// Default constructor 35 CoinAbcTypeFactorization(); 36 /// Copy constructor 37 CoinAbcTypeFactorization(const CoinAbcTypeFactorization &other); 38 /// Copy constructor 39 CoinAbcTypeFactorization(const CoinFactorization &other); 40 41 /// Destructor 42 virtual ~CoinAbcTypeFactorization(); 43 /// Clone 44 virtual CoinAbcAnyFactorization *clone() const; 45 /// Delete all stuff (leaves as after CoinAbcFactorization()) 46 void almostDestructor(); 47 /// Debug show object (shows one representation) 48 void show_self() const; 49 /// Debug - sort so can compare 50 void sort() const; 51 /// = copy 52 CoinAbcTypeFactorization &operator=(const CoinAbcTypeFactorization &other); 53 //@} 54 55 /**@name Do factorization */ 56 //@{ 57 /// Condition number - product of pivots after factorization 58 CoinSimplexDouble conditionNumber() const; 59 60 //@} 61 62 /**@name general stuff such as permutation or status */ 63 //@{ 64 /// Returns address of permute region permute() const65 inline CoinSimplexInt *permute() const 66 { 67 return NULL; //permute_.array(); 68 } 69 /// Returns array to put basis indices in indices() const70 virtual inline CoinSimplexInt *indices() const 71 { 72 return indexRowU_.array(); 73 } 74 /// Returns address of pivotColumn region (also used for permuting) pivotColumn() const75 virtual inline CoinSimplexInt *pivotColumn() const 76 { 77 return pivotColumn_.array(); 78 } 79 /// Returns address of pivot region pivotRegion() const80 virtual inline CoinFactorizationDouble *pivotRegion() const 81 { 82 return pivotRegionAddress_; 83 } 84 #if ABC_SMALL < 2 85 /// Start of each row in L startRowL() const86 inline CoinBigIndex *startRowL() const 87 { 88 return startRowL_.array(); 89 } 90 #endif 91 92 /// Start of each column in L startColumnL() const93 inline CoinBigIndex *startColumnL() const 94 { 95 return startColumnL_.array(); 96 } 97 98 #if ABC_SMALL < 2 99 /// Index of column in row for L indexColumnL() const100 inline CoinSimplexInt *indexColumnL() const 101 { 102 return indexColumnL_.array(); 103 } 104 #endif 105 106 /// Row indices of L indexRowL() const107 inline CoinSimplexInt *indexRowL() const 108 { 109 return indexRowL_.array(); 110 } 111 112 #if ABC_SMALL < 2 113 /// Elements in L (row copy) elementByRowL() const114 inline CoinFactorizationDouble *elementByRowL() const 115 { 116 return elementByRowL_.array(); 117 } 118 #endif 119 /** 120 Forward and backward linked lists (numberRows_+2) 121 **/ pivotLinkedBackwards() const122 inline CoinSimplexInt *pivotLinkedBackwards() const 123 { 124 return firstCount_.array() + numberRows_ + 1; 125 } pivotLinkedForwards() const126 inline CoinSimplexInt *pivotLinkedForwards() const 127 { 128 return firstCount_.array() + 2 * numberRows_ + 3; 129 } pivotLOrder() const130 inline CoinSimplexInt *pivotLOrder() const 131 { 132 return firstCount_.array(); 133 } 134 #if ABC_SMALL < 0 135 #define ABC_USE_FUNCTION_POINTERS 0 136 #define SMALL_PERMUTE 137 #endif 138 #ifdef ABC_USE_FUNCTION_POINTERS 139 typedef void (*scatterUpdate)(int, CoinFactorizationDouble, const CoinFactorizationDouble *, CoinFactorizationDouble *); 140 #if ABC_USE_FUNCTION_POINTERS 141 typedef struct { 142 scatterUpdate functionPointer; 143 CoinBigIndex offset; 144 int number; 145 } scatterStruct; 146 #else 147 typedef struct { 148 CoinBigIndex offset; 149 int number; 150 } scatterStruct; 151 #endif 152 /// Array of function pointers PLUS for U Column scatterUColumn() const153 inline scatterStruct *scatterUColumn() const 154 { 155 return scatterPointersUColumnAddress_; 156 } 157 #endif 158 159 /// For equal counts in factorization 160 /** First Row/Column with count of k, 161 can tell which by offset - Rows then Columns 162 actually comes before nextCount*/ firstCount() const163 inline CoinSimplexInt *firstCount() const 164 { 165 return firstCount_.array(); 166 } 167 168 /// Next Row/Column with count nextCount() const169 inline CoinSimplexInt *nextCount() const 170 { 171 return firstCount_.array() + numberRows_ + 2; 172 } 173 174 /// Previous Row/Column with count lastCount() const175 inline CoinSimplexInt *lastCount() const 176 { 177 return firstCount_.array() + 3 * numberRows_ + 2; 178 } 179 180 /// Number of Rows after iterating numberRowsExtra() const181 inline CoinSimplexInt numberRowsExtra() const 182 { 183 return numberRowsExtra_; 184 } 185 /// Number in L numberL() const186 inline CoinBigIndex numberL() const 187 { 188 return numberL_; 189 } 190 191 /// Base of L baseL() const192 inline CoinBigIndex baseL() const 193 { 194 return baseL_; 195 } 196 /// Maximum of Rows after iterating maximumRowsExtra() const197 inline CoinSimplexInt maximumRowsExtra() const 198 { 199 return maximumRowsExtra_; 200 } 201 /// Total number of elements in factorization numberElements() const202 virtual inline CoinBigIndex numberElements() const 203 { 204 return totalElements_; 205 } 206 /// Length of FT vector numberForrestTomlin() const207 inline CoinSimplexInt numberForrestTomlin() const 208 { 209 return numberInColumn_.array()[numberRowsExtra_]; 210 } 211 /// Returns areaFactor but adjusted for dense 212 CoinSimplexDouble adjustedAreaFactor() const; 213 /// Level of detail of messages messageLevel() const214 inline CoinSimplexInt messageLevel() const 215 { 216 return messageLevel_; 217 } 218 void messageLevel(CoinSimplexInt value); 219 /// Set maximum pivots 220 virtual void maximumPivots(CoinSimplexInt value); 221 222 #if ABC_SMALL < 4 223 /// Gets dense threshold denseThreshold() const224 inline CoinSimplexInt denseThreshold() const 225 { 226 return denseThreshold_; 227 } 228 /// Sets dense threshold setDenseThreshold(CoinSimplexInt value)229 inline void setDenseThreshold(CoinSimplexInt value) 230 { 231 denseThreshold_ = value; 232 } 233 #endif 234 /// Returns maximum absolute value in factorization 235 CoinSimplexDouble maximumCoefficient() const; 236 #if 0 237 /// true if Forrest Tomlin update, false if PFI 238 inline bool forrestTomlin() const 239 { return doForrestTomlin_;} 240 inline void setForrestTomlin(bool value) 241 { doForrestTomlin_=value;} 242 #endif 243 /// True if FT update and space spaceForForrestTomlin() const244 inline bool spaceForForrestTomlin() const 245 { 246 CoinBigIndex start = lastEntryByColumnU_; 247 CoinBigIndex space = lengthAreaU_ - (start + numberRowsExtra_); 248 return (space >= 0); //&&doForrestTomlin_; 249 } 250 //@} 251 252 /**@name some simple stuff */ 253 //@{ 254 255 /// Returns number in U area numberElementsU() const256 inline CoinBigIndex numberElementsU() const 257 { 258 return lengthU_; 259 } 260 /// Setss number in U area setNumberElementsU(CoinBigIndex value)261 inline void setNumberElementsU(CoinBigIndex value) 262 { 263 lengthU_ = value; 264 } 265 /// Returns length of U area lengthAreaU() const266 inline CoinBigIndex lengthAreaU() const 267 { 268 return lengthAreaU_; 269 } 270 /// Returns number in L area numberElementsL() const271 inline CoinBigIndex numberElementsL() const 272 { 273 return lengthL_; 274 } 275 /// Returns length of L area lengthAreaL() const276 inline CoinBigIndex lengthAreaL() const 277 { 278 return lengthAreaL_; 279 } 280 /// Returns number in R area numberElementsR() const281 inline CoinBigIndex numberElementsR() const 282 { 283 return lengthR_; 284 } 285 /// Number of compressions done numberCompressions() const286 inline CoinBigIndex numberCompressions() const 287 { 288 return numberCompressions_; 289 } 290 /// Returns pivot row 291 //virtual CoinSimplexInt * pivotRow() const; 292 /// Returns work area 293 //virtual CoinFactorizationDouble * workArea() const; 294 /// Returns CoinSimplexInt work area 295 //virtual CoinSimplexInt * intWorkArea() const; 296 /// Returns array to put basis starts in starts() const297 virtual inline CoinBigIndex *starts() const 298 { 299 return startColumnU_.array(); 300 } 301 /// Number of entries in each row numberInRow() const302 virtual inline CoinSimplexInt *numberInRow() const 303 { 304 return numberInRow_.array(); 305 } 306 /// Number of entries in each column numberInColumn() const307 virtual inline CoinSimplexInt *numberInColumn() const 308 { 309 return numberInColumn_.array(); 310 } 311 /// Returns array to put basis elements in elements() const312 virtual inline CoinFactorizationDouble *elements() const 313 { 314 return elementU_.array(); 315 } 316 /// Start of columns for R startColumnR() const317 inline CoinBigIndex *startColumnR() const 318 { 319 return reinterpret_cast< CoinBigIndex * >(firstCount_.array() + 3 * numberRows_ + 4); 320 } 321 /// Elements of U elementU() const322 inline CoinFactorizationDouble *elementU() const 323 { 324 return elementU_.array(); 325 } 326 /// Row indices of U indexRowU() const327 inline CoinSimplexInt *indexRowU() const 328 { 329 return indexRowU_.array(); 330 } 331 /// Start of each column in U startColumnU() const332 inline CoinBigIndex *startColumnU() const 333 { 334 return startColumnU_.array(); 335 } 336 #if COIN_BIG_DOUBLE == 1 337 /// To a work array and associate vector 338 void toLongArray(CoinIndexedVector *vector, int which) const; 339 /// From a work array and dis-associate vector 340 void fromLongArray(CoinIndexedVector *vector) const; 341 /// From a work array and dis-associate vector 342 void fromLongArray(int which) const; 343 /// Returns long double * associated with vector 344 long double *denseVector(CoinIndexedVector *vector) const; 345 /// Returns long double * associated with vector 346 long double *denseVector(CoinIndexedVector &vector) const; 347 /// Returns long double * associated with vector 348 const long double *denseVector(const CoinIndexedVector *vector) const; 349 /// Returns long double * associated with vector 350 const long double *denseVector(const CoinIndexedVector &vector) const; 351 /// Scans region to find nonzeros 352 void scan(CoinIndexedVector *vector) const; 353 /// Clear all hidden arrays 354 void clearHiddenArrays(); 355 #else 356 /// Returns double * associated with vector denseVector(CoinIndexedVector * vector) const357 inline double *denseVector(CoinIndexedVector *vector) const 358 { 359 return vector->denseVector(); 360 } denseVector(CoinIndexedVector & vector) const361 inline double *denseVector(CoinIndexedVector &vector) const 362 { 363 return vector.denseVector(); 364 } 365 /// Returns double * associated with vector denseVector(const CoinIndexedVector * vector) const366 inline const double *denseVector(const CoinIndexedVector *vector) const 367 { 368 return vector->denseVector(); 369 } denseVector(const CoinIndexedVector & vector) const370 inline const double *denseVector(const CoinIndexedVector &vector) const 371 { 372 return vector.denseVector(); 373 } 374 /// To a work array and associate vector toLongArray(CoinIndexedVector * vector,int which) const375 inline void toLongArray(CoinIndexedVector *vector, int which) const {} 376 /// From a work array and dis-associate vector fromLongArray(CoinIndexedVector * vector) const377 inline void fromLongArray(CoinIndexedVector *vector) const {} 378 /// From a work array and dis-associate vector fromLongArray(int which) const379 inline void fromLongArray(int which) const {} 380 /// Scans region to find nonzeros scan(CoinIndexedVector * vector) const381 inline void scan(CoinIndexedVector *vector) const 382 { 383 vector->scan(0, numberRows_, zeroTolerance_); 384 } 385 #endif 386 #ifdef ABC_ORDERED_FACTORIZATION 387 /// Permute in for Ftran 388 void permuteInForFtran(CoinIndexedVector ®ionSparse, bool full = false) const; 389 /// Permute in for Btran and multiply by pivot Region 390 void permuteInForBtranAndMultiply(CoinIndexedVector ®ionSparse, bool full = false) const; 391 /// Permute out for Btran 392 void permuteOutForBtran(CoinIndexedVector ®ionSparse) const; 393 #endif 394 /** Array persistence flag 395 If 0 then as now (delete/new) 396 1 then only do arrays if bigger needed 397 2 as 1 but give a bit extra if bigger needed 398 */ 399 //inline CoinSimplexInt persistenceFlag() const 400 //{ return persistenceFlag_;} 401 //@} 402 403 /**@name rank one updates which do exist */ 404 //@{ 405 #if 0 406 /** Checks if can replace one Column to basis, 407 returns 0=OK, 1=Probably OK, 2=singular, 3=no room, 5 max pivots 408 Fills in region for use later 409 partial update already in U */ 410 virtual int checkReplace ( const AbcSimplex * model, 411 CoinIndexedVector * regionSparse, 412 int pivotRow, 413 CoinSimplexDouble & pivotCheck, 414 double acceptablePivot = 1.0e-8); 415 /** Replaces one Column to basis, 416 returns 0=OK, 1=Probably OK, 2=singular, 3=no room 417 If skipBtranU is false will do btran part 418 partial update already in U */ 419 virtual CoinSimplexInt replaceColumn ( CoinIndexedVector * regionSparse, 420 CoinSimplexInt pivotRow, 421 CoinSimplexDouble pivotCheck , 422 bool skipBtranU=false, 423 CoinSimplexDouble acceptablePivot=1.0e-8); 424 #endif 425 /** Checks if can replace one Column to basis, 426 returns update alpha 427 Fills in region for use later 428 partial update already in U */ 429 virtual 430 #ifdef ABC_LONG_FACTORIZATION 431 long 432 #endif 433 double 434 checkReplacePart1(CoinIndexedVector *regionSparse, 435 int pivotRow); 436 /** Checks if can replace one Column to basis, 437 returns update alpha 438 Fills in region for use later 439 partial update in vector */ 440 virtual 441 #ifdef ABC_LONG_FACTORIZATION 442 long 443 #endif 444 double 445 checkReplacePart1(CoinIndexedVector *regionSparse, 446 CoinIndexedVector *partialUpdate, 447 int pivotRow); 448 #ifdef MOVE_REPLACE_PART1A 449 /** Checks if can replace one Column to basis, 450 returns update alpha 451 Fills in region for use later 452 partial update already in U */ 453 virtual void checkReplacePart1a(CoinIndexedVector *regionSparse, 454 int pivotRow); 455 virtual 456 #ifdef ABC_LONG_FACTORIZATION 457 long 458 #endif 459 double 460 checkReplacePart1b(CoinIndexedVector *regionSparse, 461 int pivotRow); 462 #endif 463 /** Checks if can replace one Column to basis, 464 returns 0=OK, 1=Probably OK, 2=singular, 3=no room, 5 max pivots */ 465 virtual int checkReplacePart2(int pivotRow, 466 CoinSimplexDouble btranAlpha, 467 double ftranAlpha, 468 #ifdef ABC_LONG_FACTORIZATION 469 long 470 #endif 471 double ftAlpha, 472 double acceptablePivot = 1.0e-8); 473 /** Replaces one Column to basis, 474 partial update already in U */ 475 virtual void replaceColumnPart3(const AbcSimplex *model, 476 CoinIndexedVector *regionSparse, 477 CoinIndexedVector *tableauColumn, 478 int pivotRow, 479 #ifdef ABC_LONG_FACTORIZATION 480 long 481 #endif 482 double alpha); 483 /** Replaces one Column to basis, 484 partial update in vector */ 485 virtual void replaceColumnPart3(const AbcSimplex *model, 486 CoinIndexedVector *regionSparse, 487 CoinIndexedVector *tableauColumn, 488 CoinIndexedVector *partialUpdate, 489 int pivotRow, 490 #ifdef ABC_LONG_FACTORIZATION 491 long 492 #endif 493 double alpha); 494 #ifdef EARLY_FACTORIZE 495 /// 0 success, -1 can't +1 accuracy problems 496 virtual int replaceColumns(const AbcSimplex *model, 497 CoinIndexedVector &stuff, 498 int firstPivot, int lastPivot, bool cleanUp); 499 #endif 500 /// Update partial Ftran by R update 501 void updatePartialUpdate(CoinIndexedVector &partialUpdate); 502 /// Returns true if wants tableauColumn in replaceColumn wantsTableauColumn() const503 inline virtual bool wantsTableauColumn() const 504 { 505 return false; 506 } 507 /** Combines BtranU and store which elements are to be deleted 508 returns number to be deleted 509 */ 510 int replaceColumnU(CoinIndexedVector *regionSparse, 511 CoinBigIndex *deletedPosition, 512 CoinSimplexInt *deletedColumns, 513 CoinSimplexInt pivotRow); 514 //@} 515 516 /**@name various uses of factorization (return code number elements) 517 which user may want to know about */ 518 /// Later take out return codes (apart from +- 1 on FT) 519 //@{ 520 /** Updates one column (FTRAN) from regionSparse2 521 Tries to do FT update 522 number returned is negative if no room 523 regionSparse starts as zero and is zero at end. 524 Note - if regionSparse2 packed on input - will be packed on output 525 */ 526 virtual CoinSimplexInt updateColumnFT(CoinIndexedVector ®ionSparse); 527 virtual int updateColumnFTPart1(CoinIndexedVector ®ionSparse); 528 virtual void updateColumnFTPart2(CoinIndexedVector ®ionSparse); 529 /** Updates one column (FTRAN) 530 Tries to do FT update 531 puts partial update in vector */ 532 virtual void updateColumnFT(CoinIndexedVector ®ionSparseFT, 533 CoinIndexedVector &partialUpdate, 534 int which); 535 /** This version has same effect as above with FTUpdate==false 536 so number returned is always >=0 */ 537 virtual CoinSimplexInt updateColumn(CoinIndexedVector ®ionSparse) const; 538 /** Updates one column (FTRAN) from region2 539 Tries to do FT update 540 number returned is negative if no room. 541 Also updates region3 542 region1 starts as zero and is zero at end */ 543 virtual CoinSimplexInt updateTwoColumnsFT(CoinIndexedVector ®ionFT, 544 CoinIndexedVector ®ionOther); 545 /** Updates one column (BTRAN) from regionSparse2 546 regionSparse starts as zero and is zero at end 547 Note - if regionSparse2 packed on input - will be packed on output 548 */ 549 virtual CoinSimplexInt updateColumnTranspose(CoinIndexedVector ®ionSparse) const; 550 /** Updates one full column (FTRAN) */ 551 virtual void updateFullColumn(CoinIndexedVector ®ionSparse) const; 552 /** Updates one full column (BTRAN) */ 553 virtual void updateFullColumnTranspose(CoinIndexedVector ®ionSparse) const; 554 /** Updates one column for dual steepest edge weights (FTRAN) */ 555 virtual void updateWeights(CoinIndexedVector ®ionSparse) const; 556 /** Updates one column (FTRAN) */ 557 virtual void updateColumnCpu(CoinIndexedVector ®ionSparse, int whichCpu) const; 558 /** Updates one column (BTRAN) */ 559 virtual void updateColumnTransposeCpu(CoinIndexedVector ®ionSparse, int whichCpu) const; 560 void unpack(CoinIndexedVector *regionFrom, 561 CoinIndexedVector *regionTo) const; 562 void pack(CoinIndexedVector *regionFrom, 563 CoinIndexedVector *regionTo) const; 564 /** makes a row copy of L for speed and to allow very sparse problems */ goSparse()565 inline void goSparse() {} 566 void goSparse2(); 567 #ifndef NDEBUG 568 virtual void checkMarkArrays() const; 569 #endif 570 #if ABC_SMALL < 2 571 /** get sparse threshold */ sparseThreshold() const572 inline CoinSimplexInt sparseThreshold() const 573 { 574 return sparseThreshold_; 575 } 576 #endif 577 /** set sparse threshold */ 578 void sparseThreshold(CoinSimplexInt value); 579 //@} 580 /// *** Below this user may not want to know about 581 582 /**@name various uses of factorization (return code number elements) 583 which user may not want to know about (left over from my LP code) */ 584 //@{ 585 /// Get rid of all memory clearArrays()586 inline void clearArrays() 587 { 588 gutsOfDestructor(); 589 } 590 //@} 591 /**@name used by ClpFactorization */ 592 /// See if worth going sparse 593 void checkSparse(); 594 /// The real work of constructors etc 0 just scalars, 1 bit normal 595 void gutsOfDestructor(CoinSimplexInt type = 1); 596 /// 1 bit - tolerances etc, 2 more, 4 dummy arrays 597 void gutsOfInitialize(CoinSimplexInt type); 598 void gutsOfCopy(const CoinAbcTypeFactorization &other); 599 600 /// Reset all sparsity etc statistics 601 void resetStatistics(); 602 void printRegion(const CoinIndexedVector &vector, const char *where) const; 603 604 //@} 605 606 /**@name used by factorization */ 607 /// Gets space for a factorization, called by constructors 608 virtual void getAreas(CoinSimplexInt numberRows, 609 CoinSimplexInt numberColumns, 610 CoinBigIndex maximumL, 611 CoinBigIndex maximumU); 612 613 /// PreProcesses column ordered copy of basis 614 virtual void preProcess(); 615 void preProcess(CoinSimplexInt); 616 /// Return largest element 617 double preProcess3(); 618 void preProcess4(); 619 /// Does most of factorization 620 virtual CoinSimplexInt factor(AbcSimplex *model); 621 #ifdef EARLY_FACTORIZE 622 /// Returns -2 if can't, -1 if singular, -99 memory, 0 OK 623 virtual int factorize(AbcSimplex *model, CoinIndexedVector &stuff); 624 #endif 625 /// Does post processing on valid factorization - putting variables on correct rows 626 virtual void postProcess(const CoinSimplexInt *sequence, CoinSimplexInt *pivotVariable); 627 /// Makes a non-singular basis by replacing variables 628 virtual void makeNonSingular(CoinSimplexInt *sequence); 629 630 protected: 631 /** Does sparse phase of factorization 632 return code is <0 error, 0= finished */ 633 CoinSimplexInt factorSparse(); 634 /** Does dense phase of factorization 635 return code is <0 error, 0= finished */ 636 CoinSimplexInt factorDense(); 637 638 /// Pivots when just one other row so faster? 639 bool pivotOneOtherRow(CoinSimplexInt pivotRow, 640 CoinSimplexInt pivotColumn); 641 /// Does one pivot on Row Singleton in factorization 642 bool pivotRowSingleton(CoinSimplexInt pivotRow, 643 CoinSimplexInt pivotColumn); 644 /// Does one pivot on Column Singleton in factorization (can't return false) 645 void pivotColumnSingleton(CoinSimplexInt pivotRow, 646 CoinSimplexInt pivotColumn); 647 /// After pivoting 648 void afterPivot(CoinSimplexInt pivotRow, 649 CoinSimplexInt pivotColumn); 650 /// After pivoting - returns true if need to go dense 651 int wantToGoDense(); 652 653 /** Gets space for one Column with given length, 654 may have to do compression (returns True if successful), 655 also moves existing vector, 656 extraNeeded is over and above present */ 657 bool getColumnSpace(CoinSimplexInt iColumn, 658 CoinSimplexInt extraNeeded); 659 660 /** Reorders U so contiguous and in order (if there is space) 661 Returns true if it could */ 662 bool reorderU(); 663 /** getColumnSpaceIterateR. Gets space for one extra R element in Column 664 may have to do compression (returns true) 665 also moves existing vector */ 666 bool getColumnSpaceIterateR(CoinSimplexInt iColumn, CoinFactorizationDouble value, 667 CoinSimplexInt iRow); 668 /** getColumnSpaceIterate. Gets space for one extra U element in Column 669 may have to do compression (returns true) 670 also moves existing vector. 671 Returns -1 if no memory or where element was put 672 Used by replaceRow (turns off R version) */ 673 CoinBigIndex getColumnSpaceIterate(CoinSimplexInt iColumn, CoinFactorizationDouble value, 674 CoinSimplexInt iRow); 675 /** Gets space for one Row with given length, 676 may have to do compression (returns True if successful), 677 also moves existing vector */ 678 bool getRowSpace(CoinSimplexInt iRow, CoinSimplexInt extraNeeded); 679 680 /** Gets space for one Row with given length while iterating, 681 may have to do compression (returns True if successful), 682 also moves existing vector */ 683 bool getRowSpaceIterate(CoinSimplexInt iRow, 684 CoinSimplexInt extraNeeded); 685 /// Checks that row and column copies look OK 686 void checkConsistency(); 687 //#define CHECK_LINKS 688 #ifdef CHECK_LINKS 689 void checkLinks(int x = 0); 690 #else 691 #define checkLinks(x) 692 #endif 693 /// Adds a link in chain of equal counts addLink(CoinSimplexInt index,CoinSimplexInt count)694 inline void addLink(CoinSimplexInt index, CoinSimplexInt count) 695 { 696 CoinSimplexInt *COIN_RESTRICT nextCount = nextCountAddress_; 697 CoinSimplexInt *COIN_RESTRICT firstCount = this->firstCount(); 698 CoinSimplexInt *COIN_RESTRICT lastCount = lastCountAddress_; 699 CoinSimplexInt next = firstCount[count]; 700 firstCount[count] = index; 701 nextCount[index] = next; 702 lastCount[index] = count - numberRows_ - 2; // points to firstCount[count] 703 if (next >= 0) 704 lastCount[next] = index; 705 } 706 /// Deletes a link in chain of equal counts deleteLink(CoinSimplexInt index)707 inline void deleteLink(CoinSimplexInt index) 708 { 709 CoinSimplexInt *COIN_RESTRICT nextCount = nextCountAddress_; 710 CoinSimplexInt *COIN_RESTRICT lastCount = lastCountAddress_; 711 CoinSimplexInt next = nextCount[index]; 712 CoinSimplexInt last = lastCount[index]; 713 assert(next != index); 714 assert(last != index); 715 if (next >= 0) 716 lastCount[next] = last; 717 if (last >= 0) { 718 nextCount[last] = next; 719 } else { 720 int count = last + numberRows_ + 2; 721 CoinSimplexInt *COIN_RESTRICT firstCount = this->firstCount(); 722 firstCount[count] = next; 723 } 724 } 725 /// Modifies links in chain of equal counts modifyLink(CoinSimplexInt index,CoinSimplexInt count)726 inline void modifyLink(CoinSimplexInt index, CoinSimplexInt count) 727 { 728 CoinSimplexInt *COIN_RESTRICT nextCount = nextCountAddress_; 729 CoinSimplexInt *COIN_RESTRICT lastCount = lastCountAddress_; 730 CoinSimplexInt *COIN_RESTRICT firstCount = this->firstCount(); 731 CoinSimplexInt next2 = firstCount[count]; 732 if (next2 == index) 733 return; 734 firstCount[count] = index; 735 CoinSimplexInt next = nextCount[index]; 736 CoinSimplexInt last = lastCount[index]; 737 assert(next != index); 738 assert(last != index); 739 nextCount[index] = next2; 740 lastCount[index] = count - numberRows_ - 2; // points to firstCount[count] 741 if (next >= 0) 742 lastCount[next] = last; 743 if (next2 >= 0) 744 lastCount[next2] = index; 745 if (last >= 0) { 746 nextCount[last] = next; 747 } else { 748 int count = last + numberRows_ + 2; 749 firstCount[count] = next; 750 } 751 } 752 /// Separate out links with same row/column count 753 void separateLinks(); 754 void separateLinks(CoinSimplexInt, CoinSimplexInt); 755 /// Cleans up at end of factorization 756 void cleanup(); 757 /// Set up addresses from arrays 758 void doAddresses(); 759 760 /// Updates part of column (FTRANL) 761 void updateColumnL(CoinIndexedVector *region 762 #if ABC_SMALL < 2 763 , 764 CoinAbcStatistics &statistics 765 #endif 766 #if ABC_PARALLEL 767 , 768 int whichSparse = 0 769 #endif 770 ) const; 771 /// Updates part of column (FTRANL) when densish 772 void updateColumnLDensish(CoinIndexedVector *region) const; 773 /// Updates part of column (FTRANL) when dense (i.e. do as inner products) 774 void updateColumnLDense(CoinIndexedVector *region) const; 775 /// Updates part of column (FTRANL) when sparse 776 void updateColumnLSparse(CoinIndexedVector *region 777 #if ABC_PARALLEL 778 , 779 int whichSparse 780 #endif 781 ) const; 782 783 /// Updates part of column (FTRANR) without FT update 784 void updateColumnR(CoinIndexedVector *region 785 #if ABC_SMALL < 2 786 , 787 CoinAbcStatistics &statistics 788 #endif 789 #if ABC_PARALLEL 790 , 791 int whichSparse = 0 792 #endif 793 ) const; 794 /// Store update after doing L and R - retuns false if no room 795 bool storeFT( 796 #if ABC_SMALL < 3 797 const 798 #endif 799 CoinIndexedVector *regionFT); 800 /// Updates part of column (FTRANU) 801 void updateColumnU(CoinIndexedVector *region 802 #if ABC_SMALL < 2 803 , 804 CoinAbcStatistics &statistics 805 #endif 806 #if ABC_PARALLEL 807 , 808 int whichSparse = 0 809 #endif 810 ) const; 811 812 /// Updates part of column (FTRANU) when sparse 813 void updateColumnUSparse(CoinIndexedVector *regionSparse 814 #if ABC_PARALLEL 815 , 816 int whichSparse 817 #endif 818 ) const; 819 /// Updates part of column (FTRANU) 820 void updateColumnUDensish(CoinIndexedVector *regionSparse) const; 821 /// Updates part of column (FTRANU) when dense (i.e. do as inner products) 822 void updateColumnUDense(CoinIndexedVector *regionSparse) const; 823 /// Updates part of 2 columns (FTRANU) real work 824 void updateTwoColumnsUDensish( 825 CoinSimplexInt &numberNonZero1, 826 CoinFactorizationDouble *COIN_RESTRICT region1, 827 CoinSimplexInt *COIN_RESTRICT index1, 828 CoinSimplexInt &numberNonZero2, 829 CoinFactorizationDouble *COIN_RESTRICT region2, 830 CoinSimplexInt *COIN_RESTRICT index2) const; 831 /// Updates part of column PFI (FTRAN) (after rest) 832 void updateColumnPFI(CoinIndexedVector *regionSparse) const; 833 /// Updates part of column transpose PFI (BTRAN) (before rest) 834 void updateColumnTransposePFI(CoinIndexedVector *region) const; 835 /** Updates part of column transpose (BTRANU), 836 assumes index is sorted i.e. region is correct */ 837 void updateColumnTransposeU(CoinIndexedVector *region, 838 CoinSimplexInt smallestIndex 839 #if ABC_SMALL < 2 840 , 841 CoinAbcStatistics &statistics 842 #endif 843 #if ABC_PARALLEL 844 , 845 int whichCpu 846 #endif 847 ) const; 848 /** Updates part of column transpose (BTRANU) when densish, 849 assumes index is sorted i.e. region is correct */ 850 void updateColumnTransposeUDensish(CoinIndexedVector *region, 851 CoinSimplexInt smallestIndex) const; 852 /** Updates part of column transpose (BTRANU) when sparse, 853 assumes index is sorted i.e. region is correct */ 854 void updateColumnTransposeUSparse(CoinIndexedVector *region 855 #if ABC_PARALLEL 856 , 857 int whichSparse 858 #endif 859 ) const; 860 /** Updates part of column transpose (BTRANU) by column 861 assumes index is sorted i.e. region is correct */ 862 void updateColumnTransposeUByColumn(CoinIndexedVector *region, 863 CoinSimplexInt smallestIndex) const; 864 865 /// Updates part of column transpose (BTRANR) 866 void updateColumnTransposeR(CoinIndexedVector *region 867 #if ABC_SMALL < 2 868 , 869 CoinAbcStatistics &statistics 870 #endif 871 ) const; 872 /// Updates part of column transpose (BTRANR) when dense 873 void updateColumnTransposeRDensish(CoinIndexedVector *region) const; 874 /// Updates part of column transpose (BTRANR) when sparse 875 void updateColumnTransposeRSparse(CoinIndexedVector *region) const; 876 877 /// Updates part of column transpose (BTRANL) 878 void updateColumnTransposeL(CoinIndexedVector *region 879 #if ABC_SMALL < 2 880 , 881 CoinAbcStatistics &statistics 882 #endif 883 #if ABC_PARALLEL 884 , 885 int whichSparse 886 #endif 887 ) const; 888 /// Updates part of column transpose (BTRANL) when densish by column 889 void updateColumnTransposeLDensish(CoinIndexedVector *region) const; 890 /// Updates part of column transpose (BTRANL) when densish by row 891 void updateColumnTransposeLByRow(CoinIndexedVector *region) const; 892 /// Updates part of column transpose (BTRANL) when sparse (by Row) 893 void updateColumnTransposeLSparse(CoinIndexedVector *region 894 #if ABC_PARALLEL 895 , 896 int whichSparse 897 #endif 898 ) const; 899 public: 900 /** Replaces one Column to basis for PFI 901 returns 0=OK, 1=Probably OK, 2=singular, 3=no room. 902 In this case region is not empty - it is incoming variable (updated) 903 */ 904 CoinSimplexInt replaceColumnPFI(CoinIndexedVector *regionSparse, 905 CoinSimplexInt pivotRow, CoinSimplexDouble alpha); 906 907 protected: 908 /** Returns accuracy status of replaceColumn 909 returns 0=OK, 1=Probably OK, 2=singular */ 910 CoinSimplexInt checkPivot(CoinSimplexDouble saveFromU, CoinSimplexDouble oldPivot) const; 911 /// 0 fine, -99 singular, 2 dense 912 int pivot(CoinSimplexInt pivotRow, 913 CoinSimplexInt pivotColumn, 914 CoinBigIndex pivotRowPosition, 915 CoinBigIndex pivotColumnPosition, 916 CoinFactorizationDouble *COIN_RESTRICT work, 917 CoinSimplexUnsignedInt *COIN_RESTRICT workArea2, 918 CoinSimplexInt increment2, 919 int *COIN_RESTRICT markRow); 920 int pivot(CoinSimplexInt &pivotRow, 921 CoinSimplexInt &pivotColumn, 922 CoinBigIndex pivotRowPosition, 923 CoinBigIndex pivotColumnPosition, 924 int *COIN_RESTRICT markRow); 925 #if ABC_SMALL < 2 926 #define CONVERTROW 2 927 #elif ABC_SMALL < 4 928 #else 929 #undef ABC_DENSE_CODE 930 #define ABC_DENSE_CODE 0 931 #endif 932 933 //@} 934 ////////////////// data ////////////////// 935 protected: 936 /**@name data */ 937 //@{ 938 CoinSimplexInt *pivotColumnAddress_; 939 CoinSimplexInt *permuteAddress_; 940 CoinFactorizationDouble *pivotRegionAddress_; 941 CoinFactorizationDouble *elementUAddress_; 942 CoinSimplexInt *indexRowUAddress_; 943 CoinSimplexInt *numberInColumnAddress_; 944 CoinSimplexInt *numberInColumnPlusAddress_; 945 #ifdef ABC_USE_FUNCTION_POINTERS 946 /// Array of function pointers 947 scatterStruct *scatterPointersUColumnAddress_; 948 CoinFactorizationDouble *elementUColumnPlusAddress_; 949 #endif 950 CoinBigIndex *startColumnUAddress_; 951 #if CONVERTROW 952 CoinBigIndex *convertRowToColumnUAddress_; 953 #if CONVERTROW > 1 954 CoinBigIndex *convertColumnToRowUAddress_; 955 #endif 956 #endif 957 #if ABC_SMALL < 2 958 CoinFactorizationDouble *elementRowUAddress_; 959 #endif 960 CoinBigIndex *startRowUAddress_; 961 CoinSimplexInt *numberInRowAddress_; 962 CoinSimplexInt *indexColumnUAddress_; 963 CoinSimplexInt *firstCountAddress_; 964 /// Next Row/Column with count 965 CoinSimplexInt *nextCountAddress_; 966 /// Previous Row/Column with count 967 CoinSimplexInt *lastCountAddress_; 968 CoinSimplexInt *nextColumnAddress_; 969 CoinSimplexInt *lastColumnAddress_; 970 CoinSimplexInt *nextRowAddress_; 971 CoinSimplexInt *lastRowAddress_; 972 CoinSimplexInt *saveColumnAddress_; 973 //CoinSimplexInt * saveColumnAddress2_; 974 CoinCheckZero *markRowAddress_; 975 CoinSimplexInt *listAddress_; 976 CoinFactorizationDouble *elementLAddress_; 977 CoinSimplexInt *indexRowLAddress_; 978 CoinBigIndex *startColumnLAddress_; 979 #if ABC_SMALL < 2 980 CoinBigIndex *startRowLAddress_; 981 #endif 982 CoinSimplexInt *pivotLinkedBackwardsAddress_; 983 CoinSimplexInt *pivotLinkedForwardsAddress_; 984 CoinSimplexInt *pivotLOrderAddress_; 985 CoinBigIndex *startColumnRAddress_; 986 /// Elements of R 987 CoinFactorizationDouble *elementRAddress_; 988 /// Row indices for R 989 CoinSimplexInt *indexRowRAddress_; 990 CoinSimplexInt *indexColumnLAddress_; 991 CoinFactorizationDouble *elementByRowLAddress_; 992 #if ABC_SMALL < 4 993 CoinFactorizationDouble *denseAreaAddress_; 994 #endif 995 CoinFactorizationDouble *workAreaAddress_; 996 CoinSimplexUnsignedInt *workArea2Address_; 997 mutable CoinSimplexInt *sparseAddress_; 998 #ifdef SMALL_PERMUTE 999 CoinSimplexInt *fromSmallToBigRow_; 1000 CoinSimplexInt *fromSmallToBigColumn_; 1001 #endif 1002 /// Number of Rows after iterating 1003 CoinSimplexInt numberRowsExtra_; 1004 /// Maximum number of Rows after iterating 1005 CoinSimplexInt maximumRowsExtra_; 1006 /// Size of small inverse 1007 CoinSimplexInt numberRowsSmall_; 1008 /// Number factorized in L 1009 CoinSimplexInt numberGoodL_; 1010 /// Number Rows left (numberRows-numberGood) 1011 CoinSimplexInt numberRowsLeft_; 1012 /// Number of elements in U (to go) 1013 /// or while iterating total overall 1014 CoinBigIndex totalElements_; 1015 /// First place in funny copy zeroed out 1016 CoinBigIndex firstZeroed_; 1017 #if ABC_SMALL < 2 1018 /// Below this use sparse technology - if 0 then no L row copy 1019 CoinSimplexInt sparseThreshold_; 1020 #endif 1021 /// Number in R 1022 CoinSimplexInt numberR_; 1023 /// Length of R stuff 1024 CoinBigIndex lengthR_; 1025 /// length of area reserved for R 1026 CoinBigIndex lengthAreaR_; 1027 /// Number in L 1028 CoinBigIndex numberL_; 1029 /// Base of L 1030 CoinBigIndex baseL_; 1031 /// Length of L 1032 CoinBigIndex lengthL_; 1033 /// Length of area reserved for L 1034 CoinBigIndex lengthAreaL_; 1035 /// Number in U 1036 CoinSimplexInt numberU_; 1037 /// Maximum space used in U 1038 CoinBigIndex maximumU_; 1039 /// Length of U 1040 CoinBigIndex lengthU_; 1041 /// Length of area reserved for U 1042 CoinBigIndex lengthAreaU_; 1043 /// Last entry by column for U 1044 CoinBigIndex lastEntryByColumnU_; 1045 #ifdef ABC_USE_FUNCTION_POINTERS 1046 /// Last entry by column for U 1047 CoinBigIndex lastEntryByColumnUPlus_; 1048 /// Length of U 1049 CoinBigIndex lengthAreaUPlus_; 1050 #endif 1051 /// Last entry by row for U 1052 CoinBigIndex lastEntryByRowU_; 1053 /// Number of trials before rejection 1054 CoinSimplexInt numberTrials_; 1055 #if ABC_SMALL < 4 1056 /// Leading dimension for dense 1057 CoinSimplexInt leadingDimension_; 1058 #endif 1059 #if COIN_BIG_DOUBLE == 1 1060 /// Work arrays 1061 mutable CoinFactorizationLongDoubleArrayWithLength longArray_[FACTOR_CPU]; 1062 /// Associated CoinIndexedVector 1063 mutable CoinIndexedVector *associatedVector_[FACTOR_CPU]; 1064 #endif 1065 /// Pivot order for each Column 1066 CoinIntArrayWithLength pivotColumn_; 1067 /// Permutation vector for pivot row order 1068 CoinIntArrayWithLength permute_; 1069 /// Start of each Row as pointer 1070 CoinBigIndexArrayWithLength startRowU_; 1071 /// Number in each Row 1072 CoinIntArrayWithLength numberInRow_; 1073 /// Number in each Column 1074 CoinIntArrayWithLength numberInColumn_; 1075 /// Number in each Column including pivoted 1076 CoinIntArrayWithLength numberInColumnPlus_; 1077 /** First Row/Column with count of k, 1078 can tell which by offset - Rows then Columns */ 1079 CoinIntArrayWithLength firstCount_; 1080 /// Next Column in memory order 1081 CoinIntArrayWithLength nextColumn_; 1082 /// Previous Column in memory order 1083 CoinIntArrayWithLength lastColumn_; 1084 /// Next Row in memory order 1085 CoinIntArrayWithLength nextRow_; 1086 /// Previous Row in memory order 1087 CoinIntArrayWithLength lastRow_; 1088 /// Columns left to do in a single pivot 1089 CoinIntArrayWithLength saveColumn_; 1090 /// Marks rows to be updated 1091 CoinIntArrayWithLength markRow_; 1092 /// Base address for U (may change) 1093 CoinIntArrayWithLength indexColumnU_; 1094 /// Inverses of pivot values 1095 CoinFactorizationDoubleArrayWithLength pivotRegion_; 1096 /// Elements of U 1097 CoinFactorizationDoubleArrayWithLength elementU_; 1098 /// Row indices of U 1099 CoinIntArrayWithLength indexRowU_; 1100 /// Start of each column in U 1101 CoinBigIndexArrayWithLength startColumnU_; 1102 #ifdef ABC_USE_FUNCTION_POINTERS 1103 /// Array of structs for U Column 1104 CoinArbitraryArrayWithLength scatterUColumn_; 1105 #endif 1106 #if CONVERTROW 1107 /// Converts rows to columns in U 1108 CoinBigIndexArrayWithLength convertRowToColumnU_; 1109 #if CONVERTROW > 1 1110 /// Converts columns to rows in U 1111 CoinBigIndexArrayWithLength convertColumnToRowU_; 1112 #endif 1113 #endif 1114 #if ABC_SMALL < 2 1115 /// Elements of U by row 1116 CoinFactorizationDoubleArrayWithLength elementRowU_; 1117 #endif 1118 /// Elements of L 1119 CoinFactorizationDoubleArrayWithLength elementL_; 1120 /// Row indices of L 1121 CoinIntArrayWithLength indexRowL_; 1122 /// Start of each column in L 1123 CoinBigIndexArrayWithLength startColumnL_; 1124 #if ABC_SMALL < 4 1125 /// Dense area 1126 CoinFactorizationDoubleArrayWithLength denseArea_; 1127 #endif 1128 /// First work area 1129 CoinFactorizationDoubleArrayWithLength workArea_; 1130 /// Second work area 1131 CoinUnsignedIntArrayWithLength workArea2_; 1132 #if ABC_SMALL < 2 1133 /// Start of each row in L 1134 CoinBigIndexArrayWithLength startRowL_; 1135 /// Index of column in row for L 1136 CoinIntArrayWithLength indexColumnL_; 1137 /// Elements in L (row copy) 1138 CoinFactorizationDoubleArrayWithLength elementByRowL_; 1139 /// Sparse regions 1140 mutable CoinIntArrayWithLength sparse_; 1141 #endif 1142 /// Detail in messages 1143 CoinSimplexInt messageLevel_; 1144 /// Number of compressions done 1145 CoinBigIndex numberCompressions_; 1146 // last slack pivot row 1147 CoinSimplexInt lastSlack_; 1148 #if ABC_SMALL < 2 1149 /// To decide how to solve 1150 mutable double ftranCountInput_; 1151 mutable double ftranCountAfterL_; 1152 mutable double ftranCountAfterR_; 1153 mutable double ftranCountAfterU_; 1154 double ftranAverageAfterL_; 1155 double ftranAverageAfterR_; 1156 double ftranAverageAfterU_; 1157 #if FACTORIZATION_STATISTICS 1158 double ftranTwiddleFactor1_; 1159 double ftranTwiddleFactor2_; 1160 #endif 1161 mutable CoinSimplexInt numberFtranCounts_; 1162 #endif 1163 /// Maximum rows (ever) (here to use double alignment) 1164 CoinSimplexInt maximumRows_; 1165 #if ABC_SMALL < 2 1166 mutable double ftranFTCountInput_; 1167 mutable double ftranFTCountAfterL_; 1168 mutable double ftranFTCountAfterR_; 1169 mutable double ftranFTCountAfterU_; 1170 double ftranFTAverageAfterL_; 1171 double ftranFTAverageAfterR_; 1172 double ftranFTAverageAfterU_; 1173 #if FACTORIZATION_STATISTICS 1174 double ftranFTTwiddleFactor1_; 1175 double ftranFTTwiddleFactor2_; 1176 #endif 1177 mutable CoinSimplexInt numberFtranFTCounts_; 1178 #endif 1179 #if ABC_SMALL < 4 1180 /// Dense threshold (here to use double alignment) 1181 CoinSimplexInt denseThreshold_; 1182 #endif 1183 #if ABC_SMALL < 2 1184 mutable double btranCountInput_; 1185 mutable double btranCountAfterU_; 1186 mutable double btranCountAfterR_; 1187 mutable double btranCountAfterL_; 1188 double btranAverageAfterU_; 1189 double btranAverageAfterR_; 1190 double btranAverageAfterL_; 1191 #if FACTORIZATION_STATISTICS 1192 double btranTwiddleFactor1_; 1193 double btranTwiddleFactor2_; 1194 #endif 1195 mutable CoinSimplexInt numberBtranCounts_; 1196 #endif 1197 /// Maximum maximum pivots 1198 CoinSimplexInt maximumMaximumPivots_; 1199 #if ABC_SMALL < 2 1200 /// To decide how to solve 1201 mutable double ftranFullCountInput_; 1202 mutable double ftranFullCountAfterL_; 1203 mutable double ftranFullCountAfterR_; 1204 mutable double ftranFullCountAfterU_; 1205 double ftranFullAverageAfterL_; 1206 double ftranFullAverageAfterR_; 1207 double ftranFullAverageAfterU_; 1208 #if FACTORIZATION_STATISTICS 1209 double ftranFullTwiddleFactor1_; 1210 double ftranFullTwiddleFactor2_; 1211 #endif 1212 mutable CoinSimplexInt numberFtranFullCounts_; 1213 #endif 1214 /// Rows first time nonzero 1215 CoinSimplexInt initialNumberRows_; 1216 #if ABC_SMALL < 2 1217 /// To decide how to solve 1218 mutable double btranFullCountInput_; 1219 mutable double btranFullCountAfterL_; 1220 mutable double btranFullCountAfterR_; 1221 mutable double btranFullCountAfterU_; 1222 double btranFullAverageAfterL_; 1223 double btranFullAverageAfterR_; 1224 double btranFullAverageAfterU_; 1225 #if FACTORIZATION_STATISTICS 1226 double btranFullTwiddleFactor1_; 1227 double btranFullTwiddleFactor2_; 1228 #endif 1229 mutable CoinSimplexInt numberBtranFullCounts_; 1230 #endif 1231 /** State of saved version and what can be done 1232 0 - nothing saved 1233 1 - saved and can go back to previous save by unwinding 1234 2 - saved - getting on for a full copy 1235 higher bits - see ABC_FAC.... 1236 */ 1237 CoinSimplexInt state_; 1238 /// Size in bytes of a sparseArray 1239 CoinBigIndex sizeSparseArray_; 1240 1241 public: 1242 #if ABC_SMALL < 2 1243 #if ABC_SMALL >= 0 gotLCopy() const1244 inline bool gotLCopy() const 1245 { 1246 return ((state_ & ABC_FAC_GOT_LCOPY) != 0); 1247 } setNoGotLCopy()1248 inline void setNoGotLCopy() { state_ &= ~ABC_FAC_GOT_LCOPY; } setYesGotLCopy()1249 inline void setYesGotLCopy() { state_ |= ABC_FAC_GOT_LCOPY; } gotRCopy() const1250 inline bool gotRCopy() const { return ((state_ & ABC_FAC_GOT_RCOPY) != 0); } setNoGotRCopy()1251 inline void setNoGotRCopy() { state_ &= ~ABC_FAC_GOT_RCOPY; } setYesGotRCopy()1252 inline void setYesGotRCopy() { state_ |= ABC_FAC_GOT_RCOPY; } gotUCopy() const1253 inline bool gotUCopy() const { return ((state_ & ABC_FAC_GOT_UCOPY) != 0); } setNoGotUCopy()1254 inline void setNoGotUCopy() { state_ &= ~ABC_FAC_GOT_UCOPY; } setYesGotUCopy()1255 inline void setYesGotUCopy() { state_ |= ABC_FAC_GOT_UCOPY; } gotSparse() const1256 inline bool gotSparse() const { return ((state_ & ABC_FAC_GOT_SPARSE) != 0); } setNoGotSparse()1257 inline void setNoGotSparse() { state_ &= ~ABC_FAC_GOT_SPARSE; } setYesGotSparse()1258 inline void setYesGotSparse() { state_ |= ABC_FAC_GOT_SPARSE; } 1259 #else 1260 // force use of copies 1261 inline bool gotLCopy() const { return true; } 1262 inline void setNoGotLCopy() {} 1263 inline void setYesGotLCopy() {} 1264 inline bool gotRCopy() const { return true; } 1265 inline void setNoGotRCopy() {} 1266 inline void setYesGotRCopy() {} 1267 inline bool gotUCopy() const { return true; } 1268 inline void setNoGotUCopy() {} 1269 inline void setYesGotUCopy() {} 1270 inline bool gotSparse() const { return true; } 1271 inline void setNoGotSparse() {} 1272 inline void setYesGotSparse() {} 1273 #endif 1274 #else 1275 // force no use of copies 1276 inline bool gotLCopy() const { return false; } 1277 inline void setNoGotLCopy() {} 1278 inline void setYesGotLCopy() {} 1279 inline bool gotRCopy() const { return false; } 1280 inline void setNoGotRCopy() {} 1281 inline void setYesGotRCopy() {} 1282 inline bool gotUCopy() const { return false; } 1283 inline void setNoGotUCopy() {} 1284 inline void setYesGotUCopy() {} 1285 inline bool gotSparse() const { return false; } 1286 inline void setNoGotSparse() {} 1287 inline void setYesGotSparse() {} 1288 #endif 1289 /** Array persistence flag 1290 If 0 then as now (delete/new) 1291 1 then only do arrays if bigger needed 1292 2 as 1 but give a bit extra if bigger needed 1293 */ 1294 //CoinSimplexInt persistenceFlag_; 1295 //@} 1296 }; 1297 1298 /* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2 1299 */ 1300