/* $Id$ */ // Copyright (C) 2007, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). #include "CoinPragma.hpp" #include "CoinHelperFunctions.hpp" #include "CoinIndexedVector.hpp" #include "ClpSimplex.hpp" #include "ClpConstraintLinear.hpp" #include "CoinSort.hpp" //############################################################################# // Constructors / Destructor / Assignment //############################################################################# //------------------------------------------------------------------- // Default Constructor //------------------------------------------------------------------- ClpConstraintLinear::ClpConstraintLinear() : ClpConstraint() { type_ = 0; column_ = NULL; coefficient_ = NULL; numberColumns_ = 0; numberCoefficients_ = 0; } //------------------------------------------------------------------- // Useful Constructor //------------------------------------------------------------------- ClpConstraintLinear::ClpConstraintLinear(int row, int numberCoefficents, int numberColumns, const int *column, const double *coefficient) : ClpConstraint() { type_ = 0; rowNumber_ = row; numberColumns_ = numberColumns; numberCoefficients_ = numberCoefficents; column_ = CoinCopyOfArray(column, numberCoefficients_); coefficient_ = CoinCopyOfArray(coefficient, numberCoefficients_); CoinSort_2(column_, column_ + numberCoefficients_, coefficient_); } //------------------------------------------------------------------- // Copy constructor //------------------------------------------------------------------- ClpConstraintLinear::ClpConstraintLinear(const ClpConstraintLinear &rhs) : ClpConstraint(rhs) { numberColumns_ = rhs.numberColumns_; numberCoefficients_ = rhs.numberCoefficients_; column_ = CoinCopyOfArray(rhs.column_, numberCoefficients_); coefficient_ = CoinCopyOfArray(rhs.coefficient_, numberCoefficients_); } //------------------------------------------------------------------- // Destructor //------------------------------------------------------------------- ClpConstraintLinear::~ClpConstraintLinear() { delete[] column_; delete[] coefficient_; } //---------------------------------------------------------------- // Assignment operator //------------------------------------------------------------------- ClpConstraintLinear & ClpConstraintLinear::operator=(const ClpConstraintLinear &rhs) { if (this != &rhs) { delete[] column_; delete[] coefficient_; numberColumns_ = rhs.numberColumns_; numberCoefficients_ = rhs.numberCoefficients_; column_ = CoinCopyOfArray(rhs.column_, numberCoefficients_); coefficient_ = CoinCopyOfArray(rhs.coefficient_, numberCoefficients_); } return *this; } //------------------------------------------------------------------- // Clone //------------------------------------------------------------------- ClpConstraint *ClpConstraintLinear::clone() const { return new ClpConstraintLinear(*this); } // Returns gradient int ClpConstraintLinear::gradient(const ClpSimplex *model, const double *solution, double *gradient, double &functionValue, double &offset, bool useScaling, bool refresh) const { if (refresh || !lastGradient_) { functionValue_ = 0.0; if (!lastGradient_) lastGradient_ = new double[numberColumns_]; CoinZeroN(lastGradient_, numberColumns_); bool scaling = (model && model->rowScale() && useScaling); if (!scaling) { for (int i = 0; i < numberCoefficients_; i++) { int iColumn = column_[i]; double value = solution[iColumn]; double coefficient = coefficient_[i]; functionValue_ += value * coefficient; lastGradient_[iColumn] = coefficient; } } else { // do scaling const double *columnScale = model->columnScale(); for (int i = 0; i < numberCoefficients_; i++) { int iColumn = column_[i]; double value = solution[iColumn]; // already scaled double coefficient = coefficient_[i] * columnScale[iColumn]; functionValue_ += value * coefficient; lastGradient_[iColumn] = coefficient; } } } functionValue = functionValue_; offset = 0.0; CoinMemcpyN(lastGradient_, numberColumns_, gradient); return 0; } // Resize constraint void ClpConstraintLinear::resize(int newNumberColumns) { if (numberColumns_ != newNumberColumns) { #ifndef NDEBUG int lastColumn = column_[numberCoefficients_ - 1]; #endif assert(newNumberColumns > lastColumn); delete[] lastGradient_; lastGradient_ = NULL; numberColumns_ = newNumberColumns; } } // Delete columns in constraint void ClpConstraintLinear::deleteSome(int numberToDelete, const int *which) { if (numberToDelete) { int i; char *deleted = new char[numberColumns_]; memset(deleted, 0, numberColumns_ * sizeof(char)); for (i = 0; i < numberToDelete; i++) { int j = which[i]; if (j >= 0 && j < numberColumns_ && !deleted[j]) { deleted[j] = 1; } } int n = 0; for (i = 0; i < numberCoefficients_; i++) { int iColumn = column_[i]; if (!deleted[iColumn]) { column_[n] = iColumn; coefficient_[n++] = coefficient_[i]; } } numberCoefficients_ = n; } } // Scale constraint void ClpConstraintLinear::reallyScale(const double *columnScale) { for (int i = 0; i < numberCoefficients_; i++) { int iColumn = column_[i]; coefficient_[i] *= columnScale[iColumn]; } } /* Given a zeroed array sets nonlinear columns to 1. Returns number of nonlinear columns */ int ClpConstraintLinear::markNonlinear(char *) const { return 0; } /* Given a zeroed array sets possible nonzero coefficients to 1. Returns number of nonzeros */ int ClpConstraintLinear::markNonzero(char *which) const { for (int i = 0; i < numberCoefficients_; i++) { int iColumn = column_[i]; which[iColumn] = 1; } return numberCoefficients_; } // Number of coefficients int ClpConstraintLinear::numberCoefficients() const { return numberCoefficients_; } /* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2 */