예제 #1
0
/* 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;
}
예제 #2
0
/* 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;
}
예제 #3
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;
}