#ifdef UFL_BARRIER // Copyright (C) 2004, International Business Machines // Corporation and others. All Rights Reserved. #include "CoinPragma.hpp" #include "ClpCholeskyUfl.hpp" #include "ClpMessage.hpp" #include "ClpInterior.hpp" #include "CoinHelperFunctions.hpp" #include "ClpHelperFunctions.hpp" //############################################################################# // Constructors / Destructor / Assignment //############################################################################# //------------------------------------------------------------------- // Default Constructor //------------------------------------------------------------------- ClpCholeskyUfl::ClpCholeskyUfl (int denseThreshold) : ClpCholeskyBase(denseThreshold) { type_=14; #ifdef CLP_USE_CHOLMOD L_= NULL; cholmod_start (&c_) ; // Can't use supernodal as may not be positive definite c_.supernodal=0; #endif } //------------------------------------------------------------------- // Copy constructor //------------------------------------------------------------------- ClpCholeskyUfl::ClpCholeskyUfl (const ClpCholeskyUfl & rhs) : ClpCholeskyBase(rhs) { abort(); } //------------------------------------------------------------------- // Destructor //------------------------------------------------------------------- ClpCholeskyUfl::~ClpCholeskyUfl () { #ifdef CLP_USE_CHOLMOD cholmod_free_factor (&L_, &c_) ; cholmod_finish (&c_) ; #endif } //---------------------------------------------------------------- // Assignment operator //------------------------------------------------------------------- ClpCholeskyUfl & ClpCholeskyUfl::operator=(const ClpCholeskyUfl& rhs) { if (this != &rhs) { ClpCholeskyBase::operator=(rhs); abort(); } return *this; } //------------------------------------------------------------------- // Clone //------------------------------------------------------------------- ClpCholeskyBase * ClpCholeskyUfl::clone() const { return new ClpCholeskyUfl(*this); } #ifndef CLP_USE_CHOLMOD /* Orders rows and saves pointer to matrix.and model */ int ClpCholeskyUfl::order(ClpInterior * model) { int iRow; model_=model; if (preOrder(false,true,doKKT_)) return -1; permuteInverse_ = new int [numberRows_]; permute_ = new int[numberRows_]; double Control[AMD_CONTROL]; double Info[AMD_INFO]; amd_defaults(Control); //amd_control(Control); int returnCode = amd_order(numberRows_,choleskyStart_,choleskyRow_, permute_,Control, Info); delete [] choleskyRow_; choleskyRow_=NULL; delete [] choleskyStart_; choleskyStart_=NULL; //amd_info(Info); if (returnCode!=AMD_OK) { std::cout<<"AMD ordering failed"<numberRows(); if (doKKT_) { numberRows_ += numberRows_ + model->numberColumns(); printf("finish coding UFL KKT!\n"); abort(); } rowsDropped_ = new char [numberRows_]; memset(rowsDropped_,0,numberRows_); numberRowsDropped_=0; model_=model; rowCopy_ = model->clpMatrix()->reverseOrderedCopy(); // 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; for (iRow=0;iRow=iRow&&!rowsDropped_[jRow]) { if (!used[jRow]) { used[jRow]=1; which[number++]=jRow; } } } } sizeFactor_ += number; int j; for (j=0;j=iRow&&!rowsDropped_[jRow]) { if (!used[jRow]) { used[jRow]=1; which[number++]=jRow; } } } } sizeFactor_ += number; int j; for (j=0;jclpMatrix()->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(); int iRow; double * work = new double[numberRows_]; CoinZeroN(work,numberRows_); const double * diagonalSlack = diagonal + numberColumns; int newDropped=0; double largest; //double smallest; //perturbation double perturbation=model_->diagonalPerturbation()*model_->diagonalNorm(); perturbation=0.0; perturbation=perturbation*perturbation; if (perturbation>1.0) { #ifdef COIN_DEVELOP //if (model_->model()->logLevel()&4) std::cout <<"large perturbation "<delta(); // add delta*delta to diagonal delta2 *= delta2; for (iRow=0;iRow=iRow&&!rowsDropped_[jRow]) { double value=element[j]*multiplier; work[jRow] += value; } } } } int j; for (j=0;jlargest2) { sparseFactor_[start]=CoinMax(diagonal,1.0e-10); } else { sparseFactor_[start]=CoinMax(diagonal,1.0e-10); rowsDropped[iRow]=2; numberDroppedBefore++; } } } delete [] work; cholmod_sparse A ; A.nrow=numberRows_; A.ncol=numberRows_; A.nzmax=choleskyStart_[numberRows_]; A.p = choleskyStart_; A.i = choleskyRow_; A.x=sparseFactor_; A.stype=-1; A.itype=CHOLMOD_INT; A.xtype=CHOLMOD_REAL; A.dtype=CHOLMOD_DOUBLE; A.sorted=1; A.packed=1; cholmod_factorize (&A, L_, &c_) ; /* factorize */ choleskyCondition_=1.0; bool cleanCholesky; if (model_->numberIterations()<2000) cleanCholesky=true; else cleanCholesky=false; if (cleanCholesky) { //drop fresh makes some formADAT easier //int oldDropped=numberRowsDropped_; if (newDropped||numberRowsDropped_) { //std::cout <<"Rank "<oldDropped) //std::cout<<" ( "<x); x = cholmod_solve (CHOLMOD_A, L_, b, &c_) ; CoinMemcpyN((double *) x->x,numberRows_,region); cholmod_free_dense (&x, &c_) ; cholmod_free_dense (&b, &c_) ; } #endif #endif