1 /**
2  * @file himmelblau_function_impl.hpp
3  * @author Suryoday Basak
4  *
5  * Implementation of the Beale function.
6  *
7  * ensmallen is free software; you may redistribute it and/or modify it under
8  * the terms of the 3-clause BSD license.  You should have received a copy of
9  * the 3-clause BSD license along with ensmallen.  If not, see
10  * http://www.opensource.org/licenses/BSD-3-Clause for more information.
11  */
12 #ifndef ENSMALLEN_PROBLEMS_HIMMELBLAU_FUNCTION_IMPL_HPP
13 #define ENSMALLEN_PROBLEMS_HIMMELBLAU_FUNCTION_IMPL_HPP
14 
15 // In case it hasn't been included yet.
16 #include "himmelblau_function.hpp"
17 
18 namespace ens {
19 namespace test {
20 
HimmelblauFunction()21 inline HimmelblauFunction::HimmelblauFunction() { /* Nothing to do here */ }
22 
Shuffle()23 inline void HimmelblauFunction::Shuffle() { /* Nothing to do here */ }
24 
25 template<typename MatType>
Evaluate(const MatType & coordinates,const size_t,const size_t) const26 typename MatType::elem_type HimmelblauFunction::Evaluate(
27     const MatType& coordinates,
28     const size_t /* begin */,
29     const size_t /* batchSize */) const
30 {
31   // Convenience typedef.
32   typedef typename MatType::elem_type ElemType;
33 
34   // For convenience; we assume these temporaries will be optimized out.
35   const ElemType x1 = coordinates(0);
36   const ElemType x2 = coordinates(1);
37 
38   const ElemType objective = std::pow(x1 * x1 + x2  - 11 , 2) +
39       std::pow(x1 + x2 * x2 - 7, 2);
40   return objective;
41 }
42 
43 template<typename MatType>
Evaluate(const MatType & coordinates) const44 typename MatType::elem_type HimmelblauFunction::Evaluate(
45     const MatType& coordinates) const
46 {
47   return Evaluate(coordinates, 0, NumFunctions());
48 }
49 
50 template<typename MatType, typename GradType>
Gradient(const MatType & coordinates,const size_t,GradType & gradient,const size_t) const51 inline void HimmelblauFunction::Gradient(const MatType& coordinates,
52                                          const size_t /* begin */,
53                                          GradType& gradient,
54                                          const size_t /* batchSize */) const
55 {
56   // Convenience typedef.
57   typedef typename MatType::elem_type ElemType;
58 
59   // For convenience; we assume these temporaries will be optimized out.
60   const ElemType x1 = coordinates(0);
61   const ElemType x2 = coordinates(1);
62 
63   // Aliases for different terms in the expression of the gradient
64   const ElemType x1Sq = x1 * x1;
65   const ElemType x2Sq = x2 * x2;
66 
67   gradient.set_size(2, 1);
68   gradient(0) = (4 * x1 * (x1Sq + x2 - 11)) + (2 * (x1 + x2Sq - 7));
69   gradient(1) = (2 * (x1Sq + x2 - 11)) + (4 * x2 * (x1 + x2Sq - 7));
70 }
71 
72 template<typename MatType, typename GradType>
Gradient(const MatType & coordinates,GradType & gradient)73 inline void HimmelblauFunction::Gradient(const MatType& coordinates,
74                                          GradType& gradient)
75 {
76   Gradient(coordinates, 0, gradient, 1);
77 }
78 
79 } // namespace test
80 } // namespace ens
81 
82 #endif
83