/home/coin/SVN-release/Clp-1.9.0/CoinUtils/src/CoinFactorization.hpp

Go to the documentation of this file.
00001 // Copyright (C) 2002, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
00003 
00004 /* 
00005    Authors
00006    
00007    John Forrest
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     //return firstCount_.array();
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       //first with that count
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   /********************************* START LARGE TEMPLATE ********/
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   //store pivot columns (so can easily compress)
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   //take out this bit of indexColumnU
00740   int next = nextRow[pivotRow];
00741   int last = lastRow[pivotRow];
00742 
00743   nextRow[last] = next;
00744   lastRow[next] = last;
00745   nextRow[pivotRow] = numberGoodU_;     //use for permute
00746   lastRow[pivotRow] = -2;
00747   numberInRow[pivotRow] = 0;
00748   //store column in L, compress in U and take column out
00749   CoinBigIndex l = lengthL_;
00750 
00751   if ( l + numberInPivotColumn > lengthAreaL_ ) {
00752     //need more memory
00753     if ((messageLevel_&4)!=0) 
00754       printf("more memory needed in middle of invert\n");
00755     return false;
00756   }
00757   //l+=currentAreaL_->elementByColumn-elementL;
00758   CoinBigIndex lSave = l;
00759 
00760   CoinBigIndex * startColumnL = startColumnL_.array();
00761   startColumnL[numberGoodL_] = l;       //for luck and first time
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         //take out of row list
00774         CoinBigIndex start = startRowU[iRow];
00775         CoinBigIndex end = start + numberInRow[iRow];
00776         CoinBigIndex where = start;
00777 
00778         while ( indexColumnU[where] != pivotColumn ) {
00779           where++;
00780         }                       /* endwhile */
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       //take out of row list
00803       CoinBigIndex start = startRowU[iRow];
00804       CoinBigIndex end = start + numberInRow[iRow];
00805       CoinBigIndex where = start;
00806 
00807       while ( indexColumnU[where] != pivotColumn ) {
00808         where++;
00809       }                         /* endwhile */
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     //take out of row list
00835     CoinBigIndex start = startRowU[iRow];
00836     CoinBigIndex end = start + numberInRow[iRow];
00837     CoinBigIndex where = start;
00838     
00839     while ( indexColumnU[where] != pivotColumn ) {
00840       where++;
00841     }                           /* endwhile */
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   //compress pivot column (move pivot to front including saved)
00853   numberInColumn[pivotColumn] = 0;
00854   //use end of L for temporary space
00855   int *indexL = &indexRowL[lSave];
00856   CoinFactorizationDouble *multipliersL = &elementL[lSave];
00857 
00858   //adjust
00859   int j;
00860 
00861   for ( j = 0; j < numberInPivotColumn; j++ ) {
00862     multipliersL[j] *= pivotMultiplier;
00863   }
00864   //zero out fill
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   //pack down and move to work
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     //compress column and find largest not updated
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       //need to find largest
00898       largest = 0.0;
00899       checkLargest = true;
00900       if ( mark != largeInteger ) {
00901         //will be updated
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 );       //say already in counts
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         //keep
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         //will be updated
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 );       //say already in counts
00938         added--;
00939       } else {
00940         thisPivotValue = value;
00941       }
00942     }
00943     //slot in pivot
00944     elementU[put] = elementU[startColumn];
00945     indexRowU[put] = indexRowU[startColumn];
00946     if ( positionLargest == startColumn ) {
00947       positionLargest = put;    //follow if was largest
00948     }
00949     put++;
00950     elementU[startColumn] = thisPivotValue;
00951     indexRowU[startColumn] = pivotRow;
00952     //clean up counts
00953     startColumn++;
00954     numberInColumn[iColumn] = put - startColumn;
00955     int * numberInColumnPlus = numberInColumnPlus_.array();
00956     numberInColumnPlus[iColumn]++;
00957     startColumnU[iColumn]++;
00958     //how much space have we got
00959     int next = nextColumn[iColumn];
00960     CoinBigIndex space;
00961 
00962     space = startColumnU[next] - put - numberInColumnPlus[next];
00963     //assume no zero elements
00964     if ( numberInPivotColumn > space ) {
00965       //getColumnSpace also moves fixed part
00966       if ( !getColumnSpace ( iColumn, numberInPivotColumn ) ) {
00967         return false;
00968       }
00969       //redo starts
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           //take out of row list
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           }                     /* endwhile */
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           //make sure won't be added
01015           int word = j >> COINFACTORIZATION_SHIFT_PER_INT;
01016           int bit = j & COINFACTORIZATION_MASK_PER_INT;
01017 
01018           temp2[word] = temp2[word] | ( 1 << bit );     //say already in counts
01019         }
01020       }
01021     }
01022     numberInColumn[iColumn] = put - startColumn;
01023     //move largest
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     //linked list for column
01033     if ( nextCount[iColumn + numberRows_] != -2 ) {
01034       //modify linked list
01035       deleteLink ( iColumn + numberRows_ );
01036       addLink ( iColumn + numberRows_, numberInColumn[iColumn] );
01037     }
01038     temp2 += increment2;
01039   }
01040   //get space for row list
01041   unsigned int *putBase = workArea2;
01042   int bigLoops = numberInPivotColumn >> COINFACTORIZATION_SHIFT_PER_INT;
01043   int i = 0;
01044 
01045   // do linked lists and update counts
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       //get space
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       // now do
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       //add in
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       //put back next one in case zapped
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   }                             /* endwhile */
01100   int bit;
01101 
01102   for ( bit = 0; i < numberInPivotColumn; i++, bit++ ) {
01103     unsigned int *putThis = putBase;
01104     int iRow = indexL[i];
01105 
01106     //get space
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     // now do
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     //add in
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   //modify linked list for pivots
01155   deleteLink ( pivotRow );
01156   deleteLink ( pivotColumn + numberRows_ );
01157   totalElements_ += added;
01158   return true;
01159 }
01160 
01161   /********************************* END LARGE TEMPLATE ********/
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   //int increasingRows_;
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   //int baseU_;
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 // Dense coding
01431 #ifdef COIN_HAS_LAPACK
01432 #define DENSE_CODE 1
01433 /* Type of Fortran integer translated into C */
01434 #ifndef ipfint
01435 //typedef ipfint FORTRAN_INTEGER_TYPE ;
01436 typedef int ipfint;
01437 typedef const int cipfint;
01438 #endif
01439 #endif
01440 #endif
01441 // Extra for ugly include
01442 #ifdef UGLY_COIN_FACTOR_CODING
01443 #define FAC_UNSET (FAC_SET+1)
01444 {
01445   goodPivot=false;
01446   //store pivot columns (so can easily compress)
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   //take out this bit of indexColumn
01473   int next = nextRow[iPivotRow];
01474   int last = lastRow[iPivotRow];
01475   
01476   nextRow[last] = next;
01477   lastRow[next] = last;
01478   nextRow[iPivotRow] = numberGoodU_;    //use for permute
01479   lastRow[iPivotRow] = -2;
01480   numberInRow[iPivotRow] = 0;
01481   //store column in L, compress in U and take column out
01482   CoinBigIndex l = lengthL_;
01483   // **** HORRID coding coming up but a goto seems best!
01484   {
01485     if ( l + numberDoColumn > lengthAreaL_ ) {
01486       //need more memory
01487       if ((messageLevel_&4)!=0) 
01488         printf("more memory needed in middle of invert\n");
01489       goto BAD_PIVOT;
01490     }
01491     //l+=currentAreaL_->elementByColumn-elementL;
01492     CoinBigIndex lSave = l;
01493     
01494     CoinBigIndex * startColumnL = startColumnL_.array();
01495     startColumnL[numberGoodL_] = l;     //for luck and first time
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           //take out of row list
01508           CoinBigIndex start = startRow[iRow];
01509           CoinBigIndex end = start + numberInRow[iRow];
01510           CoinBigIndex where = start;
01511           
01512           while ( indexColumn[where] != iPivotColumn ) {
01513             where++;
01514           }                     /* endwhile */
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         //take out of row list
01537         CoinBigIndex start = startRow[iRow];
01538         CoinBigIndex end = start + numberInRow[iRow];
01539         CoinBigIndex where = start;
01540         
01541         while ( indexColumn[where] != iPivotColumn ) {
01542           where++;
01543         }                               /* endwhile */
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       //take out of row list
01569       CoinBigIndex start = startRow[iRow];
01570       CoinBigIndex end = start + numberInRow[iRow];
01571       CoinBigIndex where = start;
01572       
01573       while ( indexColumn[where] != iPivotColumn ) {
01574         where++;
01575       }                         /* endwhile */
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     //compress pivot column (move pivot to front including saved)
01587     numberInColumn[iPivotColumn] = 0;
01588     //use end of L for temporary space
01589     int *indexL = &indexRowL[lSave];
01590     CoinFactorizationDouble *multipliersL = &elementL[lSave];
01591     
01592     //adjust
01593     int j;
01594     
01595     for ( j = 0; j < numberDoColumn; j++ ) {
01596       multipliersL[j] *= pivotMultiplier;
01597     }
01598     //zero out fill
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     //pack down and move to work
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       //compress column and find largest not updated
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         //need to find largest
01632         largest = 0.0;
01633         checkLargest = true;
01634         if ( mark != FAC_SET ) {
01635           //will be updated
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 );     //say already in counts
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           //keep
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           //will be updated
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 );     //say already in counts
01672           added--;
01673         } else {
01674           thisPivotValue = value;
01675         }
01676       }
01677       //slot in pivot
01678       element[put] = element[startColumnThis];
01679       indexRow[put] = indexRow[startColumnThis];
01680       if ( positionLargest == startColumnThis ) {
01681         positionLargest = put;  //follow if was largest
01682       }
01683       put++;
01684       element[startColumnThis] = thisPivotValue;
01685       indexRow[startColumnThis] = iPivotRow;
01686       //clean up counts
01687       startColumnThis++;
01688       numberInColumn[iColumn] = put - startColumnThis;
01689       int * numberInColumnPlus = numberInColumnPlus_.array();
01690       numberInColumnPlus[iColumn]++;
01691       startColumn[iColumn]++;
01692       //how much space have we got
01693       int next = nextColumn[iColumn];
01694       CoinBigIndex space;
01695       
01696       space = startColumn[next] - put - numberInColumnPlus[next];
01697       //assume no zero elements
01698       if ( numberDoColumn > space ) {
01699         //getColumnSpace also moves fixed part
01700         if ( !getColumnSpace ( iColumn, numberDoColumn ) ) {
01701           goto BAD_PIVOT;
01702         }
01703         //redo starts
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             //take out of row list
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             }                   /* endwhile */
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             //make sure won't be added
01749             int word = j >> COINFACTORIZATION_SHIFT_PER_INT;
01750             int bit = j & COINFACTORIZATION_MASK_PER_INT;
01751             
01752             temp2[word] = temp2[word] | ( 1 << bit );   //say already in counts
01753           }
01754         }
01755       }
01756       numberInColumn[iColumn] = put - startColumnThis;
01757       //move largest
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       //linked list for column
01767       if ( nextCount[iColumn + numberRows_] != -2 ) {
01768         //modify linked list
01769         deleteLink ( iColumn + numberRows_ );
01770         addLink ( iColumn + numberRows_, numberInColumn[iColumn] );
01771       }
01772       temp2 += increment2;
01773     }
01774     //get space for row list
01775     unsigned int *putBase = workArea2;
01776     int bigLoops = numberDoColumn >> COINFACTORIZATION_SHIFT_PER_INT;
01777     int i = 0;
01778     
01779     // do linked lists and update counts
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         //get space
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         // now do
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         //add in
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         //put back next one in case zapped
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     }                           /* endwhile */
01834     int bit;
01835     
01836     for ( bit = 0; i < numberDoColumn; i++, bit++ ) {
01837       unsigned int *putThis = putBase;
01838       int iRow = indexL[i];
01839       
01840       //get space
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       // now do
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       //add in
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     //modify linked list for pivots
01889     deleteLink ( iPivotRow );
01890     deleteLink ( iPivotColumn + numberRows_ );
01891     totalElements_ += added;
01892     goodPivot= true;
01893     // **** UGLY UGLY UGLY
01894   }
01895  BAD_PIVOT:
01896 
01897   ;
01898 }
01899 #undef FAC_UNSET
01900 #endif

Generated on Sat Feb 7 03:01:51 2009 by  doxygen 1.4.7