Rosenbrock.h
Go to the documentation of this file.
1 //===========================================================================
2 /*!
3  *
4  *
5  * \brief Generalized Rosenbrock benchmark function
6  *
7  * This non-convex benchmark function for real-valued optimization is
8  * a generalization from two to multiple dimensions of a classic
9  * function first proposed in:
10  *
11  * H. H. Rosenbrock. An automatic method for finding the greatest or
12  * least value of a function. The Computer Journal 3: 175-184, 1960
13  *
14  *
15  *
16  * \author -
17  * \date -
18  *
19  *
20  * \par Copyright 1995-2017 Shark Development Team
21  *
22  * <BR><HR>
23  * This file is part of Shark.
24  * <http://shark-ml.org/>
25  *
26  * Shark is free software: you can redistribute it and/or modify
27  * it under the terms of the GNU Lesser General Public License as published
28  * by the Free Software Foundation, either version 3 of the License, or
29  * (at your option) any later version.
30  *
31  * Shark is distributed in the hope that it will be useful,
32  * but WITHOUT ANY WARRANTY; without even the implied warranty of
33  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34  * GNU Lesser General Public License for more details.
35  *
36  * You should have received a copy of the GNU Lesser General Public License
37  * along with Shark. If not, see <http://www.gnu.org/licenses/>.
38  *
39  */
40 //===========================================================================
41 
42 #ifndef SHARK_OBJECTIVEFUNCTIONS_BENCHMARK_ROSENBROCK_H
43 #define SHARK_OBJECTIVEFUNCTIONS_BENCHMARK_ROSENBROCK_H
44 
46 #include <shark/Core/Random.h>
47 
48 namespace shark {
49 /*! \brief Generalized Rosenbrock benchmark function
50 *
51 * This non-convex benchmark function for real-valued optimization is a
52 * generalization from two to multiple dimensions of a classic
53 * function first proposed in:
54 *
55 * H. H. Rosenbrock. An automatic method for finding the greatest or
56 * least value of a function. The Computer Journal 3: 175-184,
57 * 1960
58 */
60 
61  /// \brief Constructs the problem
62  ///
63  /// \param dimensions number of dimensions to optimize
64  /// \param initialSpread spread of the initial starting point
65  Rosenbrock(std::size_t dimensions=23, double initialSpread = 1.0)
66  :m_numberOfVariables(dimensions), m_initialSpread(initialSpread) {
70  }
71 
72  /// \brief From INameable: return the class name.
73  std::string name() const
74  { return "Rosenbrock"; }
75 
76  std::size_t numberOfVariables()const{
77  return m_numberOfVariables;
78  }
79 
81  return true;
82  }
83 
85  m_numberOfVariables = numberOfVariables;
86  }
87 
89  RealVector x(numberOfVariables());
90 
91  for (std::size_t i = 0; i < x.size(); i++) {
92  x(i) = random::uni(*mep_rng, 0, m_initialSpread );
93  }
94  return x;
95  }
96 
97  double eval( const SearchPointType & p ) const {
99 
100  double sum = 0;
101 
102  for( std::size_t i = 0; i < p.size()-1; i++ ) {
103  sum += 100*sqr( p(i+1) - sqr( p( i ) ) ) +sqr( 1. - p( i ) );
104  }
105 
106  return( sum );
107  }
108 
109  virtual ResultType evalDerivative( const SearchPointType & p, FirstOrderDerivative & derivative )const {
110  double result = eval(p);
111  size_t size = p.size();
112  derivative.resize(size);
113  derivative(0) = 2*( p(0) - 1 ) - 400 * ( p(1) - sqr( p(0) ) ) * p(0);
114  derivative(size-1) = 200 * ( p(size - 1) - sqr( p( size - 2 ) ) ) ;
115  for(size_t i=1; i != size-1; ++i){
116  derivative( i ) = 2 * ( p(i) - 1 ) - 400 * (p(i+1) - sqr( p(i) ) ) * p( i )+200 * ( p( i )- sqr( p(i-1) ) );
117  }
118  return result;
119 
120  }
121 
122  virtual ResultType evalDerivative( const SearchPointType & p, SecondOrderDerivative & derivative )const {
123  double result = eval(p);
124  size_t size = p.size();
125  derivative.gradient.resize(size);
126  derivative.hessian.resize(size,size);
127  derivative.hessian.clear();
128 
129  derivative.gradient(0) = 2*( p(0) - 1 ) - 400 * ( p(1) - sqr( p(0) ) ) * p(0);
130  derivative.gradient(size-1) = 200 * ( p(size - 1) - sqr( p( size - 2 ) ) ) ;
131 
132  derivative.hessian(0,0) = 2 - 400* (p(1) - 3*sqr(p(0))) ;
133  derivative.hessian(0,1) = -400 * p(0) ;
134 
135  derivative.hessian(size-1,size-1) = 200;
136  derivative.hessian(size-1,size-2) = -400 * p( size - 2 );
137 
138  for(size_t i=1; i != size-1; ++i){
139  derivative.gradient( i ) = 2 * ( p(i) - 1 ) - 400 * (p(i+1) - sqr( p(i) ) ) * p( i )+200 * ( p( i )- sqr( p(i-1) ) );
140 
141  derivative.hessian(i,i) = 202 - 400 * ( p(i+1) - 3 * sqr(p(i)));
142  derivative.hessian(i,i+1) = - 400 * ( p(i) );
143  derivative.hessian(i,i-1) = - 400 * ( p(i-1) );
144 
145  }
146  return result;
147  }
148 
149 private:
150  std::size_t m_numberOfVariables;
151  double m_initialSpread;
152 };
153 
154 }
155 
156 #endif