1 /**
2  * @file beale_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_BEALE_FUNCTION_IMPL_HPP
13 #define ENSMALLEN_PROBLEMS_BEALE_FUNCTION_IMPL_HPP
14 
15 // In case it hasn't been included yet.
16 #include "beale_function.hpp"
17 
18 namespace ens {
19 namespace test {
20 
BealeFunction()21 inline BealeFunction::BealeFunction() { /* Nothing to do here */ }
22 
Shuffle()23 inline void BealeFunction::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 BealeFunction::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(1.5 - x1 + x1 * x2, 2) +
39       std::pow(2.25 - x1 + x1 * x2 * x2, 2) +
40       std::pow(2.625 - x1 + x1 * pow(x2, 3), 2);
41 
42   return objective;
43 }
44 
45 template<typename MatType>
Evaluate(const MatType & coordinates) const46 typename MatType::elem_type BealeFunction::Evaluate(
47     const MatType& coordinates) const
48 {
49   return Evaluate(coordinates, 0, NumFunctions());
50 }
51 
52 template<typename MatType, typename GradType>
Gradient(const MatType & coordinates,const size_t,GradType & gradient,const size_t) const53 inline void BealeFunction::Gradient(const MatType& coordinates,
54                                     const size_t /* begin */,
55                                     GradType& gradient,
56                                     const size_t /* batchSize */) const
57 {
58   // Convenience typedef.
59   typedef typename MatType::elem_type ElemType;
60 
61   // For convenience; we assume these temporaries will be optimized out.
62   const ElemType x1 = coordinates(0);
63   const ElemType x2 = coordinates(1);
64 
65   // Aliases for different terms in the expression of the gradient.
66   const ElemType x2Sq = x2 * x2;
67   const ElemType x2Cub = pow(x2, 3);
68 
69   gradient.set_size(2, 1);
70   gradient(0) = ((2 * x2 - 2) * (x1 * x2 - x1 + 1.5)) +
71       ((2 * x2Sq - 2) * (x1 * x2Sq - x1 + 2.25)) +
72       ((2 * x2Cub - 2) * (x1 * x2Cub - x1 + 2.625));
73   gradient(1) = (6 * x1 * x2Sq * (x1 * x2Cub - x1 + 2.625)) +
74       (4 * x1 * x2 * (x1 * x2Sq - x1 + 2.25)) +
75       (2 * x1 * (x1 * x2 - x1 + 1.5));
76 }
77 
78 template<typename MatType, typename GradType>
Gradient(const MatType & coordinates,GradType & gradient)79 inline void BealeFunction::Gradient(const MatType& coordinates,
80                                     GradType& gradient)
81 {
82   Gradient(coordinates, 0, gradient, 1);
83 }
84 
85 } // namespace test
86 } // namespace ens
87 
88 #endif
89