limp-cbc-0.3.2.0: cbits/coin/ClpConstraintLinear.cpp
/* $Id: ClpConstraintLinear.cpp 1665 2011-01-04 17:55:54Z lou $ */
// 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_;
}