00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef CoinFactorization_H
00011 #define CoinFactorization_H
00012
00013 #include <iostream>
00014 #include <string>
00015 #include <cassert>
00016 #include <cstdio>
00017 #include "CoinFinite.hpp"
00018 #include "CoinIndexedVector.hpp"
00019 class CoinPackedMatrix;
00045 class CoinFactorization {
00046 friend void CoinFactorizationUnitTest( const std::string & mpsDir );
00047
00048 public:
00049
00052
00053 CoinFactorization ( );
00055 CoinFactorization ( const CoinFactorization &other);
00056
00058 ~CoinFactorization ( );
00060 void almostDestructor();
00062 void show_self ( ) const;
00064 int saveFactorization (const char * file ) const;
00068 int restoreFactorization (const char * file , bool factor=false) ;
00070 void sort ( ) const;
00072 CoinFactorization & operator = ( const CoinFactorization & other );
00074
00084 int factorize ( const CoinPackedMatrix & matrix,
00085 int rowIsBasic[], int columnIsBasic[] ,
00086 double areaFactor = 0.0 );
00097 int factorize ( int numberRows,
00098 int numberColumns,
00099 CoinBigIndex numberElements,
00100 CoinBigIndex maximumL,
00101 CoinBigIndex maximumU,
00102 const int indicesRow[],
00103 const int indicesColumn[], const double elements[] ,
00104 int permutation[],
00105 double areaFactor = 0.0);
00110 int factorizePart1 ( int numberRows,
00111 int numberColumns,
00112 CoinBigIndex estimateNumberElements,
00113 int * indicesRow[],
00114 int * indicesColumn[],
00115 CoinFactorizationDouble * elements[],
00116 double areaFactor = 0.0);
00123 int factorizePart2 (int permutation[],int exactNumberElements);
00125 double conditionNumber() const;
00126
00128
00131
00132 inline int status ( ) const {
00133 return status_;
00134 }
00136 inline void setStatus ( int value)
00137 { status_=value; }
00139 inline int pivots ( ) const {
00140 return numberPivots_;
00141 }
00143 inline void setPivots ( int value )
00144 { numberPivots_=value; }
00146 inline int *permute ( ) const {
00147 return permute_.array();
00148 }
00150 inline int *pivotColumn ( ) const {
00151 return pivotColumn_.array();
00152 }
00154 inline CoinFactorizationDouble *pivotRegion ( ) const {
00155 return pivotRegion_.array();
00156 }
00158 inline int *permuteBack ( ) const {
00159 return permuteBack_.array();
00160 }
00163 inline int *pivotColumnBack ( ) const {
00164
00165 return pivotColumnBack_.array();
00166 }
00168 inline CoinBigIndex * startRowL() const
00169 { return startRowL_.array();}
00170
00172 inline CoinBigIndex * startColumnL() const
00173 { return startColumnL_.array();}
00174
00176 inline int * indexColumnL() const
00177 { return indexColumnL_.array();}
00178
00180 inline int * indexRowL() const
00181 { return indexRowL_.array();}
00182
00184 inline CoinFactorizationDouble * elementByRowL() const
00185 { return elementByRowL_.array();}
00186
00188 inline int numberRowsExtra ( ) const {
00189 return numberRowsExtra_;
00190 }
00192 inline void setNumberRows(int value)
00193 { numberRows_ = value; }
00195 inline int numberRows ( ) const {
00196 return numberRows_;
00197 }
00199 inline CoinBigIndex numberL() const
00200 { return numberL_;}
00201
00203 inline CoinBigIndex baseL() const
00204 { return baseL_;}
00206 inline int maximumRowsExtra ( ) const {
00207 return maximumRowsExtra_;
00208 }
00210 inline int numberColumns ( ) const {
00211 return numberColumns_;
00212 }
00214 inline int numberElements ( ) const {
00215 return totalElements_;
00216 }
00218 inline int numberForrestTomlin ( ) const {
00219 return numberInColumn_.array()[numberColumnsExtra_];
00220 }
00222 inline int numberGoodColumns ( ) const {
00223 return numberGoodU_;
00224 }
00226 inline double areaFactor ( ) const {
00227 return areaFactor_;
00228 }
00229 inline void areaFactor ( double value ) {
00230 areaFactor_=value;
00231 }
00233 double adjustedAreaFactor() const;
00235 inline void relaxAccuracyCheck(double value)
00236 { relaxCheck_ = value;}
00237 inline double getAccuracyCheck() const
00238 { return relaxCheck_;}
00240 inline int messageLevel ( ) const {
00241 return messageLevel_ ;
00242 }
00243 void messageLevel ( int value );
00245 inline int maximumPivots ( ) const {
00246 return maximumPivots_ ;
00247 }
00248 void maximumPivots ( int value );
00249
00251 inline int denseThreshold() const
00252 { return denseThreshold_;}
00254 inline void setDenseThreshold(int value)
00255 { denseThreshold_ = value;}
00257 inline double pivotTolerance ( ) const {
00258 return pivotTolerance_ ;
00259 }
00260 void pivotTolerance ( double value );
00262 inline double zeroTolerance ( ) const {
00263 return zeroTolerance_ ;
00264 }
00265 void zeroTolerance ( double value );
00266 #ifndef COIN_FAST_CODE
00268 inline double slackValue ( ) const {
00269 return slackValue_ ;
00270 }
00271 void slackValue ( double value );
00272 #endif
00274 double maximumCoefficient() const;
00276 inline bool forrestTomlin() const
00277 { return doForrestTomlin_;}
00278 inline void setForrestTomlin(bool value)
00279 { doForrestTomlin_=value;}
00281 inline bool spaceForForrestTomlin() const
00282 {
00283 CoinBigIndex start = startColumnU_.array()[maximumColumnsExtra_];
00284 CoinBigIndex space = lengthAreaU_ - ( start + numberRowsExtra_ );
00285 return (space>=0)&&doForrestTomlin_;
00286 }
00288
00291
00293 inline int numberDense() const
00294 { return numberDense_;}
00295
00297 inline CoinBigIndex numberElementsU ( ) const {
00298 return lengthU_;
00299 }
00301 inline void setNumberElementsU(CoinBigIndex value)
00302 { lengthU_ = value; }
00304 inline CoinBigIndex lengthAreaU ( ) const {
00305 return lengthAreaU_;
00306 }
00308 inline CoinBigIndex numberElementsL ( ) const {
00309 return lengthL_;
00310 }
00312 inline CoinBigIndex lengthAreaL ( ) const {
00313 return lengthAreaL_;
00314 }
00316 inline CoinBigIndex numberElementsR ( ) const {
00317 return lengthR_;
00318 }
00320 inline CoinBigIndex numberCompressions() const
00321 { return numberCompressions_;}
00323 inline int * numberInRow() const
00324 { return numberInRow_.array();}
00326 inline int * numberInColumn() const
00327 { return numberInColumn_.array();}
00329 inline CoinFactorizationDouble * elementU() const
00330 { return elementU_.array();}
00332 inline int * indexRowU() const
00333 { return indexRowU_.array();}
00335 inline CoinBigIndex * startColumnU() const
00336 { return startColumnU_.array();}
00338 inline int maximumColumnsExtra()
00339 { return maximumColumnsExtra_;}
00343 inline int biasLU() const
00344 { return biasLU_;}
00345 inline void setBiasLU(int value)
00346 { biasLU_=value;}
00352 inline int persistenceFlag() const
00353 { return persistenceFlag_;}
00354 void setPersistenceFlag(int value);
00356
00359
00367 int replaceColumn ( CoinIndexedVector * regionSparse,
00368 int pivotRow,
00369 double pivotCheck ,
00370 bool checkBeforeModifying=false);
00372
00382 int updateColumnFT ( CoinIndexedVector * regionSparse,
00383 CoinIndexedVector * regionSparse2);
00386 int updateColumn ( CoinIndexedVector * regionSparse,
00387 CoinIndexedVector * regionSparse2,
00388 bool noPermute=false) const;
00394 int updateTwoColumnsFT ( CoinIndexedVector * regionSparse1,
00395 CoinIndexedVector * regionSparse2,
00396 CoinIndexedVector * regionSparse3,
00397 bool noPermuteRegion3=false) ;
00402 int updateColumnTranspose ( CoinIndexedVector * regionSparse,
00403 CoinIndexedVector * regionSparse2) const;
00405 void goSparse();
00407 inline int sparseThreshold ( ) const
00408 { return sparseThreshold_;}
00410 void sparseThreshold ( int value );
00412
00413
00417
00418 inline void clearArrays()
00419 { gutsOfDestructor();}
00421
00424
00427 int add ( CoinBigIndex numberElements,
00428 int indicesRow[],
00429 int indicesColumn[], double elements[] );
00430
00433 int addColumn ( CoinBigIndex numberElements,
00434 int indicesRow[], double elements[] );
00435
00438 int addRow ( CoinBigIndex numberElements,
00439 int indicesColumn[], double elements[] );
00440
00442 int deleteColumn ( int Row );
00444 int deleteRow ( int Row );
00445
00449 int replaceRow ( int whichRow, int numberElements,
00450 const int indicesColumn[], const double elements[] );
00452 void emptyRows(int numberToEmpty, const int which[]);
00454
00455
00456 void checkSparse();
00458 inline bool collectStatistics() const
00459 { return collectStatistics_;}
00461 inline void setCollectStatistics(bool onOff) const
00462 { collectStatistics_ = onOff;}
00464 void gutsOfDestructor(int type=1);
00466 void gutsOfInitialize(int type);
00467 void gutsOfCopy(const CoinFactorization &other);
00468
00470 void resetStatistics();
00471
00472
00474
00476
00477 void getAreas ( int numberRows,
00478 int numberColumns,
00479 CoinBigIndex maximumL,
00480 CoinBigIndex maximumU );
00481
00484 void preProcess ( int state,
00485 int possibleDuplicates = -1 );
00487 int factor ( );
00488 protected:
00491 int factorSparse ( );
00494 int factorSparseSmall ( );
00497 int factorSparseLarge ( );
00500 int factorDense ( );
00501
00503 bool pivotOneOtherRow ( int pivotRow,
00504 int pivotColumn );
00506 bool pivotRowSingleton ( int pivotRow,
00507 int pivotColumn );
00509 bool pivotColumnSingleton ( int pivotRow,
00510 int pivotColumn );
00511
00516 bool getColumnSpace ( int iColumn,
00517 int extraNeeded );
00518
00521 bool reorderU();
00525 bool getColumnSpaceIterateR ( int iColumn, double value,
00526 int iRow);
00532 CoinBigIndex getColumnSpaceIterate ( int iColumn, double value,
00533 int iRow);
00537 bool getRowSpace ( int iRow, int extraNeeded );
00538
00542 bool getRowSpaceIterate ( int iRow,
00543 int extraNeeded );
00545 void checkConsistency ( );
00547 inline void addLink ( int index, int count ) {
00548 int *nextCount = nextCount_.array();
00549 int *firstCount = firstCount_.array();
00550 int *lastCount = lastCount_.array();
00551 int next = firstCount[count];
00552 lastCount[index] = -2 - count;
00553 if ( next < 0 ) {
00554
00555 firstCount[count] = index;
00556 nextCount[index] = -1;
00557 } else {
00558 firstCount[count] = index;
00559 nextCount[index] = next;
00560 lastCount[next] = index;
00561 }}
00563 inline void deleteLink ( int index ) {
00564 int *nextCount = nextCount_.array();
00565 int *firstCount = firstCount_.array();
00566 int *lastCount = lastCount_.array();
00567 int next = nextCount[index];
00568 int last = lastCount[index];
00569 if ( last >= 0 ) {
00570 nextCount[last] = next;
00571 } else {
00572 int count = -last - 2;
00573
00574 firstCount[count] = next;
00575 }
00576 if ( next >= 0 ) {
00577 lastCount[next] = last;
00578 }
00579 nextCount[index] = -2;
00580 lastCount[index] = -2;
00581 return;
00582 }
00584 void separateLinks(int count,bool rowsFirst);
00586 void cleanup ( );
00587
00589 void updateColumnL ( CoinIndexedVector * region, int * indexIn ) const;
00591 void updateColumnLDensish ( CoinIndexedVector * region, int * indexIn ) const;
00593 void updateColumnLSparse ( CoinIndexedVector * region, int * indexIn ) const;
00595 void updateColumnLSparsish ( CoinIndexedVector * region, int * indexIn ) const;
00596
00598 void updateColumnR ( CoinIndexedVector * region ) const;
00601 void updateColumnRFT ( CoinIndexedVector * region, int * indexIn );
00602
00604 void updateColumnU ( CoinIndexedVector * region, int * indexIn) const;
00605
00607 void updateColumnUSparse ( CoinIndexedVector * regionSparse,
00608 int * indexIn) const;
00610 void updateColumnUSparsish ( CoinIndexedVector * regionSparse,
00611 int * indexIn) const;
00613 int updateColumnUDensish ( double * COIN_RESTRICT region,
00614 int * COIN_RESTRICT regionIndex) const;
00616 void updateTwoColumnsUDensish (
00617 int & numberNonZero1,
00618 double * COIN_RESTRICT region1,
00619 int * COIN_RESTRICT index1,
00620 int & numberNonZero2,
00621 double * COIN_RESTRICT region2,
00622 int * COIN_RESTRICT index2) const;
00624 void updateColumnPFI ( CoinIndexedVector * regionSparse) const;
00626 void permuteBack ( CoinIndexedVector * regionSparse,
00627 CoinIndexedVector * outVector) const;
00628
00630 void updateColumnTransposePFI ( CoinIndexedVector * region) const;
00633 void updateColumnTransposeU ( CoinIndexedVector * region,
00634 int smallestIndex) const;
00637 void updateColumnTransposeUSparsish ( CoinIndexedVector * region,
00638 int smallestIndex) const;
00641 void updateColumnTransposeUDensish ( CoinIndexedVector * region,
00642 int smallestIndex) const;
00645 void updateColumnTransposeUSparse ( CoinIndexedVector * region) const;
00646
00648 void updateColumnTransposeR ( CoinIndexedVector * region ) const;
00650 void updateColumnTransposeRDensish ( CoinIndexedVector * region ) const;
00652 void updateColumnTransposeRSparse ( CoinIndexedVector * region ) const;
00653
00655 void updateColumnTransposeL ( CoinIndexedVector * region ) const;
00657 void updateColumnTransposeLDensish ( CoinIndexedVector * region ) const;
00659 void updateColumnTransposeLByRow ( CoinIndexedVector * region ) const;
00661 void updateColumnTransposeLSparsish ( CoinIndexedVector * region ) const;
00663 void updateColumnTransposeLSparse ( CoinIndexedVector * region ) const;
00664 public:
00669 int replaceColumnPFI ( CoinIndexedVector * regionSparse,
00670 int pivotRow, double alpha);
00671 protected:
00674 int checkPivot(double saveFromU, double oldPivot) const;
00675
00676 #ifdef INT_IS_8
00677 #define COINFACTORIZATION_BITS_PER_INT 64
00678 #define COINFACTORIZATION_SHIFT_PER_INT 6
00679 #define COINFACTORIZATION_MASK_PER_INT 0x3f
00680 #else
00681 #define COINFACTORIZATION_BITS_PER_INT 32
00682 #define COINFACTORIZATION_SHIFT_PER_INT 5
00683 #define COINFACTORIZATION_MASK_PER_INT 0x1f
00684 #endif
00685 template <class T> inline bool
00686 pivot ( int pivotRow,
00687 int pivotColumn,
00688 CoinBigIndex pivotRowPosition,
00689 CoinBigIndex pivotColumnPosition,
00690 CoinFactorizationDouble work[],
00691 unsigned int workArea2[],
00692 int increment,
00693 int increment2,
00694 T markRow[] ,
00695 int largeInteger)
00696 {
00697 int *indexColumnU = indexColumnU_.array();
00698 CoinBigIndex *startColumnU = startColumnU_.array();
00699 int *numberInColumn = numberInColumn_.array();
00700 CoinFactorizationDouble *elementU = elementU_.array();
00701 int *indexRowU = indexRowU_.array();
00702 CoinBigIndex *startRowU = startRowU_.array();
00703 int *numberInRow = numberInRow_.array();
00704 CoinFactorizationDouble *elementL = elementL_.array();
00705 int *indexRowL = indexRowL_.array();
00706 int *saveColumn = saveColumn_.array();
00707 int *nextRow = nextRow_.array();
00708 int *lastRow = lastRow_.array() ;
00709
00710
00711 int numberInPivotRow = numberInRow[pivotRow] - 1;
00712 CoinBigIndex startColumn = startColumnU[pivotColumn];
00713 int numberInPivotColumn = numberInColumn[pivotColumn] - 1;
00714 CoinBigIndex endColumn = startColumn + numberInPivotColumn + 1;
00715 int put = 0;
00716 CoinBigIndex startRow = startRowU[pivotRow];
00717 CoinBigIndex endRow = startRow + numberInPivotRow + 1;
00718
00719 if ( pivotColumnPosition < 0 ) {
00720 for ( pivotColumnPosition = startRow; pivotColumnPosition < endRow; pivotColumnPosition++ ) {
00721 int iColumn = indexColumnU[pivotColumnPosition];
00722 if ( iColumn != pivotColumn ) {
00723 saveColumn[put++] = iColumn;
00724 } else {
00725 break;
00726 }
00727 }
00728 } else {
00729 for (CoinBigIndex i = startRow ; i < pivotColumnPosition ; i++ ) {
00730 saveColumn[put++] = indexColumnU[i];
00731 }
00732 }
00733 assert (pivotColumnPosition<endRow);
00734 assert (indexColumnU[pivotColumnPosition]==pivotColumn);
00735 pivotColumnPosition++;
00736 for ( ; pivotColumnPosition < endRow; pivotColumnPosition++ ) {
00737 saveColumn[put++] = indexColumnU[pivotColumnPosition];
00738 }
00739
00740 int next = nextRow[pivotRow];
00741 int last = lastRow[pivotRow];
00742
00743 nextRow[last] = next;
00744 lastRow[next] = last;
00745 nextRow[pivotRow] = numberGoodU_;
00746 lastRow[pivotRow] = -2;
00747 numberInRow[pivotRow] = 0;
00748
00749 CoinBigIndex l = lengthL_;
00750
00751 if ( l + numberInPivotColumn > lengthAreaL_ ) {
00752
00753 if ((messageLevel_&4)!=0)
00754 printf("more memory needed in middle of invert\n");
00755 return false;
00756 }
00757
00758 CoinBigIndex lSave = l;
00759
00760 CoinBigIndex * startColumnL = startColumnL_.array();
00761 startColumnL[numberGoodL_] = l;
00762 numberGoodL_++;
00763 startColumnL[numberGoodL_] = l + numberInPivotColumn;
00764 lengthL_ += numberInPivotColumn;
00765 if ( pivotRowPosition < 0 ) {
00766 for ( pivotRowPosition = startColumn; pivotRowPosition < endColumn; pivotRowPosition++ ) {
00767 int iRow = indexRowU[pivotRowPosition];
00768 if ( iRow != pivotRow ) {
00769 indexRowL[l] = iRow;
00770 elementL[l] = elementU[pivotRowPosition];
00771 markRow[iRow] = static_cast<T>(l - lSave);
00772 l++;
00773
00774 CoinBigIndex start = startRowU[iRow];
00775 CoinBigIndex end = start + numberInRow[iRow];
00776 CoinBigIndex where = start;
00777
00778 while ( indexColumnU[where] != pivotColumn ) {
00779 where++;
00780 }
00781 #if DEBUG_COIN
00782 if ( where >= end ) {
00783 abort ( );
00784 }
00785 #endif
00786 indexColumnU[where] = indexColumnU[end - 1];
00787 numberInRow[iRow]--;
00788 } else {
00789 break;
00790 }
00791 }
00792 } else {
00793 CoinBigIndex i;
00794
00795 for ( i = startColumn; i < pivotRowPosition; i++ ) {
00796 int iRow = indexRowU[i];
00797
00798 markRow[iRow] = static_cast<T>(l - lSave);
00799 indexRowL[l] = iRow;
00800 elementL[l] = elementU[i];
00801 l++;
00802
00803 CoinBigIndex start = startRowU[iRow];
00804 CoinBigIndex end = start + numberInRow[iRow];
00805 CoinBigIndex where = start;
00806
00807 while ( indexColumnU[where] != pivotColumn ) {
00808 where++;
00809 }
00810 #if DEBUG_COIN
00811 if ( where >= end ) {
00812 abort ( );
00813 }
00814 #endif
00815 indexColumnU[where] = indexColumnU[end - 1];
00816 numberInRow[iRow]--;
00817 assert (numberInRow[iRow]>=0);
00818 }
00819 }
00820 assert (pivotRowPosition<endColumn);
00821 assert (indexRowU[pivotRowPosition]==pivotRow);
00822 CoinFactorizationDouble pivotElement = elementU[pivotRowPosition];
00823 CoinFactorizationDouble pivotMultiplier = 1.0 / pivotElement;
00824
00825 pivotRegion_.array()[numberGoodU_] = pivotMultiplier;
00826 pivotRowPosition++;
00827 for ( ; pivotRowPosition < endColumn; pivotRowPosition++ ) {
00828 int iRow = indexRowU[pivotRowPosition];
00829
00830 markRow[iRow] = static_cast<T>(l - lSave);
00831 indexRowL[l] = iRow;
00832 elementL[l] = elementU[pivotRowPosition];
00833 l++;
00834
00835 CoinBigIndex start = startRowU[iRow];
00836 CoinBigIndex end = start + numberInRow[iRow];
00837 CoinBigIndex where = start;
00838
00839 while ( indexColumnU[where] != pivotColumn ) {
00840 where++;
00841 }
00842 #if DEBUG_COIN
00843 if ( where >= end ) {
00844 abort ( );
00845 }
00846 #endif
00847 indexColumnU[where] = indexColumnU[end - 1];
00848 numberInRow[iRow]--;
00849 assert (numberInRow[iRow]>=0);
00850 }
00851 markRow[pivotRow] = static_cast<T>(largeInteger);
00852
00853 numberInColumn[pivotColumn] = 0;
00854
00855 int *indexL = &indexRowL[lSave];
00856 CoinFactorizationDouble *multipliersL = &elementL[lSave];
00857
00858
00859 int j;
00860
00861 for ( j = 0; j < numberInPivotColumn; j++ ) {
00862 multipliersL[j] *= pivotMultiplier;
00863 }
00864
00865 CoinBigIndex iErase;
00866 for ( iErase = 0; iErase < increment2 * numberInPivotRow;
00867 iErase++ ) {
00868 workArea2[iErase] = 0;
00869 }
00870 CoinBigIndex added = numberInPivotRow * numberInPivotColumn;
00871 unsigned int *temp2 = workArea2;
00872 int * nextColumn = nextColumn_.array();
00873
00874
00875 int jColumn;
00876 for ( jColumn = 0; jColumn < numberInPivotRow; jColumn++ ) {
00877 int iColumn = saveColumn[jColumn];
00878 CoinBigIndex startColumn = startColumnU[iColumn];
00879 CoinBigIndex endColumn = startColumn + numberInColumn[iColumn];
00880 int iRow = indexRowU[startColumn];
00881 CoinFactorizationDouble value = elementU[startColumn];
00882 double largest;
00883 CoinBigIndex put = startColumn;
00884 CoinBigIndex positionLargest = -1;
00885 CoinFactorizationDouble thisPivotValue = 0.0;
00886
00887
00888 bool checkLargest;
00889 int mark = markRow[iRow];
00890
00891 if ( mark == largeInteger+1 ) {
00892 largest = fabs ( value );
00893 positionLargest = put;
00894 put++;
00895 checkLargest = false;
00896 } else {
00897
00898 largest = 0.0;
00899 checkLargest = true;
00900 if ( mark != largeInteger ) {
00901
00902 work[mark] = value;
00903 int word = mark >> COINFACTORIZATION_SHIFT_PER_INT;
00904 int bit = mark & COINFACTORIZATION_MASK_PER_INT;
00905
00906 temp2[word] = temp2[word] | ( 1 << bit );
00907 added--;
00908 } else {
00909 thisPivotValue = value;
00910 }
00911 }
00912 CoinBigIndex i;
00913 for ( i = startColumn + 1; i < endColumn; i++ ) {
00914 iRow = indexRowU[i];
00915 value = elementU[i];
00916 int mark = markRow[iRow];
00917
00918 if ( mark == largeInteger+1 ) {
00919
00920 indexRowU[put] = iRow;
00921 elementU[put] = value;
00922 if ( checkLargest ) {
00923 double absValue = fabs ( value );
00924
00925 if ( absValue > largest ) {
00926 largest = absValue;
00927 positionLargest = put;
00928 }
00929 }
00930 put++;
00931 } else if ( mark != largeInteger ) {
00932
00933 work[mark] = value;
00934 int word = mark >> COINFACTORIZATION_SHIFT_PER_INT;
00935 int bit = mark & COINFACTORIZATION_MASK_PER_INT;
00936
00937 temp2[word] = temp2[word] | ( 1 << bit );
00938 added--;
00939 } else {
00940 thisPivotValue = value;
00941 }
00942 }
00943
00944 elementU[put] = elementU[startColumn];
00945 indexRowU[put] = indexRowU[startColumn];
00946 if ( positionLargest == startColumn ) {
00947 positionLargest = put;
00948 }
00949 put++;
00950 elementU[startColumn] = thisPivotValue;
00951 indexRowU[startColumn] = pivotRow;
00952
00953 startColumn++;
00954 numberInColumn[iColumn] = put - startColumn;
00955 int * numberInColumnPlus = numberInColumnPlus_.array();
00956 numberInColumnPlus[iColumn]++;
00957 startColumnU[iColumn]++;
00958
00959 int next = nextColumn[iColumn];
00960 CoinBigIndex space;
00961
00962 space = startColumnU[next] - put - numberInColumnPlus[next];
00963
00964 if ( numberInPivotColumn > space ) {
00965
00966 if ( !getColumnSpace ( iColumn, numberInPivotColumn ) ) {
00967 return false;
00968 }
00969
00970 positionLargest = positionLargest + startColumnU[iColumn] - startColumn;
00971 startColumn = startColumnU[iColumn];
00972 put = startColumn + numberInColumn[iColumn];
00973 }
00974 double tolerance = zeroTolerance_;
00975
00976 int *nextCount = nextCount_.array();
00977 for ( j = 0; j < numberInPivotColumn; j++ ) {
00978 value = work[j] - thisPivotValue * multipliersL[j];
00979 double absValue = fabs ( value );
00980
00981 if ( absValue > tolerance ) {
00982 work[j] = 0.0;
00983 elementU[put] = value;
00984 indexRowU[put] = indexL[j];
00985 if ( absValue > largest ) {
00986 largest = absValue;
00987 positionLargest = put;
00988 }
00989 put++;
00990 } else {
00991 work[j] = 0.0;
00992 added--;
00993 int word = j >> COINFACTORIZATION_SHIFT_PER_INT;
00994 int bit = j & COINFACTORIZATION_MASK_PER_INT;
00995
00996 if ( temp2[word] & ( 1 << bit ) ) {
00997
00998 iRow = indexL[j];
00999 CoinBigIndex start = startRowU[iRow];
01000 CoinBigIndex end = start + numberInRow[iRow];
01001 CoinBigIndex where = start;
01002
01003 while ( indexColumnU[where] != iColumn ) {
01004 where++;
01005 }
01006 #if DEBUG_COIN
01007 if ( where >= end ) {
01008 abort ( );
01009 }
01010 #endif
01011 indexColumnU[where] = indexColumnU[end - 1];
01012 numberInRow[iRow]--;
01013 } else {
01014
01015 int word = j >> COINFACTORIZATION_SHIFT_PER_INT;
01016 int bit = j & COINFACTORIZATION_MASK_PER_INT;
01017
01018 temp2[word] = temp2[word] | ( 1 << bit );
01019 }
01020 }
01021 }
01022 numberInColumn[iColumn] = put - startColumn;
01023
01024 if ( positionLargest >= 0 ) {
01025 value = elementU[positionLargest];
01026 iRow = indexRowU[positionLargest];
01027 elementU[positionLargest] = elementU[startColumn];
01028 indexRowU[positionLargest] = indexRowU[startColumn];
01029 elementU[startColumn] = value;
01030 indexRowU[startColumn] = iRow;
01031 }
01032
01033 if ( nextCount[iColumn + numberRows_] != -2 ) {
01034
01035 deleteLink ( iColumn + numberRows_ );
01036 addLink ( iColumn + numberRows_, numberInColumn[iColumn] );
01037 }
01038 temp2 += increment2;
01039 }
01040
01041 unsigned int *putBase = workArea2;
01042 int bigLoops = numberInPivotColumn >> COINFACTORIZATION_SHIFT_PER_INT;
01043 int i = 0;
01044
01045
01046 while ( bigLoops ) {
01047 bigLoops--;
01048 int bit;
01049 for ( bit = 0; bit < COINFACTORIZATION_BITS_PER_INT; i++, bit++ ) {
01050 unsigned int *putThis = putBase;
01051 int iRow = indexL[i];
01052
01053
01054 int number = 0;
01055 int jColumn;
01056
01057 for ( jColumn = 0; jColumn < numberInPivotRow; jColumn++ ) {
01058 unsigned int test = *putThis;
01059
01060 putThis += increment2;
01061 test = 1 - ( ( test >> bit ) & 1 );
01062 number += test;
01063 }
01064 int next = nextRow[iRow];
01065 CoinBigIndex space;
01066
01067 space = startRowU[next] - startRowU[iRow];
01068 number += numberInRow[iRow];
01069 if ( space < number ) {
01070 if ( !getRowSpace ( iRow, number ) ) {
01071 return false;
01072 }
01073 }
01074
01075 putThis = putBase;
01076 next = nextRow[iRow];
01077 number = numberInRow[iRow];
01078 CoinBigIndex end = startRowU[iRow] + number;
01079 int saveIndex = indexColumnU[startRowU[next]];
01080
01081
01082 for ( jColumn = 0; jColumn < numberInPivotRow; jColumn++ ) {
01083 unsigned int test = *putThis;
01084
01085 putThis += increment2;
01086 test = 1 - ( ( test >> bit ) & 1 );
01087 indexColumnU[end] = saveColumn[jColumn];
01088 end += test;
01089 }
01090
01091 indexColumnU[startRowU[next]] = saveIndex;
01092 markRow[iRow] = static_cast<T>(largeInteger+1);
01093 number = end - startRowU[iRow];
01094 numberInRow[iRow] = number;
01095 deleteLink ( iRow );
01096 addLink ( iRow, number );
01097 }
01098 putBase++;
01099 }
01100 int bit;
01101
01102 for ( bit = 0; i < numberInPivotColumn; i++, bit++ ) {
01103 unsigned int *putThis = putBase;
01104 int iRow = indexL[i];
01105
01106
01107 int number = 0;
01108 int jColumn;
01109
01110 for ( jColumn = 0; jColumn < numberInPivotRow; jColumn++ ) {
01111 unsigned int test = *putThis;
01112
01113 putThis += increment2;
01114 test = 1 - ( ( test >> bit ) & 1 );
01115 number += test;
01116 }
01117 int next = nextRow[iRow];
01118 CoinBigIndex space;
01119
01120 space = startRowU[next] - startRowU[iRow];
01121 number += numberInRow[iRow];
01122 if ( space < number ) {
01123 if ( !getRowSpace ( iRow, number ) ) {
01124 return false;
01125 }
01126 }
01127
01128 putThis = putBase;
01129 next = nextRow[iRow];
01130 number = numberInRow[iRow];
01131 CoinBigIndex end = startRowU[iRow] + number;
01132 int saveIndex;
01133
01134 saveIndex = indexColumnU[startRowU[next]];
01135
01136
01137 for ( jColumn = 0; jColumn < numberInPivotRow; jColumn++ ) {
01138 unsigned int test = *putThis;
01139
01140 putThis += increment2;
01141 test = 1 - ( ( test >> bit ) & 1 );
01142
01143 indexColumnU[end] = saveColumn[jColumn];
01144 end += test;
01145 }
01146 indexColumnU[startRowU[next]] = saveIndex;
01147 markRow[iRow] = static_cast<T>(largeInteger+1);
01148 number = end - startRowU[iRow];
01149 numberInRow[iRow] = number;
01150 deleteLink ( iRow );
01151 addLink ( iRow, number );
01152 }
01153 markRow[pivotRow] = static_cast<T>(largeInteger+1);
01154
01155 deleteLink ( pivotRow );
01156 deleteLink ( pivotColumn + numberRows_ );
01157 totalElements_ += added;
01158 return true;
01159 }
01160
01161
01163
01164 protected:
01165
01168
01169 double pivotTolerance_;
01171 double zeroTolerance_;
01172 #ifndef COIN_FAST_CODE
01174 double slackValue_;
01175 #else
01176 #ifndef slackValue_
01177 #define slackValue_ -1.0
01178 #endif
01179 #endif
01181 double areaFactor_;
01183 double relaxCheck_;
01185 int numberRows_;
01187 int numberRowsExtra_;
01189 int maximumRowsExtra_;
01191 int numberColumns_;
01193 int numberColumnsExtra_;
01195 int maximumColumnsExtra_;
01197 int numberGoodU_;
01199 int numberGoodL_;
01201 int maximumPivots_;
01203 int numberPivots_;
01206 CoinBigIndex totalElements_;
01208 CoinBigIndex factorElements_;
01210 CoinIntArrayWithLength pivotColumn_;
01212 CoinIntArrayWithLength permute_;
01214 CoinIntArrayWithLength permuteBack_;
01216 CoinIntArrayWithLength pivotColumnBack_;
01218 int status_;
01219
01224
01225
01227 int numberTrials_;
01229 CoinBigIndexArrayWithLength startRowU_;
01230
01232 CoinIntArrayWithLength numberInRow_;
01233
01235 CoinIntArrayWithLength numberInColumn_;
01236
01238 CoinIntArrayWithLength numberInColumnPlus_;
01239
01242 CoinIntArrayWithLength firstCount_;
01243
01245 CoinIntArrayWithLength nextCount_;
01246
01248 CoinIntArrayWithLength lastCount_;
01249
01251 CoinIntArrayWithLength nextColumn_;
01252
01254 CoinIntArrayWithLength lastColumn_;
01255
01257 CoinIntArrayWithLength nextRow_;
01258
01260 CoinIntArrayWithLength lastRow_;
01261
01263 CoinIntArrayWithLength saveColumn_;
01264
01266 CoinIntArrayWithLength markRow_;
01267
01269 int messageLevel_;
01270
01272 int biggerDimension_;
01273
01275 CoinIntArrayWithLength indexColumnU_;
01276
01278 CoinIntArrayWithLength pivotRowL_;
01279
01281 CoinFactorizationDoubleArrayWithLength pivotRegion_;
01282
01284 int numberSlacks_;
01285
01287 int numberU_;
01288
01290 CoinBigIndex maximumU_;
01291
01293
01294
01296 CoinBigIndex lengthU_;
01297
01299 CoinBigIndex lengthAreaU_;
01300
01302 CoinFactorizationDoubleArrayWithLength elementU_;
01303
01305 CoinIntArrayWithLength indexRowU_;
01306
01308 CoinBigIndexArrayWithLength startColumnU_;
01309
01311 CoinBigIndexArrayWithLength convertRowToColumnU_;
01312
01314 CoinBigIndex numberL_;
01315
01317 CoinBigIndex baseL_;
01318
01320 CoinBigIndex lengthL_;
01321
01323 CoinBigIndex lengthAreaL_;
01324
01326 CoinFactorizationDoubleArrayWithLength elementL_;
01327
01329 CoinIntArrayWithLength indexRowL_;
01330
01332 CoinBigIndexArrayWithLength startColumnL_;
01333
01335 bool doForrestTomlin_;
01336
01338 int numberR_;
01339
01341 CoinBigIndex lengthR_;
01342
01344 CoinBigIndex lengthAreaR_;
01345
01347 CoinFactorizationDouble *elementR_;
01348
01350 int *indexRowR_;
01351
01353 CoinBigIndexArrayWithLength startColumnR_;
01354
01356 double * denseArea_;
01357
01359 int * densePermute_;
01360
01362 int numberDense_;
01363
01365 int denseThreshold_;
01366
01368 CoinFactorizationDoubleArrayWithLength workArea_;
01369
01371 CoinUnsignedIntArrayWithLength workArea2_;
01372
01374 CoinBigIndex numberCompressions_;
01375
01377 mutable double ftranCountInput_;
01378 mutable double ftranCountAfterL_;
01379 mutable double ftranCountAfterR_;
01380 mutable double ftranCountAfterU_;
01381 mutable double btranCountInput_;
01382 mutable double btranCountAfterU_;
01383 mutable double btranCountAfterR_;
01384 mutable double btranCountAfterL_;
01385
01387 mutable int numberFtranCounts_;
01388 mutable int numberBtranCounts_;
01389
01391 double ftranAverageAfterL_;
01392 double ftranAverageAfterR_;
01393 double ftranAverageAfterU_;
01394 double btranAverageAfterU_;
01395 double btranAverageAfterR_;
01396 double btranAverageAfterL_;
01397
01399 mutable bool collectStatistics_;
01400
01402 int sparseThreshold_;
01403
01405 int sparseThreshold2_;
01406
01408 CoinBigIndexArrayWithLength startRowL_;
01409
01411 CoinIntArrayWithLength indexColumnL_;
01412
01414 CoinFactorizationDoubleArrayWithLength elementByRowL_;
01415
01417 mutable CoinIntArrayWithLength sparse_;
01421 int biasLU_;
01427 int persistenceFlag_;
01429 };
01430
01431 #ifdef COIN_HAS_LAPACK
01432 #define DENSE_CODE 1
01433
01434 #ifndef ipfint
01435
01436 typedef int ipfint;
01437 typedef const int cipfint;
01438 #endif
01439 #endif
01440 #endif
01441
01442 #ifdef UGLY_COIN_FACTOR_CODING
01443 #define FAC_UNSET (FAC_SET+1)
01444 {
01445 goodPivot=false;
01446
01447 CoinBigIndex startColumnThis = startColumn[iPivotColumn];
01448 CoinBigIndex endColumn = startColumnThis + numberDoColumn + 1;
01449 int put = 0;
01450 CoinBigIndex startRowThis = startRow[iPivotRow];
01451 CoinBigIndex endRow = startRowThis + numberDoRow + 1;
01452 if ( pivotColumnPosition < 0 ) {
01453 for ( pivotColumnPosition = startRowThis; pivotColumnPosition < endRow; pivotColumnPosition++ ) {
01454 int iColumn = indexColumn[pivotColumnPosition];
01455 if ( iColumn != iPivotColumn ) {
01456 saveColumn[put++] = iColumn;
01457 } else {
01458 break;
01459 }
01460 }
01461 } else {
01462 for (CoinBigIndex i = startRowThis ; i < pivotColumnPosition ; i++ ) {
01463 saveColumn[put++] = indexColumn[i];
01464 }
01465 }
01466 assert (pivotColumnPosition<endRow);
01467 assert (indexColumn[pivotColumnPosition]==iPivotColumn);
01468 pivotColumnPosition++;
01469 for ( ; pivotColumnPosition < endRow; pivotColumnPosition++ ) {
01470 saveColumn[put++] = indexColumn[pivotColumnPosition];
01471 }
01472
01473 int next = nextRow[iPivotRow];
01474 int last = lastRow[iPivotRow];
01475
01476 nextRow[last] = next;
01477 lastRow[next] = last;
01478 nextRow[iPivotRow] = numberGoodU_;
01479 lastRow[iPivotRow] = -2;
01480 numberInRow[iPivotRow] = 0;
01481
01482 CoinBigIndex l = lengthL_;
01483
01484 {
01485 if ( l + numberDoColumn > lengthAreaL_ ) {
01486
01487 if ((messageLevel_&4)!=0)
01488 printf("more memory needed in middle of invert\n");
01489 goto BAD_PIVOT;
01490 }
01491
01492 CoinBigIndex lSave = l;
01493
01494 CoinBigIndex * startColumnL = startColumnL_.array();
01495 startColumnL[numberGoodL_] = l;
01496 numberGoodL_++;
01497 startColumnL[numberGoodL_] = l + numberDoColumn;
01498 lengthL_ += numberDoColumn;
01499 if ( pivotRowPosition < 0 ) {
01500 for ( pivotRowPosition = startColumnThis; pivotRowPosition < endColumn; pivotRowPosition++ ) {
01501 int iRow = indexRow[pivotRowPosition];
01502 if ( iRow != iPivotRow ) {
01503 indexRowL[l] = iRow;
01504 elementL[l] = element[pivotRowPosition];
01505 markRow[iRow] = l - lSave;
01506 l++;
01507
01508 CoinBigIndex start = startRow[iRow];
01509 CoinBigIndex end = start + numberInRow[iRow];
01510 CoinBigIndex where = start;
01511
01512 while ( indexColumn[where] != iPivotColumn ) {
01513 where++;
01514 }
01515 #if DEBUG_COIN
01516 if ( where >= end ) {
01517 abort ( );
01518 }
01519 #endif
01520 indexColumn[where] = indexColumn[end - 1];
01521 numberInRow[iRow]--;
01522 } else {
01523 break;
01524 }
01525 }
01526 } else {
01527 CoinBigIndex i;
01528
01529 for ( i = startColumnThis; i < pivotRowPosition; i++ ) {
01530 int iRow = indexRow[i];
01531
01532 markRow[iRow] = l - lSave;
01533 indexRowL[l] = iRow;
01534 elementL[l] = element[i];
01535 l++;
01536
01537 CoinBigIndex start = startRow[iRow];
01538 CoinBigIndex end = start + numberInRow[iRow];
01539 CoinBigIndex where = start;
01540
01541 while ( indexColumn[where] != iPivotColumn ) {
01542 where++;
01543 }
01544 #if DEBUG_COIN
01545 if ( where >= end ) {
01546 abort ( );
01547 }
01548 #endif
01549 indexColumn[where] = indexColumn[end - 1];
01550 numberInRow[iRow]--;
01551 assert (numberInRow[iRow]>=0);
01552 }
01553 }
01554 assert (pivotRowPosition<endColumn);
01555 assert (indexRow[pivotRowPosition]==iPivotRow);
01556 CoinFactorizationDouble pivotElement = element[pivotRowPosition];
01557 CoinFactorizationDouble pivotMultiplier = 1.0 / pivotElement;
01558
01559 pivotRegion_.array()[numberGoodU_] = pivotMultiplier;
01560 pivotRowPosition++;
01561 for ( ; pivotRowPosition < endColumn; pivotRowPosition++ ) {
01562 int iRow = indexRow[pivotRowPosition];
01563
01564 markRow[iRow] = l - lSave;
01565 indexRowL[l] = iRow;
01566 elementL[l] = element[pivotRowPosition];
01567 l++;
01568
01569 CoinBigIndex start = startRow[iRow];
01570 CoinBigIndex end = start + numberInRow[iRow];
01571 CoinBigIndex where = start;
01572
01573 while ( indexColumn[where] != iPivotColumn ) {
01574 where++;
01575 }
01576 #if DEBUG_COIN
01577 if ( where >= end ) {
01578 abort ( );
01579 }
01580 #endif
01581 indexColumn[where] = indexColumn[end - 1];
01582 numberInRow[iRow]--;
01583 assert (numberInRow[iRow]>=0);
01584 }
01585 markRow[iPivotRow] = FAC_SET;
01586
01587 numberInColumn[iPivotColumn] = 0;
01588
01589 int *indexL = &indexRowL[lSave];
01590 CoinFactorizationDouble *multipliersL = &elementL[lSave];
01591
01592
01593 int j;
01594
01595 for ( j = 0; j < numberDoColumn; j++ ) {
01596 multipliersL[j] *= pivotMultiplier;
01597 }
01598
01599 CoinBigIndex iErase;
01600 for ( iErase = 0; iErase < increment2 * numberDoRow;
01601 iErase++ ) {
01602 workArea2[iErase] = 0;
01603 }
01604 CoinBigIndex added = numberDoRow * numberDoColumn;
01605 unsigned int *temp2 = workArea2;
01606 int * nextColumn = nextColumn_.array();
01607
01608
01609 int jColumn;
01610 for ( jColumn = 0; jColumn < numberDoRow; jColumn++ ) {
01611 int iColumn = saveColumn[jColumn];
01612 CoinBigIndex startColumnThis = startColumn[iColumn];
01613 CoinBigIndex endColumn = startColumnThis + numberInColumn[iColumn];
01614 int iRow = indexRow[startColumnThis];
01615 CoinFactorizationDouble value = element[startColumnThis];
01616 double largest;
01617 CoinBigIndex put = startColumnThis;
01618 CoinBigIndex positionLargest = -1;
01619 CoinFactorizationDouble thisPivotValue = 0.0;
01620
01621
01622 bool checkLargest;
01623 int mark = markRow[iRow];
01624
01625 if ( mark == FAC_UNSET ) {
01626 largest = fabs ( value );
01627 positionLargest = put;
01628 put++;
01629 checkLargest = false;
01630 } else {
01631
01632 largest = 0.0;
01633 checkLargest = true;
01634 if ( mark != FAC_SET ) {
01635
01636 workArea[mark] = value;
01637 int word = mark >> COINFACTORIZATION_SHIFT_PER_INT;
01638 int bit = mark & COINFACTORIZATION_MASK_PER_INT;
01639
01640 temp2[word] = temp2[word] | ( 1 << bit );
01641 added--;
01642 } else {
01643 thisPivotValue = value;
01644 }
01645 }
01646 CoinBigIndex i;
01647 for ( i = startColumnThis + 1; i < endColumn; i++ ) {
01648 iRow = indexRow[i];
01649 value = element[i];
01650 int mark = markRow[iRow];
01651
01652 if ( mark == FAC_UNSET ) {
01653
01654 indexRow[put] = iRow;
01655 element[put] = value;
01656 if ( checkLargest ) {
01657 double absValue = fabs ( value );
01658
01659 if ( absValue > largest ) {
01660 largest = absValue;
01661 positionLargest = put;
01662 }
01663 }
01664 put++;
01665 } else if ( mark != FAC_SET ) {
01666
01667 workArea[mark] = value;
01668 int word = mark >> COINFACTORIZATION_SHIFT_PER_INT;
01669 int bit = mark & COINFACTORIZATION_MASK_PER_INT;
01670
01671 temp2[word] = temp2[word] | ( 1 << bit );
01672 added--;
01673 } else {
01674 thisPivotValue = value;
01675 }
01676 }
01677
01678 element[put] = element[startColumnThis];
01679 indexRow[put] = indexRow[startColumnThis];
01680 if ( positionLargest == startColumnThis ) {
01681 positionLargest = put;
01682 }
01683 put++;
01684 element[startColumnThis] = thisPivotValue;
01685 indexRow[startColumnThis] = iPivotRow;
01686
01687 startColumnThis++;
01688 numberInColumn[iColumn] = put - startColumnThis;
01689 int * numberInColumnPlus = numberInColumnPlus_.array();
01690 numberInColumnPlus[iColumn]++;
01691 startColumn[iColumn]++;
01692
01693 int next = nextColumn[iColumn];
01694 CoinBigIndex space;
01695
01696 space = startColumn[next] - put - numberInColumnPlus[next];
01697
01698 if ( numberDoColumn > space ) {
01699
01700 if ( !getColumnSpace ( iColumn, numberDoColumn ) ) {
01701 goto BAD_PIVOT;
01702 }
01703
01704 positionLargest = positionLargest + startColumn[iColumn] - startColumnThis;
01705 startColumnThis = startColumn[iColumn];
01706 put = startColumnThis + numberInColumn[iColumn];
01707 }
01708 double tolerance = zeroTolerance_;
01709
01710 int *nextCount = nextCount_.array();
01711 for ( j = 0; j < numberDoColumn; j++ ) {
01712 value = workArea[j] - thisPivotValue * multipliersL[j];
01713 double absValue = fabs ( value );
01714
01715 if ( absValue > tolerance ) {
01716 workArea[j] = 0.0;
01717 element[put] = value;
01718 indexRow[put] = indexL[j];
01719 if ( absValue > largest ) {
01720 largest = absValue;
01721 positionLargest = put;
01722 }
01723 put++;
01724 } else {
01725 workArea[j] = 0.0;
01726 added--;
01727 int word = j >> COINFACTORIZATION_SHIFT_PER_INT;
01728 int bit = j & COINFACTORIZATION_MASK_PER_INT;
01729
01730 if ( temp2[word] & ( 1 << bit ) ) {
01731
01732 iRow = indexL[j];
01733 CoinBigIndex start = startRow[iRow];
01734 CoinBigIndex end = start + numberInRow[iRow];
01735 CoinBigIndex where = start;
01736
01737 while ( indexColumn[where] != iColumn ) {
01738 where++;
01739 }
01740 #if DEBUG_COIN
01741 if ( where >= end ) {
01742 abort ( );
01743 }
01744 #endif
01745 indexColumn[where] = indexColumn[end - 1];
01746 numberInRow[iRow]--;
01747 } else {
01748
01749 int word = j >> COINFACTORIZATION_SHIFT_PER_INT;
01750 int bit = j & COINFACTORIZATION_MASK_PER_INT;
01751
01752 temp2[word] = temp2[word] | ( 1 << bit );
01753 }
01754 }
01755 }
01756 numberInColumn[iColumn] = put - startColumnThis;
01757
01758 if ( positionLargest >= 0 ) {
01759 value = element[positionLargest];
01760 iRow = indexRow[positionLargest];
01761 element[positionLargest] = element[startColumnThis];
01762 indexRow[positionLargest] = indexRow[startColumnThis];
01763 element[startColumnThis] = value;
01764 indexRow[startColumnThis] = iRow;
01765 }
01766
01767 if ( nextCount[iColumn + numberRows_] != -2 ) {
01768
01769 deleteLink ( iColumn + numberRows_ );
01770 addLink ( iColumn + numberRows_, numberInColumn[iColumn] );
01771 }
01772 temp2 += increment2;
01773 }
01774
01775 unsigned int *putBase = workArea2;
01776 int bigLoops = numberDoColumn >> COINFACTORIZATION_SHIFT_PER_INT;
01777 int i = 0;
01778
01779
01780 while ( bigLoops ) {
01781 bigLoops--;
01782 int bit;
01783 for ( bit = 0; bit < COINFACTORIZATION_BITS_PER_INT; i++, bit++ ) {
01784 unsigned int *putThis = putBase;
01785 int iRow = indexL[i];
01786
01787
01788 int number = 0;
01789 int jColumn;
01790
01791 for ( jColumn = 0; jColumn < numberDoRow; jColumn++ ) {
01792 unsigned int test = *putThis;
01793
01794 putThis += increment2;
01795 test = 1 - ( ( test >> bit ) & 1 );
01796 number += test;
01797 }
01798 int next = nextRow[iRow];
01799 CoinBigIndex space;
01800
01801 space = startRow[next] - startRow[iRow];
01802 number += numberInRow[iRow];
01803 if ( space < number ) {
01804 if ( !getRowSpace ( iRow, number ) ) {
01805 goto BAD_PIVOT;
01806 }
01807 }
01808
01809 putThis = putBase;
01810 next = nextRow[iRow];
01811 number = numberInRow[iRow];
01812 CoinBigIndex end = startRow[iRow] + number;
01813 int saveIndex = indexColumn[startRow[next]];
01814
01815
01816 for ( jColumn = 0; jColumn < numberDoRow; jColumn++ ) {
01817 unsigned int test = *putThis;
01818
01819 putThis += increment2;
01820 test = 1 - ( ( test >> bit ) & 1 );
01821 indexColumn[end] = saveColumn[jColumn];
01822 end += test;
01823 }
01824
01825 indexColumn[startRow[next]] = saveIndex;
01826 markRow[iRow] = FAC_UNSET;
01827 number = end - startRow[iRow];
01828 numberInRow[iRow] = number;
01829 deleteLink ( iRow );
01830 addLink ( iRow, number );
01831 }
01832 putBase++;
01833 }
01834 int bit;
01835
01836 for ( bit = 0; i < numberDoColumn; i++, bit++ ) {
01837 unsigned int *putThis = putBase;
01838 int iRow = indexL[i];
01839
01840
01841 int number = 0;
01842 int jColumn;
01843
01844 for ( jColumn = 0; jColumn < numberDoRow; jColumn++ ) {
01845 unsigned int test = *putThis;
01846
01847 putThis += increment2;
01848 test = 1 - ( ( test >> bit ) & 1 );
01849 number += test;
01850 }
01851 int next = nextRow[iRow];
01852 CoinBigIndex space;
01853
01854 space = startRow[next] - startRow[iRow];
01855 number += numberInRow[iRow];
01856 if ( space < number ) {
01857 if ( !getRowSpace ( iRow, number ) ) {
01858 goto BAD_PIVOT;
01859 }
01860 }
01861
01862 putThis = putBase;
01863 next = nextRow[iRow];
01864 number = numberInRow[iRow];
01865 CoinBigIndex end = startRow[iRow] + number;
01866 int saveIndex;
01867
01868 saveIndex = indexColumn[startRow[next]];
01869
01870
01871 for ( jColumn = 0; jColumn < numberDoRow; jColumn++ ) {
01872 unsigned int test = *putThis;
01873
01874 putThis += increment2;
01875 test = 1 - ( ( test >> bit ) & 1 );
01876
01877 indexColumn[end] = saveColumn[jColumn];
01878 end += test;
01879 }
01880 indexColumn[startRow[next]] = saveIndex;
01881 markRow[iRow] = FAC_UNSET;
01882 number = end - startRow[iRow];
01883 numberInRow[iRow] = number;
01884 deleteLink ( iRow );
01885 addLink ( iRow, number );
01886 }
01887 markRow[iPivotRow] = FAC_UNSET;
01888
01889 deleteLink ( iPivotRow );
01890 deleteLink ( iPivotColumn + numberRows_ );
01891 totalElements_ += added;
01892 goodPivot= true;
01893
01894 }
01895 BAD_PIVOT:
01896
01897 ;
01898 }
01899 #undef FAC_UNSET
01900 #endif