source: trunk/Clp/src/ClpConstraintQuadratic.cpp @ 2385

Last change on this file since 2385 was 2385, checked in by unxusr, 4 months ago

formatting

  • Property svn:keywords set to Id
File size: 8.9 KB
Line 
1/* $Id: ClpConstraintQuadratic.cpp 2385 2019-01-06 19:43:06Z unxusr $ */
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 "ClpConstraintQuadratic.hpp"
11#include "CoinSort.hpp"
12//#############################################################################
13// Constructors / Destructor / Assignment
14//#############################################################################
15
16//-------------------------------------------------------------------
17// Default Constructor
18//-------------------------------------------------------------------
19ClpConstraintQuadratic::ClpConstraintQuadratic()
20  : ClpConstraint()
21{
22  type_ = 0;
23  start_ = NULL;
24  column_ = NULL;
25  coefficient_ = NULL;
26  numberColumns_ = 0;
27  numberCoefficients_ = 0;
28  numberQuadraticColumns_ = 0;
29}
30
31//-------------------------------------------------------------------
32// Useful Constructor
33//-------------------------------------------------------------------
34ClpConstraintQuadratic::ClpConstraintQuadratic(int row, int numberQuadraticColumns,
35  int numberColumns, const CoinBigIndex *start,
36  const int *column, const double *coefficient)
37  : ClpConstraint()
38{
39  type_ = 0;
40  rowNumber_ = row;
41  numberColumns_ = numberColumns;
42  numberQuadraticColumns_ = numberQuadraticColumns;
43  start_ = CoinCopyOfArray(start, numberQuadraticColumns + 1);
44  CoinBigIndex numberElements = start_[numberQuadraticColumns_];
45  column_ = CoinCopyOfArray(column, numberElements);
46  coefficient_ = CoinCopyOfArray(coefficient, numberElements);
47  char *mark = new char[numberQuadraticColumns_];
48  memset(mark, 0, numberQuadraticColumns_);
49  int iColumn;
50  for (iColumn = 0; iColumn < numberQuadraticColumns_; iColumn++) {
51    CoinBigIndex j;
52    for (j = start_[iColumn]; j < start_[iColumn + 1]; j++) {
53      int jColumn = column_[j];
54      if (jColumn >= 0) {
55        assert(jColumn < numberQuadraticColumns_);
56        mark[jColumn] = 1;
57      }
58      mark[iColumn] = 1;
59    }
60  }
61  numberCoefficients_ = 0;
62  for (iColumn = 0; iColumn < numberQuadraticColumns_; iColumn++) {
63    if (mark[iColumn])
64      numberCoefficients_++;
65  }
66  delete[] mark;
67}
68
69//-------------------------------------------------------------------
70// Copy constructor
71//-------------------------------------------------------------------
72ClpConstraintQuadratic::ClpConstraintQuadratic(const ClpConstraintQuadratic &rhs)
73  : ClpConstraint(rhs)
74{
75  numberColumns_ = rhs.numberColumns_;
76  numberCoefficients_ = rhs.numberCoefficients_;
77  numberQuadraticColumns_ = rhs.numberQuadraticColumns_;
78  start_ = CoinCopyOfArray(rhs.start_, numberQuadraticColumns_ + 1);
79  CoinBigIndex numberElements = start_[numberQuadraticColumns_];
80  column_ = CoinCopyOfArray(rhs.column_, numberElements);
81  coefficient_ = CoinCopyOfArray(rhs.coefficient_, numberElements);
82}
83
84//-------------------------------------------------------------------
85// Destructor
86//-------------------------------------------------------------------
87ClpConstraintQuadratic::~ClpConstraintQuadratic()
88{
89  delete[] start_;
90  delete[] column_;
91  delete[] coefficient_;
92}
93
94//----------------------------------------------------------------
95// Assignment operator
96//-------------------------------------------------------------------
97ClpConstraintQuadratic &
98ClpConstraintQuadratic::operator=(const ClpConstraintQuadratic &rhs)
99{
100  if (this != &rhs) {
101    delete[] start_;
102    delete[] column_;
103    delete[] coefficient_;
104    numberColumns_ = rhs.numberColumns_;
105    numberCoefficients_ = rhs.numberCoefficients_;
106    numberQuadraticColumns_ = rhs.numberQuadraticColumns_;
107    start_ = CoinCopyOfArray(rhs.start_, numberQuadraticColumns_ + 1);
108    CoinBigIndex numberElements = start_[numberQuadraticColumns_];
109    column_ = CoinCopyOfArray(rhs.column_, numberElements);
110    coefficient_ = CoinCopyOfArray(rhs.coefficient_, numberElements);
111  }
112  return *this;
113}
114//-------------------------------------------------------------------
115// Clone
116//-------------------------------------------------------------------
117ClpConstraint *ClpConstraintQuadratic::clone() const
118{
119  return new ClpConstraintQuadratic(*this);
120}
121
122// Returns gradient
123int ClpConstraintQuadratic::gradient(const ClpSimplex *model,
124  const double *solution,
125  double *gradient,
126  double &functionValue,
127  double &offset,
128  bool useScaling,
129  bool refresh) const
130{
131  if (refresh || !lastGradient_) {
132    offset_ = 0.0;
133    functionValue_ = 0.0;
134    if (!lastGradient_)
135      lastGradient_ = new double[numberColumns_];
136    CoinZeroN(lastGradient_, numberColumns_);
137    bool scaling = (model && model->rowScale() && useScaling);
138    if (!scaling) {
139      int iColumn;
140      for (iColumn = 0; iColumn < numberQuadraticColumns_; iColumn++) {
141        double valueI = solution[iColumn];
142        CoinBigIndex j;
143        for (j = start_[iColumn]; j < start_[iColumn + 1]; j++) {
144          int jColumn = column_[j];
145          if (jColumn >= 0) {
146            double valueJ = solution[jColumn];
147            double elementValue = coefficient_[j];
148            if (iColumn != jColumn) {
149              offset_ -= valueI * valueJ * elementValue;
150              double gradientI = valueJ * elementValue;
151              double gradientJ = valueI * elementValue;
152              lastGradient_[iColumn] += gradientI;
153              lastGradient_[jColumn] += gradientJ;
154            } else {
155              offset_ -= 0.5 * valueI * valueI * elementValue;
156              double gradientI = valueI * elementValue;
157              lastGradient_[iColumn] += gradientI;
158            }
159          } else {
160            // linear part
161            lastGradient_[iColumn] += coefficient_[j];
162            functionValue_ += valueI * coefficient_[j];
163          }
164        }
165      }
166      functionValue_ -= offset_;
167    } else {
168      abort();
169      // do scaling
170      const double *columnScale = model->columnScale();
171      for (int i = 0; i < numberCoefficients_; i++) {
172        int iColumn = column_[i];
173        double value = solution[iColumn]; // already scaled
174        double coefficient = coefficient_[i] * columnScale[iColumn];
175        functionValue_ += value * coefficient;
176        lastGradient_[iColumn] = coefficient;
177      }
178    }
179  }
180  functionValue = functionValue_;
181  offset = offset_;
182  CoinMemcpyN(lastGradient_, numberColumns_, gradient);
183  return 0;
184}
185// Resize constraint
186void ClpConstraintQuadratic::resize(int newNumberColumns)
187{
188  if (numberColumns_ != newNumberColumns) {
189    abort();
190#ifndef NDEBUG
191    int lastColumn = column_[numberCoefficients_ - 1];
192#endif
193    assert(newNumberColumns > lastColumn);
194    delete[] lastGradient_;
195    lastGradient_ = NULL;
196    numberColumns_ = newNumberColumns;
197  }
198}
199// Delete columns in  constraint
200void ClpConstraintQuadratic::deleteSome(int numberToDelete, const int *which)
201{
202  if (numberToDelete) {
203    abort();
204    int i;
205    char *deleted = new char[numberColumns_];
206    memset(deleted, 0, numberColumns_ * sizeof(char));
207    for (i = 0; i < numberToDelete; i++) {
208      int j = which[i];
209      if (j >= 0 && j < numberColumns_ && !deleted[j]) {
210        deleted[j] = 1;
211      }
212    }
213    int n = 0;
214    for (i = 0; i < numberCoefficients_; i++) {
215      int iColumn = column_[i];
216      if (!deleted[iColumn]) {
217        column_[n] = iColumn;
218        coefficient_[n++] = coefficient_[i];
219      }
220    }
221    numberCoefficients_ = n;
222  }
223}
224// Scale constraint
225void ClpConstraintQuadratic::reallyScale(const double *)
226{
227  abort();
228}
229/* Given a zeroed array sets nonquadratic columns to 1.
230   Returns number of nonlinear columns
231*/
232int ClpConstraintQuadratic::markNonlinear(char *which) const
233{
234  int iColumn;
235  for (iColumn = 0; iColumn < numberQuadraticColumns_; iColumn++) {
236    CoinBigIndex j;
237    for (j = start_[iColumn]; j < start_[iColumn + 1]; j++) {
238      int jColumn = column_[j];
239      if (jColumn >= 0) {
240        assert(jColumn < numberQuadraticColumns_);
241        which[jColumn] = 1;
242        which[iColumn] = 1;
243      }
244    }
245  }
246  int numberCoefficients = 0;
247  for (iColumn = 0; iColumn < numberQuadraticColumns_; iColumn++) {
248    if (which[iColumn])
249      numberCoefficients++;
250  }
251  return numberCoefficients;
252}
253/* Given a zeroed array sets possible nonzero coefficients to 1.
254   Returns number of nonzeros
255*/
256int ClpConstraintQuadratic::markNonzero(char *which) const
257{
258  int iColumn;
259  for (iColumn = 0; iColumn < numberQuadraticColumns_; iColumn++) {
260    CoinBigIndex j;
261    for (j = start_[iColumn]; j < start_[iColumn + 1]; j++) {
262      int jColumn = column_[j];
263      if (jColumn >= 0) {
264        assert(jColumn < numberQuadraticColumns_);
265        which[jColumn] = 1;
266      }
267      which[iColumn] = 1;
268    }
269  }
270  int numberCoefficients = 0;
271  for (iColumn = 0; iColumn < numberQuadraticColumns_; iColumn++) {
272    if (which[iColumn])
273      numberCoefficients++;
274  }
275  return numberCoefficients;
276}
277// Number of coefficients
278int ClpConstraintQuadratic::numberCoefficients() const
279{
280  return numberCoefficients_;
281}
282
283/* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
284*/
Note: See TracBrowser for help on using the repository browser.