// Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. #include "CoinPragma.hpp" #include #include "ClpCholeskyBase.hpp" #include "ClpInterior.hpp" #include "ClpHelperFunctions.hpp" #include "CoinHelperFunctions.hpp" #include "CoinSort.hpp" #include "ClpCholeskyDense.hpp" #include "ClpMessage.hpp" #include "ClpQuadraticObjective.hpp" //############################################################################# // Constructors / Destructor / Assignment //############################################################################# //------------------------------------------------------------------- // Default Constructor //------------------------------------------------------------------- ClpCholeskyBase::ClpCholeskyBase (int denseThreshold) : type_(0), doKKT_(false), goDense_(0.7), choleskyCondition_(0.0), model_(NULL), numberTrials_(), numberRows_(0), status_(0), rowsDropped_(NULL), permuteInverse_(NULL), permute_(NULL), numberRowsDropped_(0), sparseFactor_(NULL), choleskyStart_(NULL), choleskyRow_(NULL), indexStart_(NULL), diagonal_(NULL), workDouble_(NULL), link_(NULL), workInteger_(NULL), clique_(NULL), sizeFactor_(0), sizeIndex_(0), firstDense_(0), rowCopy_(NULL), whichDense_(NULL), denseColumn_(NULL), dense_(NULL), denseThreshold_(denseThreshold) { memset(integerParameters_,0,64*sizeof(int)); memset(doubleParameters_,0,64*sizeof(double)); } //------------------------------------------------------------------- // Copy constructor //------------------------------------------------------------------- ClpCholeskyBase::ClpCholeskyBase (const ClpCholeskyBase & rhs) : type_(rhs.type_), doKKT_(rhs.doKKT_), goDense_(rhs.goDense_), choleskyCondition_(rhs.choleskyCondition_), model_(rhs.model_), numberTrials_(rhs.numberTrials_), numberRows_(rhs.numberRows_), status_(rhs.status_), numberRowsDropped_(rhs.numberRowsDropped_) { rowsDropped_ = ClpCopyOfArray(rhs.rowsDropped_,numberRows_); permuteInverse_ = ClpCopyOfArray(rhs.permuteInverse_,numberRows_); permute_ = ClpCopyOfArray(rhs.permute_,numberRows_); sizeFactor_=rhs.sizeFactor_; sizeIndex_ = rhs.sizeIndex_; firstDense_ = rhs.firstDense_; sparseFactor_ = ClpCopyOfArray(rhs.sparseFactor_,rhs.sizeFactor_); choleskyStart_ = ClpCopyOfArray(rhs.choleskyStart_,numberRows_+1); indexStart_ = ClpCopyOfArray(rhs.indexStart_,numberRows_); choleskyRow_ = ClpCopyOfArray(rhs.choleskyRow_,sizeIndex_); diagonal_ = ClpCopyOfArray(rhs.diagonal_,numberRows_); #if CLP_LONG_CHOLESKY!=1 workDouble_ = ClpCopyOfArray(rhs.workDouble_,numberRows_); #else // actually long double workDouble_ = (double *) ClpCopyOfArray((longWork *) rhs.workDouble_,numberRows_); #endif link_ = ClpCopyOfArray(rhs.link_,numberRows_); workInteger_ = ClpCopyOfArray(rhs.workInteger_,numberRows_); clique_ = ClpCopyOfArray(rhs.clique_,numberRows_); memcpy(integerParameters_,rhs.integerParameters_,64*sizeof(int)); memcpy(doubleParameters_,rhs.doubleParameters_,64*sizeof(double)); rowCopy_ = rhs.rowCopy_->clone(); whichDense_ = NULL; denseColumn_=NULL; dense_=NULL; denseThreshold_ = rhs.denseThreshold_; } //------------------------------------------------------------------- // Destructor //------------------------------------------------------------------- ClpCholeskyBase::~ClpCholeskyBase () { delete [] rowsDropped_; delete [] permuteInverse_; delete [] permute_; delete [] sparseFactor_; delete [] choleskyStart_; delete [] choleskyRow_; delete [] indexStart_; delete [] diagonal_; delete [] workDouble_; delete [] link_; delete [] workInteger_; delete [] clique_; delete rowCopy_; delete [] whichDense_; delete [] denseColumn_; delete dense_; } //---------------------------------------------------------------- // Assignment operator //------------------------------------------------------------------- ClpCholeskyBase & ClpCholeskyBase::operator=(const ClpCholeskyBase& rhs) { if (this != &rhs) { type_ = rhs.type_; doKKT_ = rhs.doKKT_; goDense_ = rhs.goDense_; choleskyCondition_ = rhs.choleskyCondition_; model_ = rhs.model_; numberTrials_ = rhs.numberTrials_; numberRows_ = rhs.numberRows_; status_ = rhs.status_; numberRowsDropped_ = rhs.numberRowsDropped_; delete [] rowsDropped_; delete [] permuteInverse_; delete [] permute_; delete [] sparseFactor_; delete [] choleskyStart_; delete [] choleskyRow_; delete [] indexStart_; delete [] diagonal_; delete [] workDouble_; delete [] link_; delete [] workInteger_; delete [] clique_; delete rowCopy_; delete [] whichDense_; delete [] denseColumn_; delete dense_; rowsDropped_ = ClpCopyOfArray(rhs.rowsDropped_,numberRows_); permuteInverse_ = ClpCopyOfArray(rhs.permuteInverse_,numberRows_); permute_ = ClpCopyOfArray(rhs.permute_,numberRows_); sizeFactor_=rhs.sizeFactor_; sizeIndex_ = rhs.sizeIndex_; firstDense_ = rhs.firstDense_; sparseFactor_ = ClpCopyOfArray(rhs.sparseFactor_,rhs.sizeFactor_); choleskyStart_ = ClpCopyOfArray(rhs.choleskyStart_,numberRows_+1); choleskyRow_ = ClpCopyOfArray(rhs.choleskyRow_,rhs.sizeFactor_); indexStart_ = ClpCopyOfArray(rhs.indexStart_,numberRows_); choleskyRow_ = ClpCopyOfArray(rhs.choleskyRow_,sizeIndex_); diagonal_ = ClpCopyOfArray(rhs.diagonal_,numberRows_); #if CLP_LONG_CHOLESKY!=1 workDouble_ = ClpCopyOfArray(rhs.workDouble_,numberRows_); #else // actually long double workDouble_ = (double *) ClpCopyOfArray((longWork *) rhs.workDouble_,numberRows_); #endif link_ = ClpCopyOfArray(rhs.link_,numberRows_); workInteger_ = ClpCopyOfArray(rhs.workInteger_,numberRows_); clique_ = ClpCopyOfArray(rhs.clique_,numberRows_); delete rowCopy_; rowCopy_ = rhs.rowCopy_->clone(); whichDense_ = NULL; denseColumn_=NULL; dense_=NULL; denseThreshold_ = rhs.denseThreshold_; } return *this; } // reset numberRowsDropped and rowsDropped. void ClpCholeskyBase::resetRowsDropped() { numberRowsDropped_=0; memset(rowsDropped_,0,numberRows_); } /* Uses factorization to solve. - given as if KKT. region1 is rows+columns, region2 is rows */ void ClpCholeskyBase::solveKKT (double * region1, double * region2, const double * diagonal, double diagonalScaleFactor) { if (!doKKT_) { int iColumn; int numberColumns = model_->numberColumns(); int numberTotal = numberRows_+numberColumns; double * region1Save = new double[numberTotal]; for (iColumn=0;iColumnclpMatrix()->times(1.0,region1,region2); double maximumRHS = maximumAbsElement(region2,numberRows_); double scale=1.0; double unscale=1.0; if (maximumRHS>1.0e-30) { if (maximumRHS<=0.5) { double factor=2.0; while (maximumRHS<=0.5) { maximumRHS*=factor; scale*=factor; } /* endwhile */ } else if (maximumRHS>=2.0&&maximumRHS<=COIN_DBL_MAX) { double factor=0.5; while (maximumRHS>=2.0) { maximumRHS*=factor; scale*=factor; } /* endwhile */ } unscale=diagonalScaleFactor/scale; } else { //effectively zero scale=0.0; unscale=0.0; } multiplyAdd(NULL,numberRows_,0.0,region2,scale); solve(region2); multiplyAdd(NULL,numberRows_,0.0,region2,unscale); multiplyAdd(region2,numberRows_,-1.0,region1+numberColumns,0.0); CoinZeroN(region1,numberColumns); model_->clpMatrix()->transposeTimes(1.0,region2,region1); for (iColumn=0;iColumnnumberRows(); int numberColumns = model_->numberColumns(); int numberTotal = numberColumns + numberRowsModel; double * array = new double [numberRows_]; CoinMemcpyN(region1,numberTotal,array); CoinMemcpyN(region2,numberRowsModel,array+numberTotal); assert (numberRows_>=numberRowsModel+numberTotal); solve(array); int iRow; for (iRow=0;iRow1.0e-8) { printf("row region1 %d dropped %g\n",iRow,array[iRow]); } } for (;iRow1.0e-8) { printf("row region2 %d dropped %g\n",iRow,array[iRow]); } } CoinMemcpyN(array+numberTotal,numberRowsModel,region2); CoinMemcpyN(array,numberTotal,region1); delete [] array; } } //------------------------------------------------------------------- // Clone //------------------------------------------------------------------- ClpCholeskyBase * ClpCholeskyBase::clone() const { return new ClpCholeskyBase(*this); } // Forms ADAT - returns nonzero if not enough memory int ClpCholeskyBase::preOrder(bool lowerTriangular, bool includeDiagonal, bool doKKT) { delete rowCopy_; rowCopy_ = model_->clpMatrix()->reverseOrderedCopy(); if (!doKKT) { numberRows_ = model_->numberRows(); rowsDropped_ = new char [numberRows_]; memset(rowsDropped_,0,numberRows_); numberRowsDropped_=0; // Space for starts choleskyStart_ = new CoinBigIndex[numberRows_+1]; const CoinBigIndex * columnStart = model_->clpMatrix()->getVectorStarts(); const int * columnLength = model_->clpMatrix()->getVectorLengths(); const int * row = model_->clpMatrix()->getIndices(); const CoinBigIndex * rowStart = rowCopy_->getVectorStarts(); const int * rowLength = rowCopy_->getVectorLengths(); const int * column = rowCopy_->getIndices(); // We need two arrays for counts int * which = new int [numberRows_]; int * used = new int[numberRows_+1]; CoinZeroN(used,numberRows_); int iRow; sizeFactor_=0; int numberColumns = model_->numberColumns(); int numberDense=0; //denseThreshold_=3; if (denseThreshold_>0) { delete [] whichDense_; delete [] denseColumn_; delete dense_; whichDense_ = new char[numberColumns]; int iColumn; used[numberRows_]=0; for (iColumn=0;iColumn=stop;iRow--) { if (used[iRow]) printf("%d columns are of length %d\n",used[iRow],iRow); nLong += used[iRow]; if (nLong>50||nLong>(numberColumns>>2)) break; } CoinZeroN(used,numberRows_); for (iColumn=0;iColumn100) { // free delete [] whichDense_; whichDense_=NULL; denseColumn_=NULL; dense_=NULL; } else { // space for dense columns denseColumn_ = new longDouble [numberDense*numberRows_]; // dense cholesky dense_ = new ClpCholeskyDense(); dense_->reserveSpace(NULL,numberDense); printf("Taking %d columns as dense\n",numberDense); } } int offset = includeDiagonal ? 0 : 1; if (lowerTriangular) offset=-offset; for (iRow=0;iRow=iRow+offset) { if (!used[jRow]) { used[jRow]=1; which[number++]=jRow; } } } } } } sizeFactor_ += number; int j; for (j=0;j=iRow+offset) { if (!used[jRow]) { used[jRow]=1; which[number++]=jRow; } } } } } } sizeFactor_ += number; int j; for (j=0;jnumberRows(); int numberColumns = model_->numberColumns(); int numberTotal = numberColumns + numberRowsModel; numberRows_ = 2*numberRowsModel+numberColumns; rowsDropped_ = new char [numberRows_]; memset(rowsDropped_,0,numberRows_); numberRowsDropped_=0; CoinPackedMatrix * quadratic = NULL; ClpQuadraticObjective * quadraticObj = (dynamic_cast< ClpQuadraticObjective*>(model_->objectiveAsObject())); if (quadraticObj) quadratic = quadraticObj->quadraticObjective(); int numberElements = model_->clpMatrix()->getNumElements(); numberElements = numberElements+2*numberRowsModel+numberTotal; if (quadratic) numberElements += quadratic->getNumElements(); // Space for starts choleskyStart_ = new CoinBigIndex[numberRows_+1]; const CoinBigIndex * columnStart = model_->clpMatrix()->getVectorStarts(); const int * columnLength = model_->clpMatrix()->getVectorLengths(); const int * row = model_->clpMatrix()->getIndices(); //const double * element = model_->clpMatrix()->getElements(); // Now we have size - create arrays and fill in try { choleskyRow_ = new int [numberElements]; } catch (...) { // no memory delete [] choleskyStart_; choleskyStart_=NULL; return -1; } int iRow,iColumn; sizeFactor_=0; // matrix if (lowerTriangular) { if (!quadratic) { for (iColumn=0;iColumngetIndices(); const CoinBigIndex * columnQuadraticStart = quadratic->getVectorStarts(); const int * columnQuadraticLength = quadratic->getVectorLengths(); //const double * quadraticElement = quadratic->getElements(); for (iColumn=0;iColumniColumn) choleskyRow_[sizeFactor_++]=jColumn; } CoinBigIndex start=columnStart[iColumn]; CoinBigIndex end=columnStart[iColumn]+columnLength[iColumn]; for ( j=start;jclpMatrix()->reverseOrderedCopy(); const CoinBigIndex * rowStart = rowCopy->getVectorStarts(); const int * rowLength = rowCopy->getVectorLengths(); const int * column = rowCopy->getIndices(); if (!quadratic) { for (iColumn=0;iColumnnumberRows(); int numberColumns = model_->numberColumns(); int numberTotal = numberColumns + numberRowsModel; CoinPackedMatrix * quadratic = NULL; ClpQuadraticObjective * quadraticObj = (dynamic_cast< ClpQuadraticObjective*>(model_->objectiveAsObject())); if (quadraticObj) quadratic = quadraticObj->quadraticObjective(); if (!doKKT_) { numberRows_ = model->numberRows(); } else { numberRows_ = 2*numberRowsModel+numberColumns; } rowsDropped_ = new char [numberRows_]; numberRowsDropped_=0; rowCopy_ = model->clpMatrix()->reverseOrderedCopy(); const CoinBigIndex * columnStart = model_->clpMatrix()->getVectorStarts(); const int * columnLength = model_->clpMatrix()->getVectorLengths(); const int * row = model_->clpMatrix()->getIndices(); const CoinBigIndex * rowStart = rowCopy_->getVectorStarts(); const int * rowLength = rowCopy_->getVectorLengths(); const int * column = rowCopy_->getIndices(); // We need arrays for counts int * which = new int [numberRows_]; int * used = new int[numberRows_+1]; int * count = new int[numberRows_]; CoinZeroN(count,numberRows_); CoinZeroN(used,numberRows_); int iRow; sizeFactor_=0; permute_ = new int[numberRows_]; for (iRow=0;iRow0) { delete [] whichDense_; delete [] denseColumn_; delete dense_; whichDense_ = new char[numberColumns]; int iColumn; used[numberRows_]=0; for (iColumn=0;iColumn=stop;iRow--) { if (used[iRow]) printf("%d columns are of length %d\n",used[iRow],iRow); nLong += used[iRow]; if (nLong>50||nLong>(numberColumns>>2)) break; } CoinZeroN(used,numberRows_); for (iColumn=0;iColumn100) { // free delete [] whichDense_; whichDense_=NULL; denseColumn_=NULL; dense_=NULL; } else { // space for dense columns denseColumn_ = new longDouble [numberDense*numberRows_]; // dense cholesky dense_ = new ClpCholeskyDense(); dense_->reserveSpace(NULL,numberDense); printf("Taking %d columns as dense\n",numberDense); } } /* Get row counts and size */ for (iRow=0;iRowclpMatrix()->getNumElements(); numberElements = numberElements+2*numberRowsModel+numberTotal; if (quadratic) numberElements += quadratic->getNumElements(); // off diagonal numberElements -= numberRows_; sizeFactor_=numberElements; // If we sort we need to redo symbolic etc } delete [] which; delete [] used; delete [] count; permuteInverse_ = new int [numberRows_]; memset(rowsDropped_,0,numberRows_); for (iRow=0;iRowclpMatrix()->getVectorStarts(); const int * columnLength = model_->clpMatrix()->getVectorLengths(); const int * row = model_->clpMatrix()->getIndices(); const CoinBigIndex * rowStart = rowCopy_->getVectorStarts(); const int * rowLength = rowCopy_->getVectorLengths(); const int * column = rowCopy_->getIndices(); int numberRowsModel = model_->numberRows(); int numberColumns = model_->numberColumns(); int numberTotal = numberColumns + numberRowsModel; CoinPackedMatrix * quadratic = NULL; ClpQuadraticObjective * quadraticObj = (dynamic_cast< ClpQuadraticObjective*>(model_->objectiveAsObject())); if (quadraticObj) quadratic = quadraticObj->quadraticObjective(); // We need an array for counts int * used = new int[numberRows_+1]; // If KKT then re-order so negative first if (doKKT_) { int nn=0; int np=0; int iRow; for (iRow=0;iRowclpMatrix()->reverseOrderedCopy(); const CoinBigIndex * rowStart = rowCopy->getVectorStarts(); const int * rowLength = rowCopy->getVectorLengths(); const int * column = rowCopy->getIndices(); // temp bool permuted=false; for (iRow=0;iRowiRow&&!rowsDropped_[jRow]) { if (!used[jNewRow]) { used[jNewRow]=1; which[number++]=jNewRow; } } } } } sizeFactor_ += number; int j; for (j=0;jiRow) Arow[sizeFactor_++]=kRow; } } else if (iOriginalRowiRow) Arow[sizeFactor_++]=kRow; } else { int kRow = iOriginalRow-numberTotal; CoinBigIndex start=rowStart[kRow]; CoinBigIndex end=rowStart[kRow]+rowLength[kRow]; for (CoinBigIndex j=start;jiRow) Arow[sizeFactor_++]=jNewRow; } // slack - should it be permute kRow = permuteInverse_[kRow+numberColumns]; if (kRow>iRow) Arow[sizeFactor_++]=kRow; } // Sort std::sort(Arow+Astart[iRow],Arow+sizeFactor_); } } else { // quadratic const int * columnQuadratic = quadratic->getIndices(); const CoinBigIndex * columnQuadraticStart = quadratic->getVectorStarts(); const int * columnQuadraticLength = quadratic->getVectorLengths(); for (iRow=0;iRowiRow) Arow[sizeFactor_++]=jNewColumn; } iColumn=iOriginalRow; CoinBigIndex start=columnStart[iColumn]; CoinBigIndex end=columnStart[iColumn]+columnLength[iColumn]; for (j=start;jiRow) Arow[sizeFactor_++]=kRow; } } else if (iOriginalRowiRow) Arow[sizeFactor_++]=kRow; } else { int kRow = iOriginalRow-numberTotal; CoinBigIndex start=rowStart[kRow]; CoinBigIndex end=rowStart[kRow]+rowLength[kRow]; for (CoinBigIndex j=start;jiRow) Arow[sizeFactor_++]=jNewRow; } // slack - should it be permute kRow = permuteInverse_[kRow+numberColumns]; if (kRow>iRow) Arow[sizeFactor_++]=kRow; } // Sort std::sort(Arow+Astart[iRow],Arow+sizeFactor_); } } } else { if (!quadratic) { for (iColumn=0;iColumngetIndices(); const CoinBigIndex * columnQuadraticStart = quadratic->getVectorStarts(); const int * columnQuadraticLength = quadratic->getVectorLengths(); //const double * quadraticElement = quadratic->getElements(); for (iColumn=0;iColumniColumn) Arow[sizeFactor_++]=jColumn; } CoinBigIndex start=columnStart[iColumn]; CoinBigIndex end=columnStart[iColumn]+columnLength[iColumn]; for ( j=start;jmessageHandler()->logLevel()>0) std::cout<=0&&mergeLink[merge]<0) { // can re-use all startSub = indexStart_[merge]+1; nz=choleskyStart_[merge+1]-(choleskyStart_[merge]+1); reuse=true; } else { // See if we can re-use any int k=mergeLink[iRow]; int maxLength=0; while (k>=0) { int length = choleskyStart_[k+1]-(choleskyStart_[k]+1); int start = indexStart_[k]+1; int stop = start+length; if (length>maxLength) { maxLength = length; startSub = start; } int linked = iRow; for (CoinBigIndex j=start;j1) { int kRow = choleskyRow_[startSub]; mergeLink[iRow]=mergeLink[kRow]; mergeLink[kRow]=iRow; } // should not be needed //std::sort(choleskyRow_+indexStart_[iRow] // ,choleskyRow_+indexStart_[iRow]+nz); //#define CLP_DEBUG #ifdef CLP_DEBUG int last=-1; for ( j=indexStart_[iRow];jlast); last=kRow; } #endif } sizeFactor_ = choleskyStart_[numberRows_]; sizeIndex_ = start; // find dense segment here int numberleft=numberRows_; for (iRow=0;iRow= threshold) break; numberleft--; } //iRow=numberRows_; int nDense = numberRows_-iRow; #define DENSE_THRESHOLD 8 // don't do if dense columns if (nDense>=DENSE_THRESHOLD&&!dense_) { printf("Going dense for last %d rows\n",nDense); // make sure we don't disturb any indices CoinBigIndex k=0; for (int jRow=0;jRownumberRows(); int numberColumns = model_->numberColumns(); int numberTotal = numberColumns + numberRowsModel; for (iRow=firstDense_;iRowclpMatrix()->getVectorStarts(); const int * columnLength = model_->clpMatrix()->getVectorLengths(); const int * row = model_->clpMatrix()->getIndices(); const double * element = model_->clpMatrix()->getElements(); const CoinBigIndex * rowStart = rowCopy_->getVectorStarts(); const int * rowLength = rowCopy_->getVectorLengths(); const int * column = rowCopy_->getIndices(); const double * elementByRow = rowCopy_->getElements(); int numberColumns=model_->clpMatrix()->getNumCols(); //perturbation longDouble perturbation=model_->diagonalPerturbation()*model_->diagonalNorm(); //perturbation=perturbation*perturbation*100000000.0; if (perturbation>1.0) { #ifdef COIN_DEVELOP //if (model_->model()->logLevel()&4) std::cout <<"large perturbation "<numberRows(); if (whichDense_) { longDouble * denseDiagonal = dense_->diagonal(); longDouble * dense = denseColumn_; int iDense=0; for (int iColumn=0;iColumndelta(); // add delta*delta to diagonal delta2 *= delta2; // largest in initial matrix double largest2=1.0e-20; for (iRow=0;iRow=iRow&&!rowsDropped_[jRow]) { longDouble value=element[j]*multiplier; work[jNewRow] += value; } } } } diagonal_[iRow]=work[iRow]; largest2 = CoinMax(largest2,fabs(work[iRow])); work[iRow]=0.0; int j; for (j=0;jlargest2) { diagonal_[iRow]=diagonal+perturbation; } else { diagonal_[iRow]=diagonal+perturbation; rowsDropped[iRow]=2; numberDroppedBefore++; //printf("dropped - small diagonal %g\n",diagonal); } } } doubleParameters_[10]=CoinMax(1.0e-20,largest); integerParameters_[20]=0; doubleParameters_[3]=0.0; doubleParameters_[4]=COIN_DBL_MAX; integerParameters_[34]=0; // say all must be positive factorizePart2(rowsDropped); newDropped=integerParameters_[20]+numberDroppedBefore; largest=doubleParameters_[3]; smallest=doubleParameters_[4]; if (model_->messageHandler()->logLevel()>1) std::cout<<"Cholesky - largest "<=0.0); diagonal_[i]=sqrt(diagonal_[i]); } // Update dense columns (just L) // Zero out dropped rows for (i=0;iresetRowsDropped(); longDouble * denseBlob = dense_->aMatrix(); longDouble * denseDiagonal = dense_->diagonal(); // Update dense matrix for (i=0;ifactorizePart2(dropped); delete [] dropped; } // try allowing all every time //printf("trying ?\n"); //for (iRow=0;iRownumberIterations()<20||(model_->numberIterations()&1)==0) if (model_->numberIterations()<2000) cleanCholesky=true; else cleanCholesky=false; if (cleanCholesky) { //drop fresh makes some formADAT easier if (newDropped||numberRowsDropped_) { newDropped=0; for (int i=0;i(model_->objectiveAsObject())); if (quadraticObj) quadratic = quadraticObj->quadraticObjective(); // matrix int numberRowsModel = model_->numberRows(); int numberColumns = model_->numberColumns(); int numberTotal = numberColumns + numberRowsModel; // temp bool permuted=false; for (iRow=0;iRowdelta(); // add delta*delta to bottom delta2 *= delta2; // Need to permute - ugly if (!quadratic) { for (iRow=0;iRow1.0e-100) { value = 1.0/value; largest = CoinMax(largest,fabs(value)); diagonal_[iRow] = -value; CoinBigIndex start=columnStart[iColumn]; CoinBigIndex end=columnStart[iColumn]+columnLength[iColumn]; for (CoinBigIndex j=start;jiRow) { work[kRow]=element[j]; largest = CoinMax(largest,fabs(element[j])); } } } else { diagonal_[iRow] = -value; } } else if (iOriginalRow1.0e-100) { value = 1.0/value; largest = CoinMax(largest,fabs(value)); } else { value = 1.0e100; } diagonal_[iRow] = -value; int kRow = permuteInverse_[iOriginalRow+numberRowsModel]; if (kRow>iRow) work[kRow]=-1.0; } else { diagonal_[iRow]=delta2; int kRow = iOriginalRow-numberTotal; CoinBigIndex start=rowStart[kRow]; CoinBigIndex end=rowStart[kRow]+rowLength[kRow]; for (CoinBigIndex j=start;jiRow) { work[jNewRow]=elementByRow[j]; largest = CoinMax(largest,fabs(elementByRow[j])); } } // slack - should it be permute kRow = permuteInverse_[kRow+numberColumns]; if (kRow>iRow) work[kRow]=-1.0; } CoinBigIndex j; int number = choleskyStart_[iRow+1]-choleskyStart_[iRow]; for (j=0;jgetIndices(); const CoinBigIndex * columnQuadraticStart = quadratic->getVectorStarts(); const int * columnQuadraticLength = quadratic->getVectorLengths(); const double * quadraticElement = quadratic->getElements(); for (iRow=0;iRow1.0e-100) { value = 1.0/value; for (j=columnQuadraticStart[iColumn]; jiRow) { work[jNewColumn]=-quadraticElement[j]; } else if (iColumn==jColumn) { value += quadraticElement[j]; } } largest = CoinMax(largest,fabs(value)); diagonal_[iRow] = -value; CoinBigIndex start=columnStart[iColumn]; CoinBigIndex end=columnStart[iColumn]+columnLength[iColumn]; for (j=start;jiRow) { work[kRow]=element[j]; largest = CoinMax(largest,fabs(element[j])); } } } else { diagonal_[iRow] = -value; } } else if (iOriginalRow1.0e-100) { value = 1.0/value; largest = CoinMax(largest,fabs(value)); } else { value = 1.0e100; } diagonal_[iRow] = -value; int kRow = permuteInverse_[iOriginalRow+numberRowsModel]; if (kRow>iRow) work[kRow]=-1.0; } else { diagonal_[iRow]=delta2; int kRow = iOriginalRow-numberTotal; CoinBigIndex start=rowStart[kRow]; CoinBigIndex end=rowStart[kRow]+rowLength[kRow]; for (CoinBigIndex j=start;jiRow) { work[jNewRow]=elementByRow[j]; largest = CoinMax(largest,fabs(elementByRow[j])); } } // slack - should it be permute kRow = permuteInverse_[kRow+numberColumns]; if (kRow>iRow) work[kRow]=-1.0; } CoinBigIndex j; int number = choleskyStart_[iRow+1]-choleskyStart_[iRow]; for (j=0;j1.0e-100) { value = 1.0/value; largest = CoinMax(largest,fabs(value)); diagonal_[iColumn] = -value; CoinBigIndex start=columnStart[iColumn]; CoinBigIndex end=columnStart[iColumn]+columnLength[iColumn]; for (CoinBigIndex j=start;jgetIndices(); const CoinBigIndex * columnQuadraticStart = quadratic->getVectorStarts(); const int * columnQuadraticLength = quadratic->getVectorLengths(); const double * quadraticElement = quadratic->getElements(); for (iColumn=0;iColumn1.0e-100) { value = 1.0/value; for (j=columnQuadraticStart[iColumn]; jiColumn) { work[jColumn]=-quadraticElement[j]; } else if (iColumn==jColumn) { value += quadraticElement[j]; } } largest = CoinMax(largest,fabs(value)); diagonal_[iColumn] = -value; CoinBigIndex start=columnStart[iColumn]; CoinBigIndex end=columnStart[iColumn]+columnLength[iColumn]; for (j=start;j1.0e-100) { value = 1.0/value; largest = CoinMax(largest,fabs(value)); } else { value = 1.0e100; } diagonal_[iColumn] = -value; work[iColumn-numberColumns+numberTotal]=-1.0; CoinBigIndex j; int number = choleskyStart_[iColumn+1]-choleskyStart_[iColumn]; for (j=0;jdelta(); // add delta*delta to bottom delta2 *= delta2; for (iRow=0;iRowmessageHandler()->logLevel()>1) std::cout<<"Cholesky - largest "<primalR(); double * dualR = model_->dualR(); for (iRow=0;iRow0) { // this is in a clique inClique=true; if (clique_[iRow]>lastClique) { // new Clique newClique=true; // If we have clique going then signal to do old one endClique=(lastClique>0); } else { // Still in clique newClique=false; } } else { // not in clique inClique=false; newClique=false; // If we have clique going then signal to do old one endClique=(lastClique>0); } lastClique=clique_[iRow]; } else if (inClique) { // Finish off endClique=true; } else { break; } if (endClique) { // We have just finished updating a clique - do block pivot and clean up int jRow; for ( jRow=lastRow;jRow=dropValue) { smallest = CoinMin(smallest,diagonalValue); largest = CoinMax(largest,diagonalValue); d[jRow]=diagonalValue; diagonalValue = 1.0/diagonalValue; } else { rowsDropped[originalRow]=2; d[jRow]=1.0e100; diagonalValue=0.0; integerParameters_[20]++; } } diagonal_[jRow]=diagonalValue; for (CoinBigIndex j=start;j=0) { for ( jRow=lastRow;jRow=dropValue) { smallest = CoinMin(smallest,diagonalValue); largest = CoinMax(largest,diagonalValue); d[iRow]=diagonalValue; diagonalValue = 1.0/diagonalValue; } else { rowsDropped[originalRow]=2; d[iRow]=1.0e100; diagonalValue=0.0; integerParameters_[20]++; } } diagonal_[iRow]=diagonalValue; CoinBigIndex offset = indexStart_[iRow]-choleskyStart_[iRow]; CoinBigIndex start = choleskyStart_[iRow]; CoinBigIndex end = choleskyStart_[iRow+1]; assert (first[iRow]==start); if (start=firstPositive) { firstPositive=iRow-firstDense_; break; } } } dense.reserveSpace(this,nDense); int * dropped = new int[nDense]; memset(dropped,0,nDense*sizeof(int)); dense.setDoubleParameter(3,largest); dense.setDoubleParameter(4,smallest); dense.setDoubleParameter(10,dropValue); dense.setIntegerParameter(20,0); dense.setIntegerParameter(34,firstPositive); dense.factorizePart2(dropped); largest=dense.getDoubleParameter(3); smallest=dense.getDoubleParameter(4); integerParameters_[20]+=dense.getIntegerParameter(20); for (iRow=firstDense_;iRow=firstDense_); longDouble a_ik=sparseFactor_[k]; longDouble value1=dValue*a_ik; diagonal_[kRow] -= value1*a_ik; CoinBigIndex base = choleskyStart_[kRow]-kRow-1; for (CoinBigIndex j=k+1;j=firstDense_); longDouble a_ik0=sparseFactor_[k]; longDouble value0=dValue0*a_ik0; longDouble a_ik1=sparseFactor_[k+offset1]; longDouble value1=dValue1*a_ik1; diagonal_[kRow] -= value0*a_ik0 + value1*a_ik1; CoinBigIndex base = choleskyStart_[kRow]-kRow-1; for (CoinBigIndex j=k+1;j=firstDense_); double diagonalValue=diagonal_[kRow]; longDouble a_ik0=sparseFactor_[k]; longDouble value0=dValue0*a_ik0; longDouble a_ik1=sparseFactor_[k+offset1]; longDouble value1=dValue1*a_ik1; longDouble a_ik2=sparseFactor_[k+offset2]; longDouble value2=dValue2*a_ik2; CoinBigIndex base = choleskyStart_[kRow]-kRow-1; diagonal_[kRow] = diagonalValue - value0*a_ik0 - value1*a_ik1 - value2*a_ik2; for (CoinBigIndex j=k+1;j