Interior-point-optimisation  1.0-1
Interior-pointoptimisationlibrary
QuadraticCombination.cc
Go to the documentation of this file.
1 /*
2  * $Id: QuadraticCombination.cc 177 2013-07-02 16:59:05Z 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 
25 
26 using namespace ipo_function::concrete;
27 
29  : FunctionBase { size }, coefficients { size, size }{ coefficients.set_all( 0.0 ); }
30 
31 void
32 QuadraticCombination::resize( size_t const size ){
33  size_t const OLDSIZE { coefficients.size1() };
34  if( OLDSIZE != size ){
35  size_t const MIN { std::min( size, OLDSIZE ) };
36  auto oldCoefficients = coefficients;
37  coefficients = gsl::matrix { size, size };
38  // copy old values
39  for( size_t row { 0 }; row < MIN; ++row )
40  for( size_t col { 0 }; col < MIN; ++col )
41  coefficients.set( row, col, oldCoefficients.get( row, col ) );
42  // zero new values
43  for( size_t row { MIN }; row < size; ++row )
44  for( size_t col { 0 }; col < size; ++col ){
45  coefficients.set( row, col, 0 );
46  if( row != col ) coefficients.set( col, row, 0 );
47  }
48  }
49 }
50 
51 void
52 QuadraticCombination::setCoefficient( size_t const index, double const value ){
53  if( index > coefficients.size1() ){
54  using namespace ipo;
55  throw IPOE( "ipo_function::concrete::QuadraticCombination::setCoefficient(): "
56  "index out of range." );
57  }
58  coefficients.set( index, index, value );
59 }
60 
61 void
62 QuadraticCombination::setCoefficient( size_t const row, size_t const col, double const value ){
63  if( row == col ){
64  setCoefficient( row, value );
65  return;
66  }
67  if( row > coefficients.size1() ){
68  using namespace ipo;
69  throw IPOE( "ipo_function::concrete::QuadraticCombination::setCoefficient(): "
70  "row out of range." );
71  }
72  if( col > coefficients.size2() ){
73  using namespace ipo;
74  throw IPOE( "ipo_function::concrete::QuadraticCombination::setCoefficient(): "
75  "col out of range." );
76  }
77  coefficients.set( row, col, value / 2.0 );
78  coefficients.set( col, row, value / 2.0 );
79 }
80 
81 double
82 QuadraticCombination::getCoefficient( size_t const index ) const {
83  if( index > coefficients.size1() ){
84  using namespace ipo;
85  throw IPOE( "ipo_function::concrete::QuadraticCombination::getCoefficient(): "
86  "index out of range." );
87  }
88  return coefficients.get( index, index );
89 }
90 
91 double
92 QuadraticCombination::getCoefficient( size_t const row, size_t const col ) const {
93  if( row == col ) return getCoefficient( row );
94  if( row > coefficients.size1() ){
95  using namespace ipo;
96  throw IPOE( "ipo_function::concrete::QuadraticCombination::getCoefficient(): "
97  "row out of range." );
98  }
99  if( col > coefficients.size2() ){
100  using namespace ipo;
101  throw IPOE( "ipo_function::concrete::QuadraticCombination::getCoefficient(): "
102  "col out of range." );
103  }
104  return 2 * coefficients.get( row, col );
105 }
106 
107 gsl::matrix const&
109  return coefficients;
110 }
111 
112 void
113 QuadraticCombination::setCoefficients( gsl::matrix const& matrix ){
114  if( matrix.size1() != coefficients.size2() ){
115  using namespace ipo;
116  std::ostringstream
117  ost { "ipo_function::concrete::QuadraticCombination::setCoefficients(): " };
118  ost << "number of rows " << matrix.size1();
119  ost << " and number of columns " << matrix.size2();
120  ost << " of matrix do not match.";
121  throw IPOE( ost.str() );
122  }
123  if( matrix.size1() != coefficients.size1() ){
124  using namespace ipo;
125  std::ostringstream
126  ost { "ipo_function::concrete::QuadraticCombination::setCoefficients(): " };
127  ost << "matrix size " << matrix.size1();
128  ost << " and coefficients size " << coefficients.size1();
129  ost << " do not match.";
130  throw IPOE( ost.str() );
131  }
132  for( size_t row { 0 }; row < matrix.size1(); ++row ){
133  for( size_t col { row }; col < matrix.size1(); ++col ){
134  if( matrix.get( row, col ) != matrix.get( col, row ) ){
135  using namespace ipo;
136  std::ostringstream
137  ost { "ipo_function::concrete::QuadraticCombination::setCoefficients(): " };
138  ost << "matrix is not symmetric.";
139  throw IPOE( ost.str() );
140  }
141  }
142  }
143  coefficients.memcpy( matrix );
144 }
145 
146 double
147 QuadraticCombination::operator()( gsl::vector const& vector ){
148  if( vector.size() != coefficients.size1() ){
149  using namespace ipo;
150  std::ostringstream ost { "ipo_function::concrete::QuadraticCombination::operator()(): " };
151  ost << "vector size " << vector.size();
152  ost << " and coefficients size " << coefficients.size1();
153  ost << " do not match.";
154  throw IPOE( ost.str() );
155  }
156  double result { 0.0 };
157  gsl::vector temp( vector.size() );
158  gsl::blas::dsymv( gsl::blas::Upper, 1, coefficients, vector, 0, temp );
159  gsl::blas::ddot( temp, vector, &result );
160  return result;
161 }
162 
163 gsl::vector
164 QuadraticCombination::gradient( gsl::vector const& vector ){
165  size_t const SIZE = vector.size();
166  if( SIZE != coefficients.size1() ){
167  using namespace ipo;
168  std::ostringstream ost( "ipo_function::concrete::QuadraticCombination::gradient(): " );
169  ost << "vector size " << vector.size();
170  ost << " and coefficients size " << coefficients.size1();
171  ost << " do not match.";
172  throw IPOE( ost.str() );
173  }
174  // Computer the gradient
175  if( functionGradient.size() != SIZE )
176  functionGradient = gsl::vector( SIZE );
177  for( size_t i { 0 }; i < SIZE; ++ i ){
178  auto const row = coefficients.row( i );
179  double result { 0.0 };
180  gsl::blas::ddot( row, vector, &result );
181  functionGradient[i] = 2.0 * result;
182  }
183  return functionGradient;
184 }
185 
186 gsl::matrix
187 QuadraticCombination::hessian( gsl::vector const& vector ){
188  size_t const SIZE = vector.size();
189  if( SIZE != coefficients.size1() ){
190  using namespace ipo;
191  std::ostringstream ost( "ipo_function::concrete::QuadraticCombination::hessian(): " );
192  ost << "vector size " << vector.size();
193  ost << " and coefficients size " << coefficients.size1();
194  ost << " do not match.";
195  throw IPOE( ost.str() );
196  }
197  if( functionHessian.size1() != SIZE or functionHessian.size2() != SIZE )
198  functionHessian = gsl::matrix { SIZE, SIZE };
199  functionHessian.memcpy( coefficients );
200  functionHessian.scale( 2.0 );
201  return functionHessian;
202 }
203 
204 void
205 QuadraticCombination::setVector( gsl::vector const& vector ){
206  size_t const SIZE = vector.size();
207  if( SIZE != coefficients.size1() ){
208  using namespace ipo;
209  std::ostringstream ost( "ipo_function::concrete::QuadraticaticCombination::setVector(): " );
210  ost << "vector size " << vector.size();
211  ost << " and coefficients size " << coefficients.size1();
212  ost << " do not match.";
213  throw IPOE( ost.str() );
214  }
215  gsl::vector temp( vector.size() );
216  gsl::blas::dsymv( gsl::blas::Upper, 1.0, coefficients, vector, 0.0, temp );
217  gsl::blas::ddot( temp, vector, &functionValue );
218  if( functionGradient.size() != SIZE )
219  functionGradient = gsl::vector( SIZE );
220  for( size_t i { 0 }; i < SIZE; ++ i ){
221  auto const row = coefficients.row( i );
222  double result { 0.0 };
223  gsl::blas::ddot( row, vector, &result );
224  functionGradient[i] = 2.0 * result;
225  }
226  if( functionHessian.size1() != SIZE or functionHessian.size2() != SIZE )
227  functionHessian = gsl::matrix { SIZE, SIZE };
228  functionHessian.memcpy( coefficients );
229  functionHessian.scale( 2.0 );
230 }
double functionValue
The function value.
gsl::matrix const & getCoefficients() const
Get the coefficients as a matrix by reference.
gsl::vector functionGradient
The gradient value.
virtual gsl::matrix hessian() const
virtual gsl::vector gradient() const
virtual double value() const
gsl::matrix functionHessian
The Hessian value.
void resize(size_t const size)
Resize the matrix of coefficients.
Namespace to hold concrete functions.
#define IPOE(message)
Macro to allow file and line names in exceptions.
void setCoefficients(gsl::matrix const &matrix)
Set coefficients from a matrix.
QuadraticCombination(size_t const size=0)
The constructor sets up function as a quadratic combination of size entries.
gsl::matrix coefficients
The matrix of coefficients;.
double getCoefficient(size_t const index) const
Get the value of a coefficient on the diagonal.
virtual double operator()(gsl::vector const &vector)
The function operator: computes the sum of the vector entries.
virtual void setVector(gsl::vector const &vector)
Set a vector and compute function value, gradient and Hessian efficiently.
size_t const size
Size of vector arguments to supply to subclass functions.
void setCoefficient(size_t const index, double const value)
Set the value of a coefficient on the diagonal.
This namespace holds all the interior-point optimisation classes.
Definition: Array.hpp:28