BooleanType Matrix::isDiagonal( ) const { if (isSquare() == BT_FALSE) return BT_FALSE; for (unsigned i = 0; i < getNumRows( ); ++i) for (unsigned j = 0; j < getNumCols( ); ++j) if ((i != j) && (acadoIsZero( operator()(i, j) ) == BT_FALSE)) return BT_FALSE; return BT_TRUE; }
uint Matrix::determineStringLength( const char* const name, const char* const startString, const char* const endString, uint width, uint precision, const char* const colSeparator, const char* const rowSeparator ) const { uint componentLength = width; // 0.e-0000 if ( componentLength < (9 + (uint)precision) ) componentLength = 9 + precision; // allocate string of sufficient size (being quite conservative) uint stringLength; if ( getNumRows( ) * getNumCols( ) > 0 ) { stringLength = 1 + getNumRows( ) * getStringLength(startString) + ( getNumRows( )*getNumCols( ) ) * componentLength + ( (getNumCols( )-1)*getNumRows( ) ) * getStringLength(colSeparator) + ( getNumRows( )-1 ) * getStringLength(rowSeparator) + getNumRows( ) * getStringLength(endString); } else { stringLength = 1 + getStringLength(startString) + getStringLength(endString); } if ( getStringLength(name) > 0 ) stringLength += getStringLength(name)+3; return stringLength; }
void OsiTestSolverInterface::compute_rc_(const double* u, double* rc) const { if (isZeroOneMinusOne_) { rowMatrixOneMinusOne_->timesMajor(u, rc); } else { rowMatrix_.transposeTimes(u, rc); } const int psize = getNumCols(); std::transform(rc, rc+psize, objcoeffs_, rc, std::minus<double>()); std::transform(rc, rc+psize, rc, std::negate<double>()); }
returnValue Matrix::computeQRdecomposition(){ int run1, run2, run3; if( solver != 0 ){ delete solver; solver = 0; } ASSERT( getNumRows() == getNumCols() ); double r ; double h_s ; double kappa; double ll ; double ttt ; int nnn = getNumRows(); Matrix ddd(1,nnn); for(run2 = 0; run2 < nnn; run2++){ r = 0.0; for(run1 = run2; run1 < nnn; run1++){ r = r + operator()(run1,run2) * operator()(run1,run2); } if( r < EPS ) return ACADOERROR(RET_DIV_BY_ZERO); if( operator()(run2,run2) < 0.0 ){ h_s = sqrt(r); ddd(0,run2) = h_s ; } else{ h_s = -sqrt(r); ddd(0,run2) = h_s ; } ttt = h_s * operator()(run2,run2) - r; kappa = 1.0/ttt; operator()(run2,run2) -= h_s; for(run3 = run2+1; run3 < nnn; run3++){ ll = 0; for(run1 = run2; run1 < nnn; run1++) ll += operator()(run1,run2) * operator()(run1,run3); ll = kappa * ll; for(run1 = run2; run1 < nnn; run1++) operator()(run1,run3) = operator()(run1,run3) + operator()(run1,run2) * ll; } } appendRows(ddd); return SUCCESSFUL_RETURN; }
MatrixBase<T>& Matrix<T>::operator+=(const MatrixBase<T>& rhs) { int rows = getNumRows(); int cols = getNumCols(); if( rows != rhs.getNumRows() ) throw SizeError(rows, "operator+= row"); if( cols != rhs.getNumCols() ) throw SizeError(cols, "operator+= col"); for(int i=0; i < rows; i++) { for(int j=0; j < cols; j++) { operator()(i,j) = operator()(i,j) + rhs(i,j); } } return *this; }
int OsiVolSolverInterface::readMps(const char *filename, const char *extension) { CoinMpsIO reader; reader.setInfinity(getInfinity()); int retVal = reader.readMps(filename, extension); loadProblem(*reader.getMatrixByCol(), reader.getColLower(), reader.getColUpper(), reader.getObjCoefficients(), reader.getRowLower(), reader.getRowUpper()); int nc = getNumCols(); assert (continuous_); CoinFillN(continuous_, nc, true); return retVal; }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- QVector<double> DynamicTableData::flattenData() const { int numRows = getNumRows(); int numCols = getNumCols(); QVector<double> flat(numRows * numCols); for (int row = 0; row < numRows; row++) { for (int col = 0; col < numCols; col++) { flat[row * numCols + col] = m_TableData[row][col]; } } return flat; }
bool Matrix<T>::isDiagonallyDominant() const { for(int i=0; i < getNumCols(); i++) { T sum = 0; for(int j=0; j < getNumRows(); j++) { if(j != i) { sum += abs( operator()(i,j) ); } } if( sum > abs( operator()(i,i) ) ) return false; } return true; }
CMatrix CMatrix::mulByOnes( int iNumRows, int iNumCols ) { CMatrix Result; int iThisRows = getNumRows(); if (getNumCols() != iNumRows) return Result; Result.init(iThisRows, iNumCols); for (int i = 0; i < iThisRows; i++) { float fSum = CUtil::sum(m_ppfMatrix[i], m_aiMatrixDimensions[kCol]); CUtil::setValue(Result.m_ppfMatrix[i], fSum, iNumCols); } return Result; }
returnValue ExportArithmeticStatement::exportCodeAddSubtract( FILE* file, const char* const _sign, const char* _realString, const char* _intString, int _precision ) const { if ( ( rhs1 == 0 ) || ( rhs2 == 0 ) ) return ACADOERROR( RET_UNABLE_TO_EXPORT_STATEMENT ); if ( ( rhs1->getNumRows() != rhs2->getNumRows() ) || ( rhs1->getNumCols() != rhs2->getNumCols() ) ) return ACADOERROR( RET_VECTOR_DIMENSION_MISMATCH ); if ( lhs != 0 ) { if ( ( rhs1->getNumRows() != lhs->getNumRows() ) || ( rhs1->getNumCols() != lhs->getNumCols() ) ) return ACADOERROR( RET_VECTOR_DIMENSION_MISMATCH ); } for( uint i=0; i<getNumRows( ); ++i ) for( uint j=0; j<getNumCols( ); ++j ) { if ( lhs != 0 ) acadoFPrintf( file,"%s = ", lhs->get(i,j) ); if ( rhs1->isZero(i,j) == BT_FALSE ) { acadoFPrintf( file,"%s", rhs1->get(i,j) ); if ( rhs2->isZero(i,j) == BT_FALSE ) acadoFPrintf( file," %s %s;\n", _sign,rhs2->get(i,j) ); else acadoFPrintf( file,";\n" ); } else { if ( rhs2->isZero(i,j) == BT_FALSE ) acadoFPrintf( file,"%s %s;\n", _sign,rhs2->get(i,j) ); else acadoFPrintf( file,"0.0;\n" ); } } return SUCCESSFUL_RETURN; }
void Image::threshold(double threshold) { for( int r = 0; r < getNumRows(); ++r ) { for( int c = 0; c < getNumCols(); ++c ) { if( std::abs(getPixel(r, c) ) <= threshold ) { setPixel(r, c, 254); } else { setPixel(r, c, 0); } } } }
MatrixBase<T>& Matrix<T>::operator=(const MatrixBase<T>& rhs) { if(&rhs != this) { const int row = rhs.getNumRows(); const int col = rhs.getNumCols(); if(row != getNumRows()) throw SizeError(row,"operator= row"); if(col != getNumCols()) throw SizeError(col,"operator= col"); for(int i=0; i < row; i++) { for(int j=0; j < col; j++) { this->operator()(i,j) = rhs(i,j); } } } return *this; }
void OsiTestSolverInterface::addCol(const CoinPackedVectorBase& vec, const double collb, const double colub, const double obj) { const int colnum = getNumCols(); colRimResize_(colnum + 1); collower_[colnum] = collb; colupper_[colnum] = colub; objcoeffs_[colnum] = obj; continuous_[colnum] = true; colsol_[colnum] = fabs(collb)<fabs(colub) ? collb : colub; rc_[colnum] = 0.0; updateColMatrix_(); colMatrix_.appendCol(vec); rowMatrixCurrent_ = false; }
void OsiTestSolverInterface::checkData_() const { int i; for (i = getNumRows() - 1; i >= 0; --i) { if (rowlower_[i] > -1.0e20 && rowupper_[i] < 1.0e20 && rowlower_[i] != rowupper_[i]) throw CoinError("Volume algorithm is unable to handle ranged rows", "checkData_", "OsiTestSolverInterface"); } for (i = getNumCols() - 1; i >= 0; --i) { if (collower_[i] < -1.0e20 || colupper_[i] > 1.0e20) throw CoinError("Volume algorithm is unable to handle infinite bounds", "checkData_", "OsiTestSolverInterface"); } }
void OsiTestSolverInterface::setInteger(const int* indices, int len) { assert(continuous_ != NULL); const int colnum = getNumCols(); int i; for (i = len - 1; i >= 0; --i) { if (indices[i] < 0 || indices[i] > colnum) { throw CoinError("Index out of bound.", "setContinuous", "OsiTestSolverInterface"); } } for (i = len - 1; i >= 0; --i) { continuous_[indices[i]] = false; } }
/** Equivalence. Two matrices are equivalent if they are both by rows or both by columns, they have the same dimensions, and each vector is equivalent. In this method the FloatEqual function operator can be specified. */ template <class FloatEqual> bool isEquivalent(const CoinPackedMatrix& rhs, const FloatEqual& eq) const { // Both must be column order or both row ordered and must be of same size if ((isColOrdered() ^ rhs.isColOrdered()) || (getNumCols() != rhs.getNumCols()) || (getNumRows() != rhs.getNumRows()) || (getNumElements() != rhs.getNumElements())) return false; for (int i=getMajorDim()-1; i >= 0; --i) { CoinShallowPackedVector pv = getVector(i); CoinShallowPackedVector rhsPv = rhs.getVector(i); if ( !pv.isEquivalent(rhsPv,eq) ) return false; } return true; }
void MILPSolverCPX::getRow(const int & i, vector<pair<int,double> > & entries) { const int colCount = getNumCols(); IloRange & currRow = (modelcon->data)[i]; IloNumExprArg ne = currRow.getExpr(); for(IloExpr::LinearIterator itr = static_cast<IloExpr>(ne).getLinearIterator(); itr.ok(); ++itr) { const int colID = itr.getVar().getId(); for (int c = 0; c < colCount; ++c) { if ((*modelvar)[c].getId() == colID) { entries.push_back(make_pair(c, itr.getCoef())); break; } } } }
Matrix Matrix::getCholeskyDecomposition( Vector &D ) const{ int n = getNumRows(); ASSERT( n == (int) getNumCols() ); int i, j, k; double *p_i; double *p_j; double *p_k; double ld; double *A = new double[dim]; for( k = 0; k < (int) dim; k++ ){ A[k] = element[k]; } for (i = 1, p_i = A + n; i < n; p_i += n, i++) { for (j = 0, p_j = A; j < i; j++, p_j += n) for (k = 0; k < j; k++) *(p_i + j) -= *(p_i + k) * *(p_j + k); for (k = 0, p_k = A; k < i; p_k += n, k++) { ld = *(p_i + k) / *(p_k + k); *(p_i + i) -= *(p_i + k) * ld; *(p_i + k) = ld; *(p_k + i) = ld; } ASSERT( *(p_i + i) >= EPS ); } Matrix tmp(n,n); tmp.setIdentity(); D.init(n); for( i = 0; i < n; i++ ) for( k = 0; k < i; k++ ) tmp(i,k) = A[i*n+k]; for( i = 0; i < n; i++ ) D(i) = A[i*n+i]; delete[] A; return tmp; }
Matrix Matrix::getCholeskyDecomposition() const{ int n = getNumRows(); ASSERT( n == (int) getNumCols() ); int i, k, p; double *p_Lk0; double *p_Lkp; double *p_Lkk; double *p_Li0; double reciprocal; double *A = new double[dim]; for( k = 0; k < (int) dim; k++ ) A[k] = element[k]; for (k = 0, p_Lk0 = A; k < n; p_Lk0 += n, k++) { p_Lkk = p_Lk0 + k; for (p = 0, p_Lkp = p_Lk0; p < k; p_Lkp += 1, p++) *p_Lkk -= *p_Lkp * *p_Lkp; *p_Lkk = sqrt( *p_Lkk ); ASSERT( *p_Lkk >= EPS ); reciprocal = 1.0 / *p_Lkk; p_Li0 = p_Lk0 + n; for (i = k + 1; i < n; p_Li0 += n, i++) { for (p = 0; p < k; p++) *(p_Li0 + k) -= *(p_Li0 + p) * *(p_Lk0 + p); *(p_Li0 + k) *= reciprocal; *(p_Lk0 + i) = *(p_Li0 + k); } } Matrix tmp(n,n); tmp.setZero(); for( i = 0; i < n; i++ ) for( k = 0; k <= i; k++ ) tmp(i,k) = A[i*n+k]; delete[] A; return tmp; }
OsiTestSolverInterface& OsiTestSolverInterface::operator=(const OsiTestSolverInterface& rhs) { if (&rhs == this) return *this; OsiSolverInterface::operator=(rhs); gutsOfDestructor_(); rowMatrixCurrent_ = rhs.rowMatrixCurrent_; if (rowMatrixCurrent_) rowMatrix_ = rhs.rowMatrix_; colMatrixCurrent_ = rhs.colMatrixCurrent_; if (colMatrixCurrent_) colMatrix_ = rhs.colMatrix_; if (rhs.maxNumrows_) { maxNumrows_ = rhs.maxNumrows_; rowRimAllocator_(); const int rownum = getNumRows(); CoinDisjointCopyN(rhs.rowupper_, rownum, rowupper_); CoinDisjointCopyN(rhs.rowlower_, rownum, rowlower_); CoinDisjointCopyN(rhs.rowsense_, rownum, rowsense_); CoinDisjointCopyN(rhs.rhs_, rownum, rhs_); CoinDisjointCopyN(rhs.rowrange_, rownum, rowrange_); CoinDisjointCopyN(rhs.rowprice_, rownum, rowprice_); CoinDisjointCopyN(rhs.lhs_, rownum, lhs_); } if (rhs.maxNumcols_) { maxNumcols_ = rhs.maxNumcols_; colRimAllocator_(); const int colnum = getNumCols(); CoinDisjointCopyN(rhs.colupper_, colnum, colupper_); CoinDisjointCopyN(rhs.collower_, colnum, collower_); CoinDisjointCopyN(rhs.continuous_, colnum, continuous_); CoinDisjointCopyN(rhs.objcoeffs_, colnum, objcoeffs_); CoinDisjointCopyN(rhs.colsol_, colnum, colsol_); CoinDisjointCopyN(rhs.rc_, colnum, rc_); } volprob_.parm.granularity = 0.0; return *this; }
/* Return a column name, according to the current name discipline, truncated if necessary. If the column index is out of range, the name becomes an error message. */ std::string OsiSolverInterface::getColName (int ndx, unsigned maxLen) const { int nameDiscipline ; std::string name ; /* Check for valid column index. */ if (ndx < 0 || ndx >= getNumCols()) { name = invRowColName('c',ndx) ; return (name) ; } /* Determine how we're handling names. It's possible that the underlying solver has overridden getIntParam, but doesn't recognise OsiNameDiscipline. In that case, we want to default to auto names */ bool recognisesOsiNames = getIntParam(OsiNameDiscipline,nameDiscipline) ; if (recognisesOsiNames == false) { nameDiscipline = 0 ; } /* Find/generate the proper name, based on discipline. */ switch (nameDiscipline) { case 0: { name = dfltRowColName('c',ndx) ; break ; } case 1: case 2: { name = "" ; if (static_cast<unsigned>(ndx) < colNames_.size()) name = colNames_[ndx] ; if (name.length() == 0) name = dfltRowColName('c',ndx) ; break ; } default: { name = invRowColName('d',nameDiscipline) ; return (name) ; } } /* Return the (possibly truncated) substring. The default for maxLen is npos (no truncation). */ return (name.substr(0,maxLen)) ; }
// --------------------------------------------------------------------- // void DecompConstraintSet::createRowHash() { int r; string strHash; const int* rmat_ind = M->getIndices(); const double* rmat_els = M->getElements(); const int* rmat_beg = M->getVectorStarts(); const int* rmat_len = M->getVectorLengths(); printf("\nNUM COLS: %d", getNumCols()); printf("\nNUM ROWS: %d", getNumRows()); for (r = 0; r < getNumRows(); r++) { //printf("\n"); strHash = UtilCreateStringHash(rmat_len[r], rmat_ind + rmat_beg[r], rmat_els + rmat_beg[r], rowSense[r], rowRhs[r]); rowHash.push_back(strHash); } }
returnValue Matrix::computeSparseLUdecomposition(){ ASSERT( solver == 0 ); ASSERT( getNumRows() == getNumCols() ); solver = new ACADOcsparse(); int run1,run2; double ZERO_TOL = 1.e-12; const int n = getNumRows(); double *A = new double[dim]; int *idx1 = new int [dim]; int *idx2 = new int [dim]; int nDense = 0; for( run1 = 0; run1 < n; run1++ ){ for( run2 = 0; run2 < n; run2++ ){ if( fabs( operator()(run1,run2) ) > ZERO_TOL ){ A [nDense] = operator()(run1,run2); idx1[nDense] = run1; idx2[nDense] = run2; nDense++; } } } solver->setDimension ( n ); solver->setNumberOfEntries( nDense ); solver->setIndices ( idx1, idx2 ); solver->setMatrix ( A ); delete[] A; delete[] idx1; delete[] idx2; return SUCCESSFUL_RETURN; }
/* Set a run of column names. Quietly fail if the specified indices are invalid. On the target side, [tgtStart, tgtStart+len-1] must be in the range [0,n-1], where n is the number of columns. On the source side, srcStart must be zero or greater. If we run off the end of srcNames, we just generate default names. */ void OsiSolverInterface::setColNames (OsiNameVec &srcNames, int srcStart, int len, int tgtStart) { int nameDiscipline ; /* Determine how we're handling names. It's possible that the underlying solver has overridden getIntParam, but doesn't recognise OsiNameDiscipline. In that case, we want to default to auto names */ bool recognisesOsiNames = getIntParam(OsiNameDiscipline,nameDiscipline) ; if (recognisesOsiNames == false) { nameDiscipline = 0 ; } /* If the name discipline is auto, we're already done. */ if (nameDiscipline == 0) { return ; } /* A little self-protection. Check that we're within [0,m-1] on the target side, and that srcStart is zero or greater. Quietly fail if the indices don't fit. */ int n = getNumCols() ; if (tgtStart < 0 || tgtStart+len > n) { return ; } if (srcStart < 0) { return ; } int srcLen = static_cast<int>(srcNames.size()) ; /* Load 'em up. */ int srcNdx = srcStart ; int tgtNdx = tgtStart ; for ( ; tgtNdx < tgtStart+len ; srcNdx++,tgtNdx++) { if (srcNdx < srcLen) { setColName(tgtNdx,srcNames[srcNdx]) ; } else { setColName(tgtNdx,dfltRowColName('c',tgtNdx)) ; } } return ; }
/* Return the vector of column names. The vector we need depends on the name discipline: 0: return a vector of length 0 1: return colNames_, no tweaking required 2: Check that colNames_ is complete. Generate a complete vector on the spot if we need it. */ const OsiSolverInterface::OsiNameVec &OsiSolverInterface::getColNames () { int nameDiscipline ; /* Determine how we're handling names. It's possible that the underlying solver has overridden getIntParam, but doesn't recognise OsiNameDiscipline. In that case, we want to default to auto names */ bool recognisesOsiNames = getIntParam(OsiNameDiscipline,nameDiscipline) ; if (recognisesOsiNames == false) { nameDiscipline = 0 ; } /* Return the proper vector, as described at the head of the routine. If we need to generate a full vector, resize the existing vector and scan, filling in entries as required. */ switch (nameDiscipline) { case 0: { return (zeroLengthNameVec) ; } case 1: { return (colNames_) ; } case 2: { int n = getNumCols() ; if (colNames_.size() < static_cast<unsigned>(n)) { colNames_.resize(n) ; } for (int j = 0 ; j < n ; j++) { if (colNames_[j].length() == 0) { colNames_[j] = dfltRowColName('c',j) ; } } return (colNames_) ; } default: { /* quietly fail */ return (zeroLengthNameVec) ; } } /* We should never reach here. */ assert(false) ; return (zeroLengthNameVec) ; }
Matrix Matrix::getCholeskyInverse() const{ int n = getNumRows(); ASSERT( n == (int) getNumCols() ); int i, j, k; double *p_i, *p_j, *p_k; double sum; Matrix cholesky; cholesky = getCholeskyDecomposition(); double *LU = new double[n*n]; for( i = 0; i < n; i++ ){ for( k = 0; k <= i; k++ ){ LU[i+n*k] = cholesky(i,k); LU[i*n+k] = cholesky(i,k); } } lowerTriangularInverse(LU, n); for (i = 0, p_i = LU; i < n; i++, p_i += n) { for (j = 0, p_j = LU; j <= i; j++, p_j += n) { sum = 0.0; for (k = i, p_k = p_i; k < n; k++, p_k += n) sum += *(p_k + i) * *(p_k + j); *(p_i + j) = sum; *(p_j + i) = sum; } } Matrix tmp(n,n,LU); delete[] LU; return tmp; }
//############################################################################# // Initial solve and find integers bool DcModel::setupSelf() { bool feasible = true; solver_->messageHandler()->setLogLevel(0); initialSolve(); sharedBasis_ = dynamic_cast<CoinWarmStartBasis*> (solver_->getWarmStart()); # ifdef DC_DEBUG_MORE std::string problemName; solver_->getStrParam(OsiProbName, problemName); printf("Problem name - %s\n", problemName.c_str()); solver_->setHintParam(OsiDoReducePrint, false, OsiHintDo, 0); # endif status_ = 0; findIntegers(true); bestObjective_ = 1.0e50; double direction = solver_->getObjSense(); int numberColumns = getNumCols(); if (!currentSolution_) currentSolution_ = new double[numberColumns]; //continuousSolver_ = solver_->clone(); numberRowsAtContinuous_ = getNumRows(); maximumNumberCuts_ = 0; currentNumberCuts_ = 0; // FIXME: return feasible; }
/* Set a single column name. Quietly does nothing if the index or name discipline is invalid. */ void OsiSolverInterface::setColName (int ndx, std::string name) { int nameDiscipline ; /* Quietly do nothing if the index is out of bounds. This should be changed, but what's our error convention, eh? There's no precedent in OsiSolverInterface.cpp. */ if (ndx < 0 || ndx >= getNumCols()) { return ; } /* Determine how we're handling names. It's possible that the underlying solver has overridden getIntParam, but doesn't recognise OsiNameDiscipline. In that case, we want to default to auto names */ bool recognisesOsiNames = getIntParam(OsiNameDiscipline,nameDiscipline) ; if (recognisesOsiNames == false) { nameDiscipline = 0 ; } /* Do the right thing, according to the discipline. */ switch (nameDiscipline) { case 0: { break ; } case 1: case 2: { if (static_cast<unsigned>(ndx) > colNames_.capacity()) { colNames_.resize(ndx+1) ; } else if (static_cast<unsigned>(ndx) >= colNames_.size()) { colNames_.resize(ndx+1) ; } colNames_[ndx] = name ; break ; } default: { break ; } } return ; }
void OsiCpxSolverInterface::printBounds() { int nc = getNumCols(); int nr = getNumRows(); const char * s = getRowSense(); const double * b = getRightHandSide(); const double * rng = getRowRange(); const double * cl = getColLower(); const double * cu = getColUpper(); const double * rl = getRowLower(); const double * ru = getRowUpper(); std::cout << "ncols=" << nc << ", nrows=" << nr; std::cout << std::endl << "sns="; int i; for( i = 0; i < nr; ++i ) std::cout << " " << s[i]; std::cout << std::endl << "rhs="; for( i = 0; i < nr; ++i ) std::cout << " " << b[i]; std::cout << std::endl << "rng="; for( i = 0; i < nr; ++i ) std::cout << " " << rng[i]; std::cout << std::endl << "cl ="; for( i = 0; i < nc; ++i ) std::cout << " " << cl[i]; std::cout << std::endl << "cu ="; for( i = 0; i < nc; ++i ) std::cout << " " << cu[i]; std::cout << std::endl << "rl ="; for( i = 0; i < nr; ++i ) std::cout << " " << rl[i]; std::cout << std::endl << "ru ="; for( i = 0; i < nr; ++i ) std::cout << " " << ru[i]; std::cout << std::endl; }
void OsiTestSolverInterface::resolve() { int i; checkData_(); // Only one of these can do any work updateRowMatrix_(); updateColMatrix_(); const int dsize = getNumRows(); const int psize = getNumCols(); // Negate the objective coefficients if necessary if (objsense_ < 0) { std::transform(objcoeffs_, objcoeffs_+psize, objcoeffs_, std::negate<double>()); } // Set the lb/ub on the duals volprob_.dual_lb.allocate(dsize); volprob_.dual_ub.allocate(dsize); double * dlb = volprob_.dual_lb.v; double * dub = volprob_.dual_ub.v; for (i = 0; i < dsize; ++i) { dlb[i] = rowupper_[i] < getInfinity() ? -1.0e31 : 0.0; dub[i] = rowlower_[i] > -getInfinity() ? 1.0e31 : 0.0; } volprob_.dsize = dsize; volprob_.psize = psize; // Set the dual starting point VOL_dvector& dsol = volprob_.dsol; dsol.allocate(dsize); std::transform(rowprice_, rowprice_+dsize, dsol.v, std::bind2nd(std::multiplies<double>(), objsense_)); // adjust the dual vector (if necessary) to be sure it's feasible double * dv = dsol.v; for (i = 0; i < dsize; ++i) { if (dv[i] < dlb[i]) { dv[i] = dlb[i]; } else if (dv[i] > dub[i]) { dv[i] = dub[i]; } } // If requested, check whether the matrix contains anything but 0/1/-1 #if 0 isZeroOneMinusOne_ = false; #else isZeroOneMinusOne_ = test_zero_one_minusone_(colMatrix_); if (isZeroOneMinusOne_) { colMatrixOneMinusOne_ = new OsiVolMatrixOneMinusOne_(colMatrix_); rowMatrixOneMinusOne_ = new OsiVolMatrixOneMinusOne_(rowMatrix_); } #endif volprob_.solve(*this, true); // extract the solution // the lower bound on the objective value lagrangeanCost_ = objsense_ * volprob_.value; // the primal solution CoinDisjointCopyN(volprob_.psol.v, psize, colsol_); // Reset the objective coefficients if necessary if (objsense_ < 0) { std::transform(objcoeffs_, objcoeffs_ + psize, objcoeffs_, std::negate<double>()); // also, multiply the dual solution by -1 std::transform(volprob_.dsol.v, volprob_.dsol.v+dsize, rowprice_, std::negate<double>()); } else { // now we just have to copy the dual CoinDisjointCopyN(volprob_.dsol.v, dsize, rowprice_); } // Compute the reduced costs compute_rc_(rowprice_, rc_); // Compute the left hand side (row activity levels) if (isZeroOneMinusOne_) { colMatrixOneMinusOne_->timesMajor(colsol_, lhs_); } else { colMatrix_.times(colsol_, lhs_); } if (isZeroOneMinusOne_) { delete colMatrixOneMinusOne_; colMatrixOneMinusOne_ = NULL; delete rowMatrixOneMinusOne_; rowMatrixOneMinusOne_ = NULL; } }