/home/coin/SVN-release/CoinAll-1.1.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 "CoinFinite.hpp"
00017 #include "CoinIndexedVector.hpp"
00018 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                        double * 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 double *pivotRegion (  ) const {
00155     return pivotRegion_.array();
00156   }
00158   inline int *permuteBack (  ) const {
00159     return permuteBack_.array();
00160   }
00162   inline int *pivotColumnBack (  ) const {
00163     return pivotColumnBack_.array();
00164   }
00166   inline CoinBigIndex * startRowL() const
00167   { return startRowL_.array();}
00168 
00170   inline CoinBigIndex * startColumnL() const
00171   { return startColumnL_.array();}
00172 
00174   inline int * indexColumnL() const
00175   { return indexColumnL_.array();}
00176 
00178   inline int * indexRowL() const
00179   { return indexRowL_.array();}
00180 
00182   inline double * elementByRowL() const
00183   { return elementByRowL_.array();}
00184 
00186   inline int numberRowsExtra (  ) const {
00187     return numberRowsExtra_;
00188   }
00190   inline void setNumberRows(int value)
00191   { numberRows_ = value; }
00193   inline int numberRows (  ) const {
00194     return numberRows_;
00195   }
00197   inline CoinBigIndex numberL() const
00198   { return numberL_;}
00199 
00201   inline CoinBigIndex baseL() const
00202   { return baseL_;}
00204   inline int maximumRowsExtra (  ) const {
00205     return maximumRowsExtra_;
00206   }
00208   inline int numberColumns (  ) const {
00209     return numberColumns_;
00210   }
00212   inline int numberElements (  ) const {
00213     return totalElements_;
00214   }
00216   inline int numberForrestTomlin (  ) const {
00217     return numberInColumn_.array()[numberColumnsExtra_];
00218   }
00220   inline int numberGoodColumns (  ) const {
00221     return numberGoodU_;
00222   }
00224   inline double areaFactor (  ) const {
00225     return areaFactor_;
00226   }
00227   inline void areaFactor ( double value ) {
00228     areaFactor_=value;
00229   }
00231   double adjustedAreaFactor() const;
00233   inline void relaxAccuracyCheck(double value)
00234   { relaxCheck_ = value;}
00235   inline double getAccuracyCheck() const
00236   { return relaxCheck_;}
00238   inline bool increasingRows (  ) const 
00239   { return true; }
00245   inline void increasingRows ( int value  ) {}
00247   inline int messageLevel (  ) const {
00248     return messageLevel_ ;
00249   }
00250   void messageLevel (  int value );
00252   inline int maximumPivots (  ) const {
00253     return maximumPivots_ ;
00254   }
00255   void maximumPivots (  int value );
00256 
00258   inline int denseThreshold() const 
00259     { return denseThreshold_;}
00261   inline void setDenseThreshold(int value)
00262     { denseThreshold_ = value;}
00264   inline double pivotTolerance (  ) const {
00265     return pivotTolerance_ ;
00266   }
00267   void pivotTolerance (  double value );
00269   inline double zeroTolerance (  ) const {
00270     return zeroTolerance_ ;
00271   }
00272   void zeroTolerance (  double value );
00274   inline double slackValue (  ) const {
00275     return slackValue_ ;
00276   }
00277   void slackValue (  double value );
00279   double maximumCoefficient() const;
00281   inline bool forrestTomlin() const
00282   { return doForrestTomlin_;}
00283   inline void setForrestTomlin(bool value)
00284   { doForrestTomlin_=value;}
00286 
00289 
00291   inline int numberDense() const
00292   { return numberDense_;}
00293 
00295   inline CoinBigIndex numberElementsU (  ) const {
00296     return lengthU_;
00297   }
00299   inline void setNumberElementsU(CoinBigIndex value)
00300   { lengthU_ = value; }
00302   inline CoinBigIndex lengthAreaU (  ) const {
00303     return lengthAreaU_;
00304   }
00306   inline CoinBigIndex numberElementsL (  ) const {
00307     return lengthL_;
00308   }
00310   inline CoinBigIndex lengthAreaL (  ) const {
00311     return lengthAreaL_;
00312   }
00314   inline CoinBigIndex numberElementsR (  ) const {
00315     return lengthR_;
00316   }
00318   inline CoinBigIndex numberCompressions() const
00319   { return numberCompressions_;}
00321   inline int * numberInRow() const
00322   { return numberInRow_.array();}
00324   inline int * numberInColumn() const
00325   { return numberInColumn_.array();}
00327   inline double * elementU() const
00328   { return elementU_.array();}
00330   inline int * indexRowU() const
00331   { return indexRowU_.array();}
00333   inline CoinBigIndex * startColumnU() const
00334   { return startColumnU_.array();}
00336   inline int maximumColumnsExtra()
00337   { return maximumColumnsExtra_;}
00341   inline int biasLU() const
00342   { return biasLU_;}
00343   inline void setBiasLU(int value)
00344   { biasLU_=value;}
00350   inline int persistenceFlag() const
00351   { return persistenceFlag_;}
00352   void setPersistenceFlag(int value);
00354 
00357 
00365   int replaceColumn ( CoinIndexedVector * regionSparse,
00366                       int pivotRow,
00367                       double pivotCheck ,
00368                       bool checkBeforeModifying=false);
00370 
00380   int updateColumnFT ( CoinIndexedVector * regionSparse,
00381                        CoinIndexedVector * regionSparse2);
00384   int updateColumn ( CoinIndexedVector * regionSparse,
00385                      CoinIndexedVector * regionSparse2,
00386                      bool noPermute=false) const;
00391   int updateColumnTranspose ( CoinIndexedVector * regionSparse,
00392                               CoinIndexedVector * regionSparse2) const;
00394   void goSparse();
00396   inline int sparseThreshold ( ) const
00397   { return sparseThreshold_;}
00399   void sparseThreshold ( int value );
00401 
00402 
00406 
00407   inline void clearArrays()
00408   { gutsOfDestructor();}
00410 
00413 
00416   int add ( CoinBigIndex numberElements,
00417                int indicesRow[],
00418                int indicesColumn[], double elements[] );
00419 
00422   int addColumn ( CoinBigIndex numberElements,
00423                      int indicesRow[], double elements[] );
00424 
00427   int addRow ( CoinBigIndex numberElements,
00428                   int indicesColumn[], double elements[] );
00429 
00431   int deleteColumn ( int Row );
00433   int deleteRow ( int Row );
00434 
00438   int replaceRow ( int whichRow, int numberElements,
00439                       const int indicesColumn[], const double elements[] );
00441   void emptyRows(int numberToEmpty, const int which[]);
00443 
00444 
00445   void checkSparse();
00447   inline bool collectStatistics() const
00448   { return collectStatistics_;}
00450   inline void setCollectStatistics(bool onOff) const
00451   { collectStatistics_ = onOff;}
00453   void gutsOfDestructor(int type=1);
00455   void gutsOfInitialize(int type);
00456   void gutsOfCopy(const CoinFactorization &other);
00457 
00459   void resetStatistics();
00460 
00461 
00463 
00465 
00466   void getAreas ( int numberRows,
00467                   int numberColumns,
00468                   CoinBigIndex maximumL,
00469                   CoinBigIndex maximumU );
00470 
00473   void preProcess ( int state,
00474                     int possibleDuplicates = -1 );
00476   int factor (  );
00477 protected:
00480   int factorSparse (  );
00483   int factorDense (  );
00484 
00486   bool pivotOneOtherRow ( int pivotRow,
00487                           int pivotColumn );
00489   bool pivotRowSingleton ( int pivotRow,
00490                            int pivotColumn );
00492   bool pivotColumnSingleton ( int pivotRow,
00493                               int pivotColumn );
00494 
00499   bool getColumnSpace ( int iColumn,
00500                         int extraNeeded );
00501 
00505   bool getColumnSpaceIterateR ( int iColumn, double value,
00506                                int iRow);
00512   CoinBigIndex getColumnSpaceIterate ( int iColumn, double value,
00513                                int iRow);
00517   bool getRowSpace ( int iRow, int extraNeeded );
00518 
00522   bool getRowSpaceIterate ( int iRow,
00523                             int extraNeeded );
00525   void checkConsistency (  );
00527   inline void addLink ( int index, int count ) {
00528     int *nextCount = nextCount_.array();
00529     int *firstCount = firstCount_.array();
00530     int *lastCount = lastCount_.array();
00531     int next = firstCount[count];
00532       lastCount[index] = -2 - count;
00533     if ( next < 0 ) {
00534       //first with that count
00535       firstCount[count] = index;
00536       nextCount[index] = -1;
00537     } else {
00538       firstCount[count] = index;
00539       nextCount[index] = next;
00540       lastCount[next] = index;
00541   }}
00543   inline void deleteLink ( int index ) {
00544     int *nextCount = nextCount_.array();
00545     int *firstCount = firstCount_.array();
00546     int *lastCount = lastCount_.array();
00547     int next = nextCount[index];
00548     int last = lastCount[index];
00549     if ( last >= 0 ) {
00550       nextCount[last] = next;
00551     } else {
00552       int count = -last - 2;
00553 
00554       firstCount[count] = next;
00555     }
00556     if ( next >= 0 ) {
00557       lastCount[next] = last;
00558     }
00559     nextCount[index] = -2;
00560     lastCount[index] = -2;
00561     return;
00562   }
00564   void separateLinks(int count,bool rowsFirst);
00566   void cleanup (  );
00567 
00569   void updateColumnL ( CoinIndexedVector * region, int * indexIn ) const;
00571   void updateColumnLDensish ( CoinIndexedVector * region, int * indexIn ) const;
00573   void updateColumnLSparse ( CoinIndexedVector * region, int * indexIn ) const;
00575   void updateColumnLSparsish ( CoinIndexedVector * region, int * indexIn ) const;
00576 
00578   void updateColumnR ( CoinIndexedVector * region ) const;
00581   void updateColumnRFT ( CoinIndexedVector * region, int * indexIn );
00582 
00584   void updateColumnU ( CoinIndexedVector * region, int * indexIn) const;
00585 
00587   void updateColumnUSparse ( CoinIndexedVector * regionSparse, 
00588                              int * indexIn) const;
00590   void updateColumnUSparsish ( CoinIndexedVector * regionSparse, 
00591                                int * indexIn) const;
00593   void updateColumnUDensish ( CoinIndexedVector * regionSparse, 
00594                               int * indexIn) const;
00596   void updateColumnPFI ( CoinIndexedVector * regionSparse) const; 
00598   void permuteBack ( CoinIndexedVector * regionSparse, 
00599                      CoinIndexedVector * outVector) const;
00600 
00602   void updateColumnTransposePFI ( CoinIndexedVector * region) const;
00605   void updateColumnTransposeU ( CoinIndexedVector * region,
00606                                 int smallestIndex) const;
00609   void updateColumnTransposeUSparsish ( CoinIndexedVector * region,
00610                                         int smallestIndex) const;
00613   void updateColumnTransposeUDensish ( CoinIndexedVector * region,
00614                                        int smallestIndex) const;
00617   void updateColumnTransposeUSparse ( CoinIndexedVector * region) const;
00618 
00620   void updateColumnTransposeR ( CoinIndexedVector * region ) const;
00622   void updateColumnTransposeRDensish ( CoinIndexedVector * region ) const;
00624   void updateColumnTransposeRSparse ( CoinIndexedVector * region ) const;
00625 
00627   void updateColumnTransposeL ( CoinIndexedVector * region ) const;
00629   void updateColumnTransposeLDensish ( CoinIndexedVector * region ) const;
00631   void updateColumnTransposeLByRow ( CoinIndexedVector * region ) const;
00633   void updateColumnTransposeLSparsish ( CoinIndexedVector * region ) const;
00635   void updateColumnTransposeLSparse ( CoinIndexedVector * region ) const;
00636 public:
00641   int replaceColumnPFI ( CoinIndexedVector * regionSparse,
00642                          int pivotRow, double alpha);
00643 protected:
00646   int checkPivot(double saveFromU, double oldPivot) const;
00647   /********************************* START LARGE TEMPLATE ********/
00648 #ifdef INT_IS_8
00649 #define COINFACTORIZATION_BITS_PER_INT 64
00650 #define COINFACTORIZATION_SHIFT_PER_INT 6
00651 #define COINFACTORIZATION_MASK_PER_INT 0x3f
00652 #else
00653 #define COINFACTORIZATION_BITS_PER_INT 32
00654 #define COINFACTORIZATION_SHIFT_PER_INT 5
00655 #define COINFACTORIZATION_MASK_PER_INT 0x1f
00656 #endif
00657   template <class T>  inline bool
00658   pivot ( int pivotRow,
00659           int pivotColumn,
00660           CoinBigIndex pivotRowPosition,
00661           CoinBigIndex pivotColumnPosition,
00662           double work[],
00663           unsigned int workArea2[],
00664           int increment,
00665           int increment2,
00666           T markRow[] ,
00667           int largeInteger)
00668 {
00669   int *indexColumnU = indexColumnU_.array();
00670   CoinBigIndex *startColumnU = startColumnU_.array();
00671   int *numberInColumn = numberInColumn_.array();
00672   double *elementU = elementU_.array();
00673   int *indexRowU = indexRowU_.array();
00674   CoinBigIndex *startRowU = startRowU_.array();
00675   int *numberInRow = numberInRow_.array();
00676   double *elementL = elementL_.array();
00677   int *indexRowL = indexRowL_.array();
00678   int *saveColumn = saveColumn_.array();
00679   int *nextRow = nextRow_.array();
00680   int *lastRow = lastRow_.array() ;
00681 
00682   //store pivot columns (so can easily compress)
00683   int numberInPivotRow = numberInRow[pivotRow] - 1;
00684   CoinBigIndex startColumn = startColumnU[pivotColumn];
00685   int numberInPivotColumn = numberInColumn[pivotColumn] - 1;
00686   CoinBigIndex endColumn = startColumn + numberInPivotColumn + 1;
00687   int put = 0;
00688   CoinBigIndex startRow = startRowU[pivotRow];
00689   CoinBigIndex endRow = startRow + numberInPivotRow + 1;
00690 
00691   if ( pivotColumnPosition < 0 ) {
00692     for ( pivotColumnPosition = startRow; pivotColumnPosition < endRow; pivotColumnPosition++ ) {
00693       int iColumn = indexColumnU[pivotColumnPosition];
00694       if ( iColumn != pivotColumn ) {
00695         saveColumn[put++] = iColumn;
00696       } else {
00697         break;
00698       }
00699     }
00700   } else {
00701     for (CoinBigIndex i = startRow ; i < pivotColumnPosition ; i++ ) {
00702       saveColumn[put++] = indexColumnU[i];
00703     }
00704   }
00705   assert (pivotColumnPosition<endRow);
00706   assert (indexColumnU[pivotColumnPosition]==pivotColumn);
00707   pivotColumnPosition++;
00708   for ( ; pivotColumnPosition < endRow; pivotColumnPosition++ ) {
00709     saveColumn[put++] = indexColumnU[pivotColumnPosition];
00710   }
00711   //take out this bit of indexColumnU
00712   int next = nextRow[pivotRow];
00713   int last = lastRow[pivotRow];
00714 
00715   nextRow[last] = next;
00716   lastRow[next] = last;
00717   nextRow[pivotRow] = numberGoodU_;     //use for permute
00718   lastRow[pivotRow] = -2;
00719   numberInRow[pivotRow] = 0;
00720   //store column in L, compress in U and take column out
00721   CoinBigIndex l = lengthL_;
00722 
00723   if ( l + numberInPivotColumn > lengthAreaL_ ) {
00724     //need more memory
00725     printf("more memory needed in middle of invert\n");
00726     return false;
00727   }
00728   //l+=currentAreaL_->elementByColumn-elementL;
00729   CoinBigIndex lSave = l;
00730 
00731   pivotRowL_.array()[numberGoodL_] = pivotRow;
00732   CoinBigIndex * startColumnL = startColumnL_.array();
00733   startColumnL[numberGoodL_] = l;       //for luck and first time
00734   numberGoodL_++;
00735   startColumnL[numberGoodL_] = l + numberInPivotColumn;
00736   lengthL_ += numberInPivotColumn;
00737   if ( pivotRowPosition < 0 ) {
00738     for ( pivotRowPosition = startColumn; pivotRowPosition < endColumn; pivotRowPosition++ ) {
00739       int iRow = indexRowU[pivotRowPosition];
00740       if ( iRow != pivotRow ) {
00741         indexRowL[l] = iRow;
00742         elementL[l] = elementU[pivotRowPosition];
00743         markRow[iRow] = l - lSave;
00744         l++;
00745         //take out of row list
00746         CoinBigIndex start = startRowU[iRow];
00747         CoinBigIndex end = start + numberInRow[iRow];
00748         CoinBigIndex where = start;
00749 
00750         while ( indexColumnU[where] != pivotColumn ) {
00751           where++;
00752         }                       /* endwhile */
00753 #if DEBUG_COIN
00754         if ( where >= end ) {
00755           abort (  );
00756         }
00757 #endif
00758         indexColumnU[where] = indexColumnU[end - 1];
00759         numberInRow[iRow]--;
00760       } else {
00761         break;
00762       }
00763     }
00764   } else {
00765     CoinBigIndex i;
00766 
00767     for ( i = startColumn; i < pivotRowPosition; i++ ) {
00768       int iRow = indexRowU[i];
00769 
00770       markRow[iRow] = l - lSave;
00771       indexRowL[l] = iRow;
00772       elementL[l] = elementU[i];
00773       l++;
00774       //take out of row list
00775       CoinBigIndex start = startRowU[iRow];
00776       CoinBigIndex end = start + numberInRow[iRow];
00777       CoinBigIndex where = start;
00778 
00779       while ( indexColumnU[where] != pivotColumn ) {
00780         where++;
00781       }                         /* endwhile */
00782 #if DEBUG_COIN
00783       if ( where >= end ) {
00784         abort (  );
00785       }
00786 #endif
00787       indexColumnU[where] = indexColumnU[end - 1];
00788       numberInRow[iRow]--;
00789       assert (numberInRow[iRow]>=0);
00790     }
00791   }
00792   assert (pivotRowPosition<endColumn);
00793   assert (indexRowU[pivotRowPosition]==pivotRow);
00794   double pivotElement = elementU[pivotRowPosition];
00795   double pivotMultiplier = 1.0 / pivotElement;
00796 
00797   pivotRegion_.array()[numberGoodU_] = pivotMultiplier;
00798   pivotRowPosition++;
00799   for ( ; pivotRowPosition < endColumn; pivotRowPosition++ ) {
00800     int iRow = indexRowU[pivotRowPosition];
00801     
00802     markRow[iRow] = l - lSave;
00803     indexRowL[l] = iRow;
00804     elementL[l] = elementU[pivotRowPosition];
00805     l++;
00806     //take out of row list
00807     CoinBigIndex start = startRowU[iRow];
00808     CoinBigIndex end = start + numberInRow[iRow];
00809     CoinBigIndex where = start;
00810     
00811     while ( indexColumnU[where] != pivotColumn ) {
00812       where++;
00813     }                           /* endwhile */
00814 #if DEBUG_COIN
00815     if ( where >= end ) {
00816       abort (  );
00817     }
00818 #endif
00819     indexColumnU[where] = indexColumnU[end - 1];
00820     numberInRow[iRow]--;
00821     assert (numberInRow[iRow]>=0);
00822   }
00823   markRow[pivotRow] = largeInteger;
00824   //compress pivot column (move pivot to front including saved)
00825   numberInColumn[pivotColumn] = 0;
00826   //use end of L for temporary space
00827   int *indexL = &indexRowL[lSave];
00828   double *multipliersL = &elementL[lSave];
00829 
00830   //adjust
00831   int j;
00832 
00833   for ( j = 0; j < numberInPivotColumn; j++ ) {
00834     multipliersL[j] *= pivotMultiplier;
00835   }
00836   //zero out fill
00837   CoinBigIndex iErase;
00838   for ( iErase = 0; iErase < increment2 * numberInPivotRow;
00839         iErase++ ) {
00840     workArea2[iErase] = 0;
00841   }
00842   CoinBigIndex added = numberInPivotRow * numberInPivotColumn;
00843   unsigned int *temp2 = workArea2;
00844   int * nextColumn = nextColumn_.array();
00845 
00846   //pack down and move to work
00847   int jColumn;
00848   for ( jColumn = 0; jColumn < numberInPivotRow; jColumn++ ) {
00849     int iColumn = saveColumn[jColumn];
00850     CoinBigIndex startColumn = startColumnU[iColumn];
00851     CoinBigIndex endColumn = startColumn + numberInColumn[iColumn];
00852     int iRow = indexRowU[startColumn];
00853     double value = elementU[startColumn];
00854     double largest;
00855     CoinBigIndex put = startColumn;
00856     CoinBigIndex positionLargest = -1;
00857     double thisPivotValue = 0.0;
00858 
00859     //compress column and find largest not updated
00860     bool checkLargest;
00861     int mark = markRow[iRow];
00862 
00863     if ( mark < 0 ) {
00864       largest = fabs ( value );
00865       positionLargest = put;
00866       put++;
00867       checkLargest = false;
00868     } else {
00869       //need to find largest
00870       largest = 0.0;
00871       checkLargest = true;
00872       if ( mark != largeInteger ) {
00873         //will be updated
00874         work[mark] = value;
00875         int word = mark >> COINFACTORIZATION_SHIFT_PER_INT;
00876         int bit = mark & COINFACTORIZATION_MASK_PER_INT;
00877 
00878         temp2[word] = temp2[word] | ( 1 << bit );       //say already in counts
00879         added--;
00880       } else {
00881         thisPivotValue = value;
00882       }
00883     }
00884     CoinBigIndex i;
00885     for ( i = startColumn + 1; i < endColumn; i++ ) {
00886       iRow = indexRowU[i];
00887       value = elementU[i];
00888       int mark = markRow[iRow];
00889 
00890       if ( mark < 0 ) {
00891         //keep
00892         indexRowU[put] = iRow;
00893         elementU[put] = value;
00894         if ( checkLargest ) {
00895           double absValue = fabs ( value );
00896 
00897           if ( absValue > largest ) {
00898             largest = absValue;
00899             positionLargest = put;
00900           }
00901         }
00902         put++;
00903       } else if ( mark != largeInteger ) {
00904         //will be updated
00905         work[mark] = value;
00906         int word = mark >> COINFACTORIZATION_SHIFT_PER_INT;
00907         int bit = mark & COINFACTORIZATION_MASK_PER_INT;
00908 
00909         temp2[word] = temp2[word] | ( 1 << bit );       //say already in counts
00910         added--;
00911       } else {
00912         thisPivotValue = value;
00913       }
00914     }
00915     //slot in pivot
00916     elementU[put] = elementU[startColumn];
00917     indexRowU[put] = indexRowU[startColumn];
00918     if ( positionLargest == startColumn ) {
00919       positionLargest = put;    //follow if was largest
00920     }
00921     put++;
00922     elementU[startColumn] = thisPivotValue;
00923     indexRowU[startColumn] = pivotRow;
00924     //clean up counts
00925     startColumn++;
00926     numberInColumn[iColumn] = put - startColumn;
00927     int * numberInColumnPlus = numberInColumnPlus_.array();
00928     numberInColumnPlus[iColumn]++;
00929     startColumnU[iColumn]++;
00930     //how much space have we got
00931     int next = nextColumn[iColumn];
00932     CoinBigIndex space;
00933 
00934     space = startColumnU[next] - put - numberInColumnPlus[next];
00935     //assume no zero elements
00936     if ( numberInPivotColumn > space ) {
00937       //getColumnSpace also moves fixed part
00938       if ( !getColumnSpace ( iColumn, numberInPivotColumn ) ) {
00939         return false;
00940       }
00941       //redo starts
00942       positionLargest = positionLargest + startColumnU[iColumn] - startColumn;
00943       startColumn = startColumnU[iColumn];
00944       put = startColumn + numberInColumn[iColumn];
00945     }
00946     double tolerance = zeroTolerance_;
00947 
00948     int *nextCount = nextCount_.array();
00949     for ( j = 0; j < numberInPivotColumn; j++ ) {
00950       value = work[j] - thisPivotValue * multipliersL[j];
00951       double absValue = fabs ( value );
00952 
00953       if ( absValue > tolerance ) {
00954         work[j] = 0.0;
00955         elementU[put] = value;
00956         indexRowU[put] = indexL[j];
00957         if ( absValue > largest ) {
00958           largest = absValue;
00959           positionLargest = put;
00960         }
00961         put++;
00962       } else {
00963         work[j] = 0.0;
00964         added--;
00965         int word = j >> COINFACTORIZATION_SHIFT_PER_INT;
00966         int bit = j & COINFACTORIZATION_MASK_PER_INT;
00967 
00968         if ( temp2[word] & ( 1 << bit ) ) {
00969           //take out of row list
00970           iRow = indexL[j];
00971           CoinBigIndex start = startRowU[iRow];
00972           CoinBigIndex end = start + numberInRow[iRow];
00973           CoinBigIndex where = start;
00974 
00975           while ( indexColumnU[where] != iColumn ) {
00976             where++;
00977           }                     /* endwhile */
00978 #if DEBUG_COIN
00979           if ( where >= end ) {
00980             abort (  );
00981           }
00982 #endif
00983           indexColumnU[where] = indexColumnU[end - 1];
00984           numberInRow[iRow]--;
00985         } else {
00986           //make sure won't be added
00987           int word = j >> COINFACTORIZATION_SHIFT_PER_INT;
00988           int bit = j & COINFACTORIZATION_MASK_PER_INT;
00989 
00990           temp2[word] = temp2[word] | ( 1 << bit );     //say already in counts
00991         }
00992       }
00993     }
00994     numberInColumn[iColumn] = put - startColumn;
00995     //move largest
00996     if ( positionLargest >= 0 ) {
00997       value = elementU[positionLargest];
00998       iRow = indexRowU[positionLargest];
00999       elementU[positionLargest] = elementU[startColumn];
01000       indexRowU[positionLargest] = indexRowU[startColumn];
01001       elementU[startColumn] = value;
01002       indexRowU[startColumn] = iRow;
01003     }
01004     //linked list for column
01005     if ( nextCount[iColumn + numberRows_] != -2 ) {
01006       //modify linked list
01007       deleteLink ( iColumn + numberRows_ );
01008       addLink ( iColumn + numberRows_, numberInColumn[iColumn] );
01009     }
01010     temp2 += increment2;
01011   }
01012   //get space for row list
01013   unsigned int *putBase = workArea2;
01014   int bigLoops = numberInPivotColumn >> COINFACTORIZATION_SHIFT_PER_INT;
01015   int i = 0;
01016 
01017   // do linked lists and update counts
01018   while ( bigLoops ) {
01019     bigLoops--;
01020     int bit;
01021     for ( bit = 0; bit < COINFACTORIZATION_BITS_PER_INT; i++, bit++ ) {
01022       unsigned int *putThis = putBase;
01023       int iRow = indexL[i];
01024 
01025       //get space
01026       int number = 0;
01027       int jColumn;
01028 
01029       for ( jColumn = 0; jColumn < numberInPivotRow; jColumn++ ) {
01030         unsigned int test = *putThis;
01031 
01032         putThis += increment2;
01033         test = 1 - ( ( test >> bit ) & 1 );
01034         number += test;
01035       }
01036       int next = nextRow[iRow];
01037       CoinBigIndex space;
01038 
01039       space = startRowU[next] - startRowU[iRow];
01040       number += numberInRow[iRow];
01041       if ( space < number ) {
01042         if ( !getRowSpace ( iRow, number ) ) {
01043           return false;
01044         }
01045       }
01046       // now do
01047       putThis = putBase;
01048       next = nextRow[iRow];
01049       number = numberInRow[iRow];
01050       CoinBigIndex end = startRowU[iRow] + number;
01051       int saveIndex = indexColumnU[startRowU[next]];
01052 
01053       //add in
01054       for ( jColumn = 0; jColumn < numberInPivotRow; jColumn++ ) {
01055         unsigned int test = *putThis;
01056 
01057         putThis += increment2;
01058         test = 1 - ( ( test >> bit ) & 1 );
01059         indexColumnU[end] = saveColumn[jColumn];
01060         end += test;
01061       }
01062       //put back next one in case zapped
01063       indexColumnU[startRowU[next]] = saveIndex;
01064       markRow[iRow] = -1;
01065       number = end - startRowU[iRow];
01066       numberInRow[iRow] = number;
01067       deleteLink ( iRow );
01068       addLink ( iRow, number );
01069     }
01070     putBase++;
01071   }                             /* endwhile */
01072   int bit;
01073 
01074   for ( bit = 0; i < numberInPivotColumn; i++, bit++ ) {
01075     unsigned int *putThis = putBase;
01076     int iRow = indexL[i];
01077 
01078     //get space
01079     int number = 0;
01080     int jColumn;
01081 
01082     for ( jColumn = 0; jColumn < numberInPivotRow; jColumn++ ) {
01083       unsigned int test = *putThis;
01084 
01085       putThis += increment2;
01086       test = 1 - ( ( test >> bit ) & 1 );
01087       number += test;
01088     }
01089     int next = nextRow[iRow];
01090     CoinBigIndex space;
01091 
01092     space = startRowU[next] - startRowU[iRow];
01093     number += numberInRow[iRow];
01094     if ( space < number ) {
01095       if ( !getRowSpace ( iRow, number ) ) {
01096         return false;
01097       }
01098     }
01099     // now do
01100     putThis = putBase;
01101     next = nextRow[iRow];
01102     number = numberInRow[iRow];
01103     CoinBigIndex end = startRowU[iRow] + number;
01104     int saveIndex;
01105 
01106     saveIndex = indexColumnU[startRowU[next]];
01107 
01108     //add in
01109     for ( jColumn = 0; jColumn < numberInPivotRow; jColumn++ ) {
01110       unsigned int test = *putThis;
01111 
01112       putThis += increment2;
01113       test = 1 - ( ( test >> bit ) & 1 );
01114 
01115       indexColumnU[end] = saveColumn[jColumn];
01116       end += test;
01117     }
01118     indexColumnU[startRowU[next]] = saveIndex;
01119     markRow[iRow] = -1;
01120     number = end - startRowU[iRow];
01121     numberInRow[iRow] = number;
01122     deleteLink ( iRow );
01123     addLink ( iRow, number );
01124   }
01125   markRow[pivotRow] = -1;
01126   //modify linked list for pivots
01127   deleteLink ( pivotRow );
01128   deleteLink ( pivotColumn + numberRows_ );
01129   totalElements_ += added;
01130   return true;
01131 }
01132 
01133   /********************************* END LARGE TEMPLATE ********/
01135 
01136 protected:
01137 
01140 
01141   double pivotTolerance_;
01143   double zeroTolerance_;
01145   double slackValue_;
01147   double areaFactor_;
01149   double relaxCheck_;
01151   int numberRows_;
01153   int numberRowsExtra_;
01155   int maximumRowsExtra_;
01157   int numberColumns_;
01159   int numberColumnsExtra_;
01161   int maximumColumnsExtra_;
01163   int numberGoodU_;
01165   int numberGoodL_;
01167   int maximumPivots_;
01169   int numberPivots_;
01172   CoinBigIndex totalElements_;
01174   CoinBigIndex factorElements_;
01176   CoinIntArrayWithLength pivotColumn_;
01178   CoinIntArrayWithLength permute_;
01180   CoinIntArrayWithLength permuteBack_;
01182   CoinIntArrayWithLength pivotColumnBack_;
01184   int status_;
01185 
01190   //int increasingRows_;
01191 
01193   int numberTrials_;
01195   CoinBigIndexArrayWithLength startRowU_;
01196 
01198   CoinIntArrayWithLength numberInRow_;
01199 
01201   CoinIntArrayWithLength numberInColumn_;
01202 
01204   CoinIntArrayWithLength numberInColumnPlus_;
01205 
01208   CoinIntArrayWithLength firstCount_;
01209 
01211   CoinIntArrayWithLength nextCount_;
01212 
01214   CoinIntArrayWithLength lastCount_;
01215 
01217   CoinIntArrayWithLength nextColumn_;
01218 
01220   CoinIntArrayWithLength lastColumn_;
01221 
01223   CoinIntArrayWithLength nextRow_;
01224 
01226   CoinIntArrayWithLength lastRow_;
01227 
01229   CoinIntArrayWithLength saveColumn_;
01230 
01232   CoinIntArrayWithLength markRow_;
01233 
01235   int messageLevel_;
01236 
01238   int biggerDimension_;
01239 
01241   CoinIntArrayWithLength indexColumnU_;
01242 
01244   CoinIntArrayWithLength pivotRowL_;
01245 
01247   CoinDoubleArrayWithLength pivotRegion_;
01248 
01250   int numberSlacks_;
01251 
01253   int numberU_;
01254 
01256   CoinBigIndex maximumU_;
01257 
01259   //int baseU_;
01260 
01262   CoinBigIndex lengthU_;
01263 
01265   CoinBigIndex lengthAreaU_;
01266 
01268   CoinDoubleArrayWithLength elementU_;
01269 
01271   CoinIntArrayWithLength indexRowU_;
01272 
01274   CoinBigIndexArrayWithLength startColumnU_;
01275 
01277   CoinBigIndexArrayWithLength convertRowToColumnU_;
01278 
01280   CoinBigIndex numberL_;
01281 
01283   CoinBigIndex baseL_;
01284 
01286   CoinBigIndex lengthL_;
01287 
01289   CoinBigIndex lengthAreaL_;
01290 
01292   CoinDoubleArrayWithLength elementL_;
01293 
01295   CoinIntArrayWithLength indexRowL_;
01296 
01298   CoinBigIndexArrayWithLength startColumnL_;
01299 
01301   bool doForrestTomlin_;
01302 
01304   int numberR_;
01305 
01307   CoinBigIndex lengthR_;
01308 
01310   CoinBigIndex lengthAreaR_;
01311 
01313   double *elementR_;
01314 
01316   int *indexRowR_;
01317 
01319   CoinBigIndexArrayWithLength startColumnR_;
01320 
01322   double  * denseArea_;
01323 
01325   int * densePermute_;
01326 
01328   int numberDense_;
01329 
01331   int denseThreshold_;
01332 
01334   CoinDoubleArrayWithLength workArea_;
01335 
01337   CoinUnsignedIntArrayWithLength workArea2_;
01338 
01340   CoinBigIndex numberCompressions_;
01341 
01343   mutable double ftranCountInput_;
01344   mutable double ftranCountAfterL_;
01345   mutable double ftranCountAfterR_;
01346   mutable double ftranCountAfterU_;
01347   mutable double btranCountInput_;
01348   mutable double btranCountAfterU_;
01349   mutable double btranCountAfterR_;
01350   mutable double btranCountAfterL_;
01351 
01353   mutable int numberFtranCounts_;
01354   mutable int numberBtranCounts_;
01355 
01357   double ftranAverageAfterL_;
01358   double ftranAverageAfterR_;
01359   double ftranAverageAfterU_;
01360   double btranAverageAfterU_;
01361   double btranAverageAfterR_;
01362   double btranAverageAfterL_;
01363 
01365   mutable bool collectStatistics_;
01366 
01368   int sparseThreshold_;
01369 
01371   int sparseThreshold2_;
01372 
01374   CoinBigIndexArrayWithLength startRowL_;
01375 
01377   CoinIntArrayWithLength indexColumnL_;
01378 
01380   CoinDoubleArrayWithLength elementByRowL_;
01381 
01383   mutable CoinIntArrayWithLength sparse_;
01387   int biasLU_;
01393   int persistenceFlag_;
01395 };
01396 // Dense coding
01397 #ifdef COIN_HAS_LAPACK
01398 #define DENSE_CODE 1
01399 /* Type of Fortran integer translated into C */
01400 #ifndef ipfint
01401 //typedef ipfint FORTRAN_INTEGER_TYPE ;
01402 typedef int ipfint;
01403 typedef const int cipfint;
01404 #endif
01405 #endif
01406 #endif

Generated on Sun Nov 14 14:06:32 2010 for Coin-All by  doxygen 1.4.7