Interior-point-optimisation  1.0-1
Interior-pointoptimisationlibrary
LinearConstraint.cc
Go to the documentation of this file.
1 /*
2  * $Id: LinearConstraint.cc 205 2014-10-29 09:57:25Z jdl3 $
3  * Copyright (C) 2013 John D Lamb
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or (at
8  * your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 
20 #ifdef HAVE_CONFIG_H
21 # include<config.h>
22 #endif
23 
24 #include"LinearConstraint.hpp"
25 
26 using namespace ipo;
27 
29  : Constraint { model,
31  name }{}
32 
34  : Constraint { model,
36  name }{}
37 
38 void
39 LinearConstraint::setCoefficient( Variable const& variable, double const value ){
40  auto& variables = getVariables();
41  auto p = std::find( variables.begin(), variables.end(), variable );
42  if( variables.end() == p ){
43  using namespace ipo;
44  std::ostringstream ost( "ipo::LinearConstraint::setCoefficient(): " );
45  ost << "variable " << variable.getName()
46  << " is not a variable of LinearConstraint object.";
47  throw IPOE( ost.str() );
48  }
49  auto q = dynamic_cast<ipo_function::concrete::LinearCombination*>( getFunction() );
50  if( nullptr == q ){ // should always be false
51  using namespace ipo;
52  throw IPOE( "ipo::LinearConstraint::setCoefficient(): "
53  "function must be an ipo_function::concrete::LinearCombination." );
54  }
55  q->resize( getVariables().size() );
56  q->setCoefficient( p - variables.begin(), value );
57 }
58 
59 double
60 LinearConstraint::getCoefficient( Variable const& variable ) const {
61  auto const& variables = const_cast<LinearConstraint*>( this )->getVariables();
62  auto p = std::find( variables.begin(), variables.end(), variable );
63  if( variables.end() == p ){
64  using namespace ipo;
65  std::ostringstream ost( "ipo::LinearConstraint::getCoefficient(): " );
66  ost << "variable " << variable.getName()
67  << " is not a variable of LinearConstraint object.";
68  throw IPOE( ost.str() );
69  }
70  auto const q = dynamic_cast<ipo_function::concrete::
71  LinearCombination*>( const_cast<LinearConstraint*>( this )->getFunction() );
72  if( nullptr == q ){ // should always be false
73  using namespace ipo;
74  throw IPOE( "ipo::LinearConstraint::getCoefficient(): "
75  "function must be an ipo_function::concrete::LinearCombination." );
76  }
77  q->resize( const_cast<LinearConstraint*>( this )->getVariables().size() );
78  return q->getCoefficient( p - variables.begin() );
79 }
80 
81 gsl::vector const&
83  auto const p = dynamic_cast<ipo_function::concrete::LinearCombination*>
84  ( const_cast<LinearConstraint*>( this )->getFunction() );
85  if( nullptr == p ){ // should always be false
86  using namespace ipo;
87  throw IPOE( "ipo::LinearConstraint::notify(): "
88  "function must be an ipo_function::concrete::LinearCombination." );
89  }
90  p->resize( const_cast<LinearConstraint*>( this )->getVariables().size() );
91  try {
92  return p->getCoefficients();
93  } catch( IPOException ){
94  RETHROW( "ipo::getCoefficients()" );
95  }
96 }
97 
100  auto const p = dynamic_cast<ipo_function::concrete::LinearCombination*>
101  ( const_cast<LinearConstraint*>( this )->ModelFunction::getFunction() );
102  if( nullptr == p ){ // should always be false
103  using namespace ipo;
104  throw IPOE( "ipo::LinearConstraint::notify(): "
105  "function must be an ipo_function::concrete::LinearCombination." );
106  }
107  p->resize( getVariables().size() );
108  return function.get();
109 }
110 
111 void
113  if( upperBound < data->lowerBound )
114  throw IPOE( "ipo::LinearConstraint::setUpperBound(): "
115  "upper bound must be at least lower." );
116  // Set to true if this has to be removed from a list in model
117  bool const removed { (data->lowerBound == data->upperBound)
118  != (data->lowerBound == upperBound)
119  and const_cast<Model*>( dynamic_cast<Model const*>( getModel() ) )->
120  removeConstraint( *this ) };
121  data->upperBound = upperBound;
122  // May have to add back
123  if( removed )
124  const_cast<Model*>( dynamic_cast<Model const*>( getModel() ) )->addConstraint( *this );
125 }
126 
127 void
129  if( data->upperBound < lowerBound )
130  throw IPOE( "ipo::LinearConstraint::setLowerBound(): "
131  "upper bound must be at least lower." );
132  // Set to true if this has to be removed from a list in model
133  bool const removed { (data->lowerBound == data->upperBound)
134  != (lowerBound == data->upperBound)
135  and const_cast<Model*>( dynamic_cast<Model const*>( getModel() ) )->
136  removeConstraint( *this ) };
137  data->lowerBound = lowerBound;
138  // May have to add back
139  if( removed )
140  const_cast<Model*>( dynamic_cast<Model const*>( getModel() ) )->addConstraint( *this );
141 }
142 
143 bool
145  return getUpperBound() == getLowerBound();
146 }
147 
148 void
150  // Set to true if this has to be removed from a list in model
151  bool const removed { (data->lowerBound != data->upperBound)
152  and const_cast<Model*>( dynamic_cast<Model const*>( getModel() ) )->
153  removeConstraint( *this ) };
154  data->lowerBound = value;
155  data->upperBound = value;
156  // May have to add back
157  if( removed )
158  const_cast<Model*>( dynamic_cast<Model const*>( getModel() ) )->addConstraint( *this );
159 }
160 
161 void
162 LinearConstraint::setCoefficients( gsl::vector const& vector ){
163  size_t const SIZE { getVariables().size() };
164  if( SIZE != vector.size() ){
165  using namespace ipo;
166  std::ostringstream ost( "ipo::LinearConstraint::setCoefficients(): " );
167  ost << "constraint has " << SIZE << " variables"
168  << " but vector of " << vector.size() << "coefficients supplied.";
169  throw IPOE( ost.str() );
170  }
171  auto q = dynamic_cast<ipo_function::concrete::LinearCombination*>( getFunction() );
172  if( nullptr == q ){ // should always be false
173  using namespace ipo;
174  throw IPOE( "ipo::LinearConstraint::setCoefficient(): "
175  "function must be an ipo_function::concrete::LinearCombination." );
176  }
177  q->resize( SIZE );
178  for( size_t i { 0 }; i < SIZE; ++i ) q->setCoefficient( i, vector.get( i ) );
179 }
void setValue(double const value)
Set value of Constraint.
virtual void setUpperBound(double const upperBound)
Set upper bound of Constraint.
Shared pointer to ipo::Function object.
double getCoefficient(Variable const &variable) const
Get the coefficient of variable.
ModelBase & model
A Model to attach this to.
Definition: Var.hpp:101
This class provides function objects representing linear combinations of the elements of their vector...
size_type size() const
Get size of array.
Definition: Array.hpp:400
bool isEqualityConstraint() const
Find if this is an equality constraint (upperBound = lowerBound).
Array & getVariables()
Get variables used by Objective function.
Definition: Objective.cc:75
void setCoefficients(gsl::vector const &vector)
Set all the coefficients of this LinearConstraint.
std::shared_ptr< Data > data
The objective data.
Definition: Objective.hpp:205
Namespace to hold concrete functions.
Class to represent a linear combination as an Objective or Constraint.
#define IPOE(message)
Macro to allow file and line names in exceptions.
virtual void setLowerBound(double const lowerBound)
Set lower bound of Constraint.
std::string getName() const
Get name of variable.
Definition: Variable.cc:49
Class for a constraint function.
Definition: Constraint.hpp:40
Model an interior-point optimisation problem.
Definition: Model.hpp:325
LinearConstraint(detail::ModelBase &model, std::string const &name)
The constructor creates a new object with no variables.
Abstract base class for model.
Definition: Var.hpp:39
#define RETHROW(function)
Macro to allow file and line names in exceptions.
double getLowerBound() const
Get lower bound of Constraint.
Definition: Constraint.cc:58
double value() const noexcept
Value of the objective function at the current value of the variables.
Definition: Objective.cc:209
This class computes a function at a vector.
Definition: Function.hpp:38
This class represents a variable.
Definition: Variable.hpp:36
Objects of this class are used to store information about an exception generated by ipo objects and f...
void setCoefficient(Variable const &variable, double const value)
Set the coefficient of variable.
data lowerBound
Definition: Variable.cc:39
double getUpperBound() const
Get upper bound of Constraint.
Definition: Constraint.cc:53
data name
Definition: Variable.cc:37
data upperBound
Definition: Variable.cc:38
ModelBase const *const getModel() const
Get pointer to model.
Definition: Var.hpp:88
virtual ::ipo_function::Function * getFunction()
Get function.
void addConstraint(Constraint &constraint)
Add a constraint.
Definition: Model.cc:48
gsl::vector const & getCoefficients() const
Get all the coefficients of this LinearConstraint.
This namespace holds all the interior-point optimisation classes.
Definition: Array.hpp:28