/* Modifies djs to allow for quadratic. returns quadratic offset */ CoinWorkDouble ClpInterior::quadraticDjs(CoinWorkDouble * djRegion, const CoinWorkDouble * solution, CoinWorkDouble scaleFactor) { CoinWorkDouble quadraticOffset = 0.0; #ifndef NO_RTTI ClpQuadraticObjective * quadraticObj = (dynamic_cast< ClpQuadraticObjective*>(objective_)); #else ClpQuadraticObjective * quadraticObj = NULL; if (objective_->type() == 2) quadraticObj = (static_cast< ClpQuadraticObjective*>(objective_)); #endif if (quadraticObj) { CoinPackedMatrix * quadratic = quadraticObj->quadraticObjective(); const int * columnQuadratic = quadratic->getIndices(); const CoinBigIndex * columnQuadraticStart = quadratic->getVectorStarts(); const int * columnQuadraticLength = quadratic->getVectorLengths(); double * quadraticElement = quadratic->getMutableElements(); int numberColumns = quadratic->getNumCols(); for (int iColumn = 0; iColumn < numberColumns; iColumn++) { CoinWorkDouble value = 0.0; for (CoinBigIndex j = columnQuadraticStart[iColumn]; j < columnQuadraticStart[iColumn] + columnQuadraticLength[iColumn]; j++) { int jColumn = columnQuadratic[j]; CoinWorkDouble valueJ = solution[jColumn]; CoinWorkDouble elementValue = quadraticElement[j]; //value += valueI*valueJ*elementValue; value += valueJ * elementValue; quadraticOffset += solution[iColumn] * valueJ * elementValue; } djRegion[iColumn] += scaleFactor * value; } } return quadraticOffset; }
/* Factorize - filling in rowsDropped and returning number dropped */ int ClpCholeskyWssmpKKT::factorize(const double * diagonal, int * rowsDropped) { int numberRowsModel = model_->numberRows(); int numberColumns = model_->numberColumns(); int numberTotal = numberColumns + numberRowsModel; int newDropped = 0; double largest = 0.0; double smallest; //perturbation double perturbation = model_->diagonalPerturbation() * model_->diagonalNorm(); perturbation = perturbation * perturbation; if (perturbation > 1.0) { #ifdef COIN_DEVELOP //if (model_->model()->logLevel()&4) std::cout << "large perturbation " << perturbation << std::endl; #endif perturbation = sqrt(perturbation);; perturbation = 1.0; } // need to recreate every time int iRow, iColumn; const CoinBigIndex * columnStart = model_->clpMatrix()->getVectorStarts(); const int * columnLength = model_->clpMatrix()->getVectorLengths(); const int * row = model_->clpMatrix()->getIndices(); const double * element = model_->clpMatrix()->getElements(); CoinBigIndex numberElements = 0; CoinPackedMatrix * quadratic = NULL; ClpQuadraticObjective * quadraticObj = (dynamic_cast< ClpQuadraticObjective*>(model_->objectiveAsObject())); if (quadraticObj) quadratic = quadraticObj->quadraticObjective(); // matrix if (!quadratic) { for (iColumn = 0; iColumn < numberColumns; iColumn++) { choleskyStart_[iColumn] = numberElements; double value = diagonal[iColumn]; if (fabs(value) > 1.0e-100) { value = 1.0 / value; largest = CoinMax(largest, fabs(value)); sparseFactor_[numberElements] = -value; choleskyRow_[numberElements++] = iColumn; CoinBigIndex start = columnStart[iColumn]; CoinBigIndex end = columnStart[iColumn] + columnLength[iColumn]; for (CoinBigIndex j = start; j < end; j++) { choleskyRow_[numberElements] = row[j] + numberTotal; sparseFactor_[numberElements++] = element[j]; largest = CoinMax(largest, fabs(element[j])); } } else { sparseFactor_[numberElements] = -1.0e100; choleskyRow_[numberElements++] = iColumn; } } } else { // Quadratic const int * columnQuadratic = quadratic->getIndices(); const CoinBigIndex * columnQuadraticStart = quadratic->getVectorStarts(); const int * columnQuadraticLength = quadratic->getVectorLengths(); const double * quadraticElement = quadratic->getElements(); for (iColumn = 0; iColumn < numberColumns; iColumn++) { choleskyStart_[iColumn] = numberElements; CoinBigIndex savePosition = numberElements; choleskyRow_[numberElements++] = iColumn; double value = diagonal[iColumn]; if (fabs(value) > 1.0e-100) { value = 1.0 / value; for (CoinBigIndex j = columnQuadraticStart[iColumn]; j < columnQuadraticStart[iColumn] + columnQuadraticLength[iColumn]; j++) { int jColumn = columnQuadratic[j]; if (jColumn > iColumn) { sparseFactor_[numberElements] = -quadraticElement[j]; choleskyRow_[numberElements++] = jColumn; } else if (iColumn == jColumn) { value += quadraticElement[j]; } } largest = CoinMax(largest, fabs(value)); sparseFactor_[savePosition] = -value; CoinBigIndex start = columnStart[iColumn]; CoinBigIndex end = columnStart[iColumn] + columnLength[iColumn]; for (CoinBigIndex j = start; j < end; j++) { choleskyRow_[numberElements] = row[j] + numberTotal; sparseFactor_[numberElements++] = element[j]; largest = CoinMax(largest, fabs(element[j])); } } else { value = 1.0e100; sparseFactor_[savePosition] = -value; } } } for (iColumn = 0; iColumn < numberColumns; iColumn++) { assert (sparseFactor_[choleskyStart_[iColumn]] < 0.0); } // slacks for (iColumn = numberColumns; iColumn < numberTotal; iColumn++) { choleskyStart_[iColumn] = numberElements; double value = diagonal[iColumn]; if (fabs(value) > 1.0e-100) { value = 1.0 / value; largest = CoinMax(largest, fabs(value)); } else { value = 1.0e100; } sparseFactor_[numberElements] = -value; choleskyRow_[numberElements++] = iColumn; choleskyRow_[numberElements] = iColumn - numberColumns + numberTotal; sparseFactor_[numberElements++] = -1.0; } // Finish diagonal double delta2 = model_->delta(); // add delta*delta to bottom delta2 *= delta2; for (iRow = 0; iRow < numberRowsModel; iRow++) { choleskyStart_[iRow+numberTotal] = numberElements; choleskyRow_[numberElements] = iRow + numberTotal; sparseFactor_[numberElements++] = delta2; } choleskyStart_[numberRows_] = numberElements; int i1 = 1; int i0 = 0; integerParameters_[1] = 3; integerParameters_[2] = 3; integerParameters_[10] = 2; //integerParameters_[11]=1; integerParameters_[12] = 2; // LDLT integerParameters_[30] = 1; doubleParameters_[20] = 1.0e100; double largest2 = largest * 1.0e-20; largest = CoinMin(largest2, 1.0e-11); doubleParameters_[10] = CoinMax(1.0e-20, largest); if (doubleParameters_[10] > 1.0e-3) integerParameters_[9] = 1; else integerParameters_[9] = 0; #ifndef WSMP // Set up LDL cutoff integerParameters_[34] = numberTotal; doubleParameters_[20] = 1.0e-15; doubleParameters_[34] = 1.0e-12; //printf("tol is %g\n",doubleParameters_[10]); //doubleParameters_[10]=1.0e-17; #endif int * rowsDropped2 = new int[numberRows_]; CoinZeroN(rowsDropped2, numberRows_); F77_FUNC(wssmp,WSSMP)(&numberRows_, choleskyStart_, choleskyRow_, sparseFactor_, NULL, permute_, permuteInverse_, NULL, &numberRows_, &i1, NULL, &i0, rowsDropped2, integerParameters_, doubleParameters_); //std::cout<<"factorization took "<<doubleParameters_[0]<<std::endl; if (integerParameters_[9]) { std::cout << "scaling applied" << std::endl; } newDropped = integerParameters_[20]; #if 1 // Should save adjustments in ..R_ int n1 = 0, n2 = 0; double * primalR = model_->primalR(); double * dualR = model_->dualR(); for (iRow = 0; iRow < numberTotal; iRow++) { if (rowsDropped2[iRow]) { n1++; //printf("row region1 %d dropped\n",iRow); //rowsDropped_[iRow]=1; rowsDropped_[iRow] = 0; primalR[iRow] = doubleParameters_[20]; } else { rowsDropped_[iRow] = 0; primalR[iRow] = 0.0; } } for (; iRow < numberRows_; iRow++) { if (rowsDropped2[iRow]) { n2++; //printf("row region2 %d dropped\n",iRow); //rowsDropped_[iRow]=1; rowsDropped_[iRow] = 0; dualR[iRow-numberTotal] = doubleParameters_[34]; } else { rowsDropped_[iRow] = 0; dualR[iRow-numberTotal] = 0.0; } } //printf("%d rows dropped in region1, %d in region2\n",n1,n2); #endif delete [] rowsDropped2; //if (integerParameters_[20]) //std::cout<<integerParameters_[20]<<" rows dropped"<<std::endl; largest = doubleParameters_[3]; smallest = doubleParameters_[4]; if (model_->messageHandler()->logLevel() > 1) std::cout << "Cholesky - largest " << largest << " smallest " << smallest << std::endl; choleskyCondition_ = largest / smallest; if (integerParameters_[63] < 0) return -1; // out of memory status_ = 0; return 0; }
/* Orders rows and saves pointer to model */ int ClpCholeskyWssmpKKT::order(ClpInterior * model) { int numberRowsModel = model->numberRows(); int numberColumns = model->numberColumns(); int numberTotal = numberColumns + numberRowsModel; numberRows_ = 2 * numberRowsModel + numberColumns; rowsDropped_ = new char [numberRows_]; memset(rowsDropped_, 0, numberRows_); numberRowsDropped_ = 0; model_ = model; 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; } try { sparseFactor_ = new double[numberElements]; } catch (...) { // no memory delete [] choleskyRow_; choleskyRow_ = NULL; delete [] choleskyStart_; choleskyStart_ = NULL; return -1; } int iRow, iColumn; sizeFactor_ = 0; // matrix if (!quadratic) { for (iColumn = 0; iColumn < numberColumns; iColumn++) { choleskyStart_[iColumn] = sizeFactor_; choleskyRow_[sizeFactor_++] = iColumn; CoinBigIndex start = columnStart[iColumn]; CoinBigIndex end = columnStart[iColumn] + columnLength[iColumn]; for (CoinBigIndex j = start; j < end; j++) { choleskyRow_[sizeFactor_++] = row[j] + numberTotal; } } } else { // Quadratic const int * columnQuadratic = quadratic->getIndices(); const CoinBigIndex * columnQuadraticStart = quadratic->getVectorStarts(); const int * columnQuadraticLength = quadratic->getVectorLengths(); //const double * quadraticElement = quadratic->getElements(); for (iColumn = 0; iColumn < numberColumns; iColumn++) { choleskyStart_[iColumn] = sizeFactor_; choleskyRow_[sizeFactor_++] = iColumn; for (CoinBigIndex j = columnQuadraticStart[iColumn]; j < columnQuadraticStart[iColumn] + columnQuadraticLength[iColumn]; j++) { int jColumn = columnQuadratic[j]; if (jColumn > iColumn) choleskyRow_[sizeFactor_++] = jColumn; } CoinBigIndex start = columnStart[iColumn]; CoinBigIndex end = columnStart[iColumn] + columnLength[iColumn]; for (CoinBigIndex j = start; j < end; j++) { choleskyRow_[sizeFactor_++] = row[j] + numberTotal; } } } // slacks for (; iColumn < numberTotal; iColumn++) { choleskyStart_[iColumn] = sizeFactor_; choleskyRow_[sizeFactor_++] = iColumn; choleskyRow_[sizeFactor_++] = iColumn - numberColumns + numberTotal; } // Transpose - nonzero diagonal (may regularize) for (iRow = 0; iRow < numberRowsModel; iRow++) { choleskyStart_[iRow+numberTotal] = sizeFactor_; // diagonal choleskyRow_[sizeFactor_++] = iRow + numberTotal; } choleskyStart_[numberRows_] = sizeFactor_; permuteInverse_ = new int [numberRows_]; permute_ = new int[numberRows_]; integerParameters_[0] = 0; int i0 = 0; int i1 = 1; #ifndef USE_EKKWSSMP int i2 = 1; if (model->numberThreads() <= 0) i2 = 1; else i2 = model->numberThreads(); F77_FUNC(wsetmaxthrds,WSETMAXTHRDS)(&i2); #endif F77_FUNC(wssmp,WSSMP)(&numberRows_, choleskyStart_, choleskyRow_, sparseFactor_, NULL, permute_, permuteInverse_, 0, &numberRows_, &i1, NULL, &i0, NULL, integerParameters_, doubleParameters_); integerParameters_[1] = 1; //order and symbolic integerParameters_[2] = 2; integerParameters_[3] = 0; //CSR integerParameters_[4] = 0; //C style integerParameters_[13] = 1; //reuse initial factorization space integerParameters_[15+0] = 1; //ordering integerParameters_[15+1] = 0; integerParameters_[15+2] = 1; integerParameters_[15+3] = 0; integerParameters_[15+4] = 1; doubleParameters_[10] = 1.0e-20; doubleParameters_[11] = 1.0e-15; #if 1 integerParameters_[1] = 2; //just symbolic for (int iRow = 0; iRow < numberRows_; iRow++) { permuteInverse_[iRow] = iRow; permute_[iRow] = iRow; } #endif F77_FUNC(wssmp,WSSMP)(&numberRows_, choleskyStart_, choleskyRow_, sparseFactor_, NULL, permute_, permuteInverse_, NULL, &numberRows_, &i1, NULL, &i0, NULL, integerParameters_, doubleParameters_); //std::cout<<"Ordering and symbolic factorization took "<<doubleParameters_[0]<<std::endl; if (integerParameters_[63]) { std::cout << "wssmp returning error code of " << integerParameters_[63] << std::endl; return 1; } std::cout << integerParameters_[23] << " elements in sparse Cholesky" << std::endl; if (!integerParameters_[23]) { for (int iRow = 0; iRow < numberRows_; iRow++) { permuteInverse_[iRow] = iRow; permute_[iRow] = iRow; } std::cout << "wssmp says no elements - fully dense? - switching to dense" << std::endl; integerParameters_[1] = 2; integerParameters_[2] = 2; integerParameters_[7] = 1; // no permute F77_FUNC(wssmp,WSSMP)(&numberRows_, choleskyStart_, choleskyRow_, sparseFactor_, NULL, permute_, permuteInverse_, NULL, &numberRows_, &i1, NULL, &i0, NULL, integerParameters_, doubleParameters_); std::cout << integerParameters_[23] << " elements in dense Cholesky" << std::endl; } return 0; }