// Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. #if defined(_MSC_VER) // Turn off compiler warning about long names # pragma warning(disable:4786) #endif #include "CoinUtilsConfig.h" #include #include #include #include "CoinFactorization.hpp" #include "CoinIndexedVector.hpp" #include "CoinHelperFunctions.hpp" #if DENSE_CODE==1 // using simple lapack interface extern "C" { /** LAPACK Fortran subroutine DGETRF. */ void F77_FUNC(dgetrf,DGETRF)(ipfint * m, ipfint *n, double *A, ipfint *ldA, ipfint * ipiv, ipfint *info); } #endif static int counter1=0; // factorSparse. Does sparse phase of factorization //return code is <0 error, 0= finished int CoinFactorization::factorSparse ( ) { int *indexRow = indexRowU_.array(); int *indexColumn = indexColumnU_.array(); double *element = elementU_.array(); int count = 1; workArea_.conditionalNew(numberRows_); double * workArea = workArea_.array(); counter1++; // when to go dense int denseThreshold=denseThreshold_; CoinZeroN ( workArea, numberRows_ ); //get space for bit work area CoinBigIndex workSize = 1000; workArea2_.conditionalNew(workSize); unsigned int * workArea2 = workArea2_.array(); int larger; if ( numberRows_ < numberColumns_ ) { larger = numberColumns_; } else { larger = numberRows_; } int status = 0; //do slacks first int * numberInRow = numberInRow_.array(); int * numberInColumn = numberInColumn_.array(); int * numberInColumnPlus = numberInColumnPlus_.array(); int * pivotRowL = pivotRowL_.array(); CoinBigIndex * startColumnU = startColumnU_.array(); CoinBigIndex * startColumnL = startColumnL_.array(); if (biasLU_<3&&numberColumns_==numberRows_) { int iPivotColumn; int * pivotColumn = pivotColumn_.array(); int * nextRow = nextRow_.array(); int * lastRow = lastRow_.array(); for ( iPivotColumn = 0; iPivotColumn < numberColumns_; iPivotColumn++ ) { if ( numberInColumn[iPivotColumn] == 1 ) { CoinBigIndex start = startColumnU[iPivotColumn]; double value = element[start]; if ( value == slackValue_ && numberInColumnPlus[iPivotColumn] == 0 ) { // treat as slack int iRow = indexRow[start]; // but only if row not marked if (numberInRow[iRow]>0) { totalElements_ -= numberInRow[iRow]; //take out this bit of indexColumnU int next = nextRow[iRow]; int last = lastRow[iRow]; nextRow[last] = next; lastRow[next] = last; nextRow[iRow] = numberGoodU_; //use for permute //modify linked list for pivots deleteLink ( iRow ); numberInRow[iRow]=-1; numberInColumn[iPivotColumn]=0; pivotRowL[numberGoodL_] = iRow; numberGoodL_++; startColumnL[numberGoodL_] = 0; pivotColumn[numberGoodU_] = iPivotColumn; numberGoodU_++; } } } } // redo preProcess(4); } numberSlacks_ = numberGoodU_; int *nextCount = nextCount_.array(); int *firstCount = firstCount_.array(); CoinBigIndex *startRow = startRowU_.array(); CoinBigIndex *startColumn = startColumnU; double pivotTolerance = pivotTolerance_; int numberTrials = numberTrials_; int numberRows = numberRows_; // Put column singletons first - (if false) separateLinks(1,(biasLU_>1)); int counter2=0; while ( count <= biggerDimension_ ) { counter2++; int badRow=-1; if (counter1==-1&&counter2>=0) { // check counts consistent for (int iCount=1;iCount= 0 ) { if ( look < numberRows_ ) { int iRow = look; if (iRow==badRow) printf("row count for row %d is %d\n",iCount,iRow); if ( numberInRow[iRow] != iCount ) { printf("failed debug on %d entry to factorSparse and %d try\n", counter1,counter2); printf("row %d - count %d number %d\n",iRow,iCount,numberInRow[iRow]); abort(); } look = nextCount[look]; } else { int iColumn = look - numberRows; if ( numberInColumn[iColumn] != iCount ) { printf("failed debug on %d entry to factorSparse and %d try\n", counter1,counter2); printf("column %d - count %d number %d\n",iColumn,iCount,numberInColumn[iColumn]); abort(); } look = nextCount[look]; } } } } CoinBigIndex minimumCount = COIN_INT_MAX; double minimumCost = COIN_DBL_MAX; int iPivotRow = -1; int iPivotColumn = -1; int pivotRowPosition = -1; int pivotColumnPosition = -1; int look = firstCount[count]; int trials = 0; int * pivotColumn = pivotColumn_.array(); if ( count == 1 && firstCount[1] >= 0 &&!biasLU_) { //do column singletons first to put more in U while ( look >= 0 ) { if ( look < numberRows_ ) { look = nextCount[look]; } else { int iColumn = look - numberRows_; assert ( numberInColumn[iColumn] == count ); CoinBigIndex start = startColumnU[iColumn]; int iRow = indexRow[start]; iPivotRow = iRow; pivotRowPosition = start; iPivotColumn = iColumn; assert (iPivotRow>=0&&iPivotColumn>=0); pivotColumnPosition = -1; look = -1; break; } } /* endwhile */ if ( iPivotRow < 0 ) { //back to singletons look = firstCount[1]; } } while ( look >= 0 ) { if ( look < numberRows_ ) { int iRow = look; if ( numberInRow[iRow] != count ) { printf("failed on %d entry to factorSparse and %d try\n", counter1,counter2); printf("row %d - count %d number %d\n",iRow,count,numberInRow[iRow]); abort(); } look = nextCount[look]; bool rejected = false; CoinBigIndex start = startRow[iRow]; CoinBigIndex end = start + count; CoinBigIndex i; for ( i = start; i < end; i++ ) { int iColumn = indexColumn[i]; assert (numberInColumn[iColumn]>0); double cost = ( count - 1 ) * numberInColumn[iColumn]; if ( cost < minimumCost ) { CoinBigIndex where = startColumn[iColumn]; double minimumValue = element[where]; minimumValue = fabs ( minimumValue ) * pivotTolerance; while ( indexRow[where] != iRow ) { where++; } /* endwhile */ assert ( where < startColumn[iColumn] + numberInColumn[iColumn]); double value = element[where]; value = fabs ( value ); if ( value >= minimumValue ) { minimumCost = cost; minimumCount = numberInColumn[iColumn]; iPivotRow = iRow; pivotRowPosition = -1; iPivotColumn = iColumn; assert (iPivotRow>=0&&iPivotColumn>=0); pivotColumnPosition = i; rejected=false; if ( minimumCount < count ) { look = -1; break; } } else if ( iPivotRow == -1 ) { rejected = true; } } } trials++; if ( trials >= numberTrials && iPivotRow >= 0 ) { look = -1; break; } if ( rejected ) { //take out for moment //eligible when row changes deleteLink ( iRow ); addLink ( iRow, biggerDimension_ + 1 ); } } else { int iColumn = look - numberRows; assert ( numberInColumn[iColumn] == count ); look = nextCount[look]; CoinBigIndex start = startColumn[iColumn]; CoinBigIndex end = start + numberInColumn[iColumn]; double minimumValue = element[start]; minimumValue = fabs ( minimumValue ) * pivotTolerance; CoinBigIndex i; for ( i = start; i < end; i++ ) { double value = element[i]; value = fabs ( value ); if ( value >= minimumValue ) { int iRow = indexRow[i]; int nInRow = numberInRow[iRow]; assert (nInRow>0); double cost = ( count - 1 ) * nInRow; if ( cost < minimumCost ) { minimumCost = cost; minimumCount = nInRow; iPivotRow = iRow; pivotRowPosition = i; iPivotColumn = iColumn; assert (iPivotRow>=0&&iPivotColumn>=0); pivotColumnPosition = -1; if ( minimumCount <= count + 1 ) { look = -1; break; } } } } trials++; if ( trials >= numberTrials && iPivotRow >= 0 ) { look = -1; break; } } } /* endwhile */ if (iPivotRow>=0) { if ( iPivotRow >= 0 ) { int numberDoRow = numberInRow[iPivotRow] - 1; int numberDoColumn = numberInColumn[iPivotColumn] - 1; totalElements_ -= ( numberDoRow + numberDoColumn + 1 ); if ( numberDoColumn > 0 ) { if ( numberDoRow > 0 ) { if ( numberDoColumn > 1 ) { // if (1) { //need to adjust more for cache and SMP //allow at least 4 extra int increment = numberDoColumn + 1 + 4; if ( increment & 15 ) { increment = increment & ( ~15 ); increment += 16; } int increment2 = ( increment + COINFACTORIZATION_BITS_PER_INT - 1 ) >> COINFACTORIZATION_SHIFT_PER_INT; CoinBigIndex size = increment2 * numberDoRow; if ( size > workSize ) { workSize = size; workArea2_.conditionalNew(workSize); workArea2 = workArea2_.array(); } bool goodPivot; if ( larger < 32766 ) { //branch out to best pivot routine goodPivot = pivot ( iPivotRow, iPivotColumn, pivotRowPosition, pivotColumnPosition, workArea, workArea2, increment, increment2, ( short * ) markRow_.array() , 32767); } else { //might be able to do better by permuting goodPivot = pivot ( iPivotRow, iPivotColumn, pivotRowPosition, pivotColumnPosition, workArea, workArea2, increment, increment2, ( int * ) markRow_.array() , COIN_INT_MAX); } if ( !goodPivot ) { status = -99; count=biggerDimension_+1; break; } } else { if ( !pivotOneOtherRow ( iPivotRow, iPivotColumn ) ) { status = -99; count=biggerDimension_+1; break; } } } else { assert (!numberDoRow); if ( !pivotRowSingleton ( iPivotRow, iPivotColumn ) ) { status = -99; count=biggerDimension_+1; break; } } } else { assert (!numberDoColumn); if ( !pivotColumnSingleton ( iPivotRow, iPivotColumn ) ) { status = -99; count=biggerDimension_+1; break; } } pivotColumn[numberGoodU_] = iPivotColumn; numberGoodU_++; // This should not need to be trapped here - but be safe if (numberGoodU_==numberRows_) count=biggerDimension_+1; } #if COIN_DEBUG==2 checkConsistency ( ); #endif #if 0 // Even if no dense code may be better to use naive dense if (!denseThreshold_&&totalElements_>1000) { int leftRows=numberRows_-numberGoodU_; double full = leftRows; full *= full; assert (full>=0.0); double leftElements = totalElements_; double ratio; if (leftRows>2000) ratio=4.0; else ratio=3.0; if (ratio*leftElements>full) denseThreshold=1; } #endif if (denseThreshold) { // see whether to go dense int leftRows=numberRows_-numberGoodU_; double full = leftRows; full *= full; assert (full>=0.0); double leftElements = totalElements_; //if (leftRows==100) //printf("at 100 %d elements\n",totalElements_); double ratio; if (leftRows>2000) ratio=4.0; else if (leftRows>800) ratio=3.0; else if (leftRows>256) ratio=2.0; else ratio=1.5; if ((ratio*leftElements>full&&leftRows>denseThreshold_)) { //return to do dense if (status!=0) break; int check=0; for (int iColumn=0;iColumn=2<<15) { abort(); } CoinBigIndex full; if (denseThreshold_>0) full = numberDense_*numberDense_; else full = - denseThreshold_*numberDense_; totalElements_=full; denseArea_= new double [full]; CoinZeroN(denseArea_,full); densePermute_= new int [numberDense_]; int * pivotRowL = pivotRowL_.array(); int * indexRowU = indexRowU_.array(); //mark row lookup using lastRow int i; int * nextRow = nextRow_.array(); int * lastRow = lastRow_.array(); int * numberInColumn = numberInColumn_.array(); int * numberInColumnPlus = numberInColumnPlus_.array(); for (i=0;i0) { assert(numberGoodU_==numberRows_); numberGoodL_=numberRows_; //now factorize //dgef(denseArea_,&numberDense_,&numberDense_,densePermute_); int info; F77_FUNC(dgetrf,DGETRF)(&numberDense_,&numberDense_,denseArea_,&numberDense_,densePermute_, &info); // need to check size of pivots if(info) status = -1; return status; } #endif numberGoodU_ = numberRows_-numberDense_; int base = numberGoodU_; int iDense; int numberToDo=-denseThreshold_; denseThreshold_=0; double tolerance = zeroTolerance_; tolerance = 1.0e-30; int * nextColumn = nextColumn_.array(); const int * pivotColumnConst = pivotColumn_.array(); // make sure we have enough space in L and U for (iDense=0;iDense space ) { //getColumnSpace also moves fixed part if ( !getColumnSpace ( iColumn, numberInPivotColumn ) ) { return -99; } } // set so further moves will work numberInColumn[iColumn]=numberInPivotColumn; } // Fill in ? for (iColumn=numberGoodU_+numberToDo;iColumn lengthAreaL_ ) { //need more memory if ((messageLevel_&4)!=0) std::cout << "more memory needed in middle of invert" << std::endl; return -99; } double *elementU = elementU_.array(); for (iDense=0;iDenselargest) { largest = fabs(element[iRow]); pivotRow = iRow; } } if ( pivotRow >= 0 ) { iColumn = pivotColumnConst[base+iDense]; double pivotElement=element[pivotRow]; // get original row int originalRow = densePermute_[pivotRow]; // do nextRow nextRow[originalRow] = numberGoodU_; // swap densePermute_[pivotRow]=densePermute_[iDense]; densePermute_[iDense] = originalRow; for (jDense=iDense;jDensetolerance) { indexRowL[l] = densePermute_[iRow]; elementL[l++] = value; } } pivotRowL[numberGoodL_++] = originalRow; lengthL_ = l; startColumnL[numberGoodL_] = l; // update U column CoinBigIndex start = startColumnU[iColumn]; for (iRow=0;iRowtolerance) { indexRowU[start] = densePermute_[iRow]; elementU[start++] = element[iRow]; } } numberInColumn[iColumn]=0; numberInColumnPlus[iColumn] += start-startColumnU[iColumn]; startColumnU[iColumn]=start; // update other columns double * element2 = element+numberDense_; for (jDense=iDense+1;jDense=0) { int next2=nextCount[next]; if (next>=numberRows_) { nextCount[next]=-1; // Column if (firstColumn>=0) { lastCount[next]=lastColumn; nextCount[lastColumn]=next; } else { lastCount[next]= -2 - count; firstColumn=next; } lastColumn=next; } else { // Row if (firstRow>=0) { lastCount[next]=lastRow; nextCount[lastRow]=next; } else { lastCount[next]= -2 - count; firstRow=next; } lastRow=next; } next=next2; } if (rowsFirst&&firstRow>=0) { firstCount[count]=firstRow; nextCount[lastRow]=firstColumn; if (firstColumn>=0) lastCount[firstColumn]=lastRow; } else if (firstRow<0) { firstCount[count]=firstColumn; } else if (firstColumn>=0) { firstCount[count]=firstColumn; nextCount[lastColumn]=firstRow; if (firstRow>=0) lastCount[firstRow]=lastColumn; } } // Debug - save on file int CoinFactorization::saveFactorization (const char * file ) const { FILE * fp = fopen(file,"wb"); if (fp) { // Save so we can pick up scalars const char * first = (const char *) &pivotTolerance_; const char * last = (const char *) &biasLU_; // increment last += sizeof(int); if (fwrite(first,last-first,1,fp)!=1) return 1; // Now arrays if (CoinToFile(elementU_.array(),lengthAreaU_ , fp )) return 1; if (CoinToFile(indexRowU_.array(),lengthAreaU_ , fp )) return 1; if (CoinToFile(indexColumnU_.array(),lengthAreaU_ , fp )) return 1; if (CoinToFile(convertRowToColumnU_.array(),lengthAreaU_ , fp )) return 1; if (CoinToFile(elementByRowL_.array(),lengthAreaL_ , fp )) return 1; if (CoinToFile(indexColumnL_.array(),lengthAreaL_ , fp )) return 1; if (CoinToFile(startRowL_.array() , numberRows_+1, fp )) return 1; if (CoinToFile(elementL_.array(),lengthAreaL_ , fp )) return 1; if (CoinToFile(indexRowL_.array(),lengthAreaL_ , fp )) return 1; if (CoinToFile(startColumnL_.array(),numberRows_ + 1 , fp )) return 1; if (CoinToFile(markRow_.array(),numberRows_ , fp)) return 1; if (CoinToFile(saveColumn_.array(),numberColumns_ , fp)) return 1; if (CoinToFile(startColumnR_.array() , maximumPivots_ + 1 , fp )) return 1; if (CoinToFile(startRowU_.array(),maximumRowsExtra_ + 1 , fp )) return 1; if (CoinToFile(numberInRow_.array(),maximumRowsExtra_ + 1 , fp )) return 1; if (CoinToFile(nextRow_.array(),maximumRowsExtra_ + 1 , fp )) return 1; if (CoinToFile(lastRow_.array(),maximumRowsExtra_ + 1 , fp )) return 1; if (CoinToFile(pivotRegion_.array(),maximumRowsExtra_ + 1 , fp )) return 1; if (CoinToFile(permuteBack_.array(),maximumRowsExtra_ + 1 , fp )) return 1; if (CoinToFile(permute_.array(),maximumRowsExtra_ + 1 , fp )) return 1; if (CoinToFile(pivotColumnBack_.array(),maximumRowsExtra_ + 1 , fp )) return 1; if (CoinToFile(startColumnU_.array(),maximumColumnsExtra_ + 1 , fp )) return 1; if (CoinToFile(numberInColumn_.array(),maximumColumnsExtra_ + 1 , fp )) return 1; if (CoinToFile(numberInColumnPlus_.array(),maximumColumnsExtra_ + 1 , fp )) return 1; if (CoinToFile(firstCount_.array(),biggerDimension_ + 2 , fp )) return 1; if (CoinToFile(nextCount_.array(),numberRows_ + numberColumns_ , fp )) return 1; if (CoinToFile(lastCount_.array(),numberRows_ + numberColumns_ , fp )) return 1; if (CoinToFile(pivotRowL_.array(),numberRows_ + 1 , fp )) return 1; if (CoinToFile(pivotColumn_.array(),maximumColumnsExtra_ + 1 , fp )) return 1; if (CoinToFile(nextColumn_.array(),maximumColumnsExtra_ + 1 , fp )) return 1; if (CoinToFile(lastColumn_.array(),maximumColumnsExtra_ + 1 , fp )) return 1; if (CoinToFile(denseArea_ , numberDense_*numberDense_, fp )) return 1; if (CoinToFile(densePermute_ , numberDense_, fp )) return 1; fclose(fp); } return 0; } // Debug - restore from file int CoinFactorization::restoreFactorization (const char * file , bool factorIt ) { FILE * fp = fopen(file,"rb"); if (fp) { // Get rid of current gutsOfDestructor(); int newSize=0; // for checking - should be same // Restore so we can pick up scalars char * first = (char *) &pivotTolerance_; char * last = (char *) &biasLU_; // increment last += sizeof(int); if (fread(first,last-first,1,fp)!=1) return 1; CoinBigIndex space = lengthAreaL_ - lengthL_; // Now arrays double *elementU = elementU_.array(); if (CoinFromFile(elementU,lengthAreaU_ , fp, newSize )==1) return 1; assert (newSize==lengthAreaU_); int * indexRowU = indexRowU_.array(); if (CoinFromFile(indexRowU,lengthAreaU_ , fp, newSize )==1) return 1; assert (newSize==lengthAreaU_); int * indexColumnU = indexColumnU_.array(); if (CoinFromFile(indexColumnU,lengthAreaU_ , fp, newSize )==1) return 1; assert (newSize==lengthAreaU_); CoinBigIndex *convertRowToColumnU = convertRowToColumnU_.array(); if (CoinFromFile(convertRowToColumnU,lengthAreaU_ , fp, newSize )==1) return 1; assert (newSize==lengthAreaU_||(newSize==0&&!convertRowToColumnU_.array())); double * elementByRowL = elementByRowL_.array(); if (CoinFromFile(elementByRowL,lengthAreaL_ , fp, newSize )==1) return 1; assert (newSize==lengthAreaL_||(newSize==0&&!elementByRowL_.array())); int * indexColumnL = indexColumnL_.array(); if (CoinFromFile(indexColumnL,lengthAreaL_ , fp, newSize )==1) return 1; assert (newSize==lengthAreaL_||(newSize==0&&!indexColumnL_.array())); CoinBigIndex * startRowL = startRowL_.array(); if (CoinFromFile(startRowL , numberRows_+1, fp, newSize )==1) return 1; assert (newSize==numberRows_+1||(newSize==0&&!startRowL_.array())); double * elementL = elementL_.array(); if (CoinFromFile(elementL,lengthAreaL_ , fp, newSize )==1) return 1; assert (newSize==lengthAreaL_); int * indexRowL = indexRowL_.array(); if (CoinFromFile(indexRowL,lengthAreaL_ , fp, newSize )==1) return 1; assert (newSize==lengthAreaL_); CoinBigIndex * startColumnL = startColumnL_.array(); if (CoinFromFile(startColumnL,numberRows_ + 1 , fp, newSize )==1) return 1; assert (newSize==numberRows_+1); int * markRow = markRow_.array(); if (CoinFromFile(markRow,numberRows_ , fp, newSize )==1) return 1; assert (newSize==numberRows_); int * saveColumn = saveColumn_.array(); if (CoinFromFile(saveColumn,numberColumns_ , fp, newSize )==1) return 1; assert (newSize==numberColumns_); CoinBigIndex * startColumnR = startColumnR_.array(); if (CoinFromFile(startColumnR , maximumPivots_ + 1 , fp, newSize )==1) return 1; assert (newSize==maximumPivots_+1||(newSize==0&&!startColumnR_.array())); CoinBigIndex * startRowU = startRowU_.array(); if (CoinFromFile(startRowU,maximumRowsExtra_ + 1 , fp, newSize )==1) return 1; assert (newSize==maximumRowsExtra_+1||(newSize==0&&!startRowU_.array())); int * numberInRow = numberInRow_.array(); if (CoinFromFile(numberInRow,maximumRowsExtra_ + 1 , fp, newSize )==1) return 1; assert (newSize==maximumRowsExtra_+1); int * nextRow = nextRow_.array(); if (CoinFromFile(nextRow,maximumRowsExtra_ + 1 , fp, newSize )==1) return 1; assert (newSize==maximumRowsExtra_+1); int * lastRow = lastRow_.array(); if (CoinFromFile(lastRow,maximumRowsExtra_ + 1 , fp, newSize )==1) return 1; assert (newSize==maximumRowsExtra_+1); double * pivotRegion = pivotRegion_.array(); if (CoinFromFile(pivotRegion,maximumRowsExtra_ + 1 , fp, newSize )==1) return 1; assert (newSize==maximumRowsExtra_+1); int * permuteBack = permuteBack_.array(); if (CoinFromFile(permuteBack,maximumRowsExtra_ + 1 , fp, newSize )==1) return 1; assert (newSize==maximumRowsExtra_+1||(newSize==0&&!permuteBack_.array())); int * permute = permute_.array(); if (CoinFromFile(permute,maximumRowsExtra_ + 1 , fp, newSize )==1) return 1; assert (newSize==maximumRowsExtra_+1||(newSize==0&&!permute_.array())); int * pivotColumnBack = pivotColumnBack_.array(); if (CoinFromFile(pivotColumnBack,maximumRowsExtra_ + 1 , fp, newSize )==1) return 1; assert (newSize==maximumRowsExtra_+1||(newSize==0&&!pivotColumnBack_.array())); CoinBigIndex * startColumnU = startColumnU_.array(); if (CoinFromFile(startColumnU,maximumColumnsExtra_ + 1 , fp, newSize )==1) return 1; assert (newSize==maximumColumnsExtra_+1); int * numberInColumn = numberInColumn_.array(); if (CoinFromFile(numberInColumn,maximumColumnsExtra_ + 1 , fp, newSize )==1) return 1; assert (newSize==maximumColumnsExtra_+1); int * numberInColumnPlus = numberInColumnPlus_.array(); if (CoinFromFile(numberInColumnPlus,maximumColumnsExtra_ + 1 , fp, newSize )==1) return 1; assert (newSize==maximumColumnsExtra_+1); int *firstCount = firstCount_.array(); if (CoinFromFile(firstCount,biggerDimension_ + 2 , fp, newSize )==1) return 1; assert (newSize==biggerDimension_+2); int *nextCount = nextCount_.array(); if (CoinFromFile(nextCount,numberRows_ + numberColumns_ , fp, newSize )==1) return 1; assert (newSize==numberRows_+numberColumns_); int *lastCount = lastCount_.array(); if (CoinFromFile(lastCount,numberRows_ + numberColumns_ , fp, newSize )==1) return 1; assert (newSize==numberRows_+numberColumns_); int * pivotRowL = pivotRowL_.array(); if (CoinFromFile(pivotRowL,numberRows_ + 1 , fp, newSize )==1) return 1; assert (newSize==numberRows_+1); int * pivotColumn = pivotColumn_.array(); if (CoinFromFile(pivotColumn,maximumColumnsExtra_ + 1 , fp, newSize )==1) return 1; assert (newSize==maximumColumnsExtra_+1); int * nextColumn = nextColumn_.array(); if (CoinFromFile(nextColumn,maximumColumnsExtra_ + 1 , fp, newSize )==1) return 1; assert (newSize==maximumColumnsExtra_+1); int * lastColumn = lastColumn_.array(); if (CoinFromFile(lastColumn,maximumColumnsExtra_ + 1 , fp, newSize )==1) return 1; assert (newSize==maximumColumnsExtra_+1); if (CoinFromFile(denseArea_ , numberDense_*numberDense_, fp, newSize )==1) return 1; assert (newSize==numberDense_*numberDense_); if (CoinFromFile(densePermute_ , numberDense_, fp, newSize )==1) return 1; assert (newSize==numberDense_); lengthAreaR_ = space; elementR_ = elementL_.array() + lengthL_; indexRowR_ = indexRowL_.array() + lengthL_; fclose(fp); if (factorIt) { if (biasLU_>=3||numberRows_!=numberColumns_) preProcess ( 2 ); else preProcess ( 3 ); // no row copy factor ( ); } } return 0; }