1/* $Id: ClpConstraintLinear.cpp 1665 2011-01-04 17:55:54Z lou $ */
2// Copyright (C) 2007, International Business Machines
3// Corporation and others. All Rights Reserved.
4// This code is licensed under the terms of the Eclipse Public License (EPL).
5
6#include "CoinPragma.hpp"
7#include "CoinHelperFunctions.hpp"
8#include "CoinIndexedVector.hpp"
9#include "ClpSimplex.hpp"
10#include "ClpConstraintLinear.hpp"
11#include "CoinSort.hpp"
12//#############################################################################
13// Constructors / Destructor / Assignment
14//#############################################################################
15
16//-------------------------------------------------------------------
17// Default Constructor
18//-------------------------------------------------------------------
19ClpConstraintLinear::ClpConstraintLinear ()
20 : ClpConstraint()
21{
22 type_ = 0;
23 column_ = NULL;
24 coefficient_ = NULL;
25 numberColumns_ = 0;
26 numberCoefficients_ = 0;
27}
28
29//-------------------------------------------------------------------
30// Useful Constructor
31//-------------------------------------------------------------------
32ClpConstraintLinear::ClpConstraintLinear (int row, int numberCoefficents ,
33 int numberColumns,
34 const int * column, const double * coefficient)
35 : ClpConstraint()
36{
37 type_ = 0;
38 rowNumber_ = row;
39 numberColumns_ = numberColumns;
40 numberCoefficients_ = numberCoefficents;
41 column_ = CoinCopyOfArray(column, numberCoefficients_);
42 coefficient_ = CoinCopyOfArray(coefficient, numberCoefficients_);
43 CoinSort_2(column_, column_ + numberCoefficients_, coefficient_);
44}
45
46//-------------------------------------------------------------------
47// Copy constructor
48//-------------------------------------------------------------------
49ClpConstraintLinear::ClpConstraintLinear (const ClpConstraintLinear & rhs)
50 : ClpConstraint(rhs)
51{
52 numberColumns_ = rhs.numberColumns_;
53 numberCoefficients_ = rhs.numberCoefficients_;
54 column_ = CoinCopyOfArray(rhs.column_, numberCoefficients_);
55 coefficient_ = CoinCopyOfArray(rhs.coefficient_, numberCoefficients_);
56}
57
58
59//-------------------------------------------------------------------
60// Destructor
61//-------------------------------------------------------------------
62ClpConstraintLinear::~ClpConstraintLinear ()
63{
64 delete [] column_;
65 delete [] coefficient_;
66}
67
68//----------------------------------------------------------------
69// Assignment operator
70//-------------------------------------------------------------------
71ClpConstraintLinear &
72ClpConstraintLinear::operator=(const ClpConstraintLinear& rhs)
73{
74 if (this != &rhs) {
75 delete [] column_;
76 delete [] coefficient_;
77 numberColumns_ = rhs.numberColumns_;
78 numberCoefficients_ = rhs.numberCoefficients_;
79 column_ = CoinCopyOfArray(rhs.column_, numberCoefficients_);
80 coefficient_ = CoinCopyOfArray(rhs.coefficient_, numberCoefficients_);
81 }
82 return *this;
83}
84//-------------------------------------------------------------------
85// Clone
86//-------------------------------------------------------------------
87ClpConstraint * ClpConstraintLinear::clone() const
88{
89 return new ClpConstraintLinear(*this);
90}
91
92// Returns gradient
93int
94ClpConstraintLinear::gradient(const ClpSimplex * model,
95 const double * solution,
96 double * gradient,
97 double & functionValue,
98 double & offset,
99 bool useScaling,
100 bool refresh) const
101{
102 if (refresh || !lastGradient_) {
103 functionValue_ = 0.0;
104 if (!lastGradient_)
105 lastGradient_ = new double[numberColumns_];
106 CoinZeroN(lastGradient_, numberColumns_);
107 bool scaling = (model && model->rowScale() && useScaling);
108 if (!scaling) {
109 for (int i = 0; i < numberCoefficients_; i++) {
110 int iColumn = column_[i];
111 double value = solution[iColumn];
112 double coefficient = coefficient_[i];
113 functionValue_ += value * coefficient;
114 lastGradient_[iColumn] = coefficient;
115 }
116 } else {
117 // do scaling
118 const double * columnScale = model->columnScale();
119 for (int i = 0; i < numberCoefficients_; i++) {
120 int iColumn = column_[i];
121 double value = solution[iColumn]; // already scaled
122 double coefficient = coefficient_[i] * columnScale[iColumn];
123 functionValue_ += value * coefficient;
124 lastGradient_[iColumn] = coefficient;
125 }
126 }
127 }
128 functionValue = functionValue_;
129 offset = 0.0;
130 CoinMemcpyN(lastGradient_, numberColumns_, gradient);
131 return 0;
132}
133// Resize constraint
134void
135ClpConstraintLinear::resize(int newNumberColumns)
136{
137 if (numberColumns_ != newNumberColumns) {
138#ifndef NDEBUG
139 int lastColumn = column_[numberCoefficients_-1];
140#endif
141 assert (newNumberColumns > lastColumn);
142 delete [] lastGradient_;
143 lastGradient_ = NULL;
144 numberColumns_ = newNumberColumns;
145 }
146}
147// Delete columns in constraint
148void
149ClpConstraintLinear::deleteSome(int numberToDelete, const int * which)
150{
151 if (numberToDelete) {
152 int i ;
153 char * deleted = new char[numberColumns_];
154 memset(deleted, 0, numberColumns_ * sizeof(char));
155 for (i = 0; i < numberToDelete; i++) {
156 int j = which[i];
157 if (j >= 0 && j < numberColumns_ && !deleted[j]) {
158 deleted[j] = 1;
159 }
160 }
161 int n = 0;
162 for (i = 0; i < numberCoefficients_; i++) {
163 int iColumn = column_[i];
164 if (!deleted[iColumn]) {
165 column_[n] = iColumn;
166 coefficient_[n++] = coefficient_[i];
167 }
168 }
169 numberCoefficients_ = n;
170 }
171}
172// Scale constraint
173void
174ClpConstraintLinear::reallyScale(const double * columnScale)
175{
176 for (int i = 0; i < numberCoefficients_; i++) {
177 int iColumn = column_[i];
178 coefficient_[i] *= columnScale[iColumn];
179 }
180}
181/* Given a zeroed array sets nonlinear columns to 1.
182 Returns number of nonlinear columns
183*/
184int
185ClpConstraintLinear::markNonlinear(char *) const
186{
187 return 0;
188}
189/* Given a zeroed array sets possible nonzero coefficients to 1.
190 Returns number of nonzeros
191*/
192int
193ClpConstraintLinear::markNonzero(char * which) const
194{
195 for (int i = 0; i < numberCoefficients_; i++) {
196 int iColumn = column_[i];
197 which[iColumn] = 1;
198 }
199 return numberCoefficients_;
200}
201// Number of coefficients
202int
203ClpConstraintLinear::numberCoefficients() const
204{
205 return numberCoefficients_;
206}
207