CombinedObjectiveFunction.h
Go to the documentation of this file.
1//===========================================================================
2/*!
3 *
4 *
5 * \brief CombinedObjectiveFunction
6 *
7 *
8 *
9 * \author T.Voss, T. Glasmachers, O.Krause
10 * \date 2010-2011
11 *
12 *
13 * \par Copyright 1995-2017 Shark Development Team
14 *
15 * <BR><HR>
16 * This file is part of Shark.
17 * <https://shark-ml.github.io/Shark/>
18 *
19 * Shark is free software: you can redistribute it and/or modify
20 * it under the terms of the GNU Lesser General Public License as published
21 * by the Free Software Foundation, either version 3 of the License, or
22 * (at your option) any later version.
23 *
24 * Shark is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU Lesser General Public License for more details.
28 *
29 * You should have received a copy of the GNU Lesser General Public License
30 * along with Shark. If not, see <http://www.gnu.org/licenses/>.
31 *
32 */
33//===========================================================================
34#ifndef SHARK_OBJECTIVEFUNCTIONS_COMBINEDOBJECTIVEFUNCTION_H
35#define SHARK_OBJECTIVEFUNCTIONS_COMBINEDOBJECTIVEFUNCTION_H
36
37
39
40namespace shark {
41
42
43///
44/// \brief Linear combination of objective functions
45///
46/// \par
47/// The CombinedObjectiveFunction is a linear combination of
48/// objective functions. It assumed that the result type is
49/// capable of forming linear combinations with real coefficients.
50/// \ingroup objfunctions
51template <typename SearchPointType, typename ResultT>
52class CombinedObjectiveFunction : public AbstractObjectiveFunction<SearchPointType, ResultT>
53{
54public:
55
58
59 /// Constructor
64
65 /// \brief From INameable: return the class name.
66 std::string name() const
67 { return "CombinedObjectiveFunction"; }
68
69
70 /// Adds a new objective function with a
71 /// weight of one to the linear combination.
72 void add(element& e){
73 add(1.0, e);
74 }
75
76 /// Adds a new objective function with
77 /// a weight to the linear combination.
78 void add(double weight, element& e)
79 {
80 SHARK_RUNTIME_CHECK(weight >= 0.0, "[CombinedObjectiveFunction::add] weight must be non-negative");
81
82 m_weight.push_back(weight);
83 m_elements.push_back(&e);
84
88 }
89
90 /// Tests whether a point in SearchSpace is feasible,
91 /// e.g., whether the constraints are fulfilled.
92 bool isFeasible( const typename super::SearchPointType & input) const {
93 std::size_t ic = m_elements.size();
94 for ( std::size_t i=0; i<ic; i++)
95 if (! m_elements[i]->isFeasible(input))
96 return false;
97 return true;
98 }
99
100 void init(){
101 for ( std::size_t i=0; i<m_elements.size(); i++){
102 m_elements[i]->setRng(this->mep_rng);
103 m_elements[i]->init();
104 }
105 }
106
107 std::size_t numberOfVariables()const{
108 //todo sthis will fail if SarchPointType != Vectorspace
109 return m_elements.size() == 0? 0: m_elements[0]->numberOfVariables();
110 }
111
112 /// Evaluates the objective function.
113 typename super::ResultType eval( const typename super::SearchPointType & input ) const
114 {
115 ++this->m_evaluationCounter;
116 std::size_t ic = m_elements.size();
117 typename super::ResultType ret = m_weight[0] * m_elements[0]->eval(input);
118 for (std::size_t i=1; i<ic; i++)
119 ret += m_weight[i] * m_elements[i]->eval(input);
120 return ret;
121 }
122
123 /// Evaluates the objective function
124 /// and calculates its gradient.
125 typename super::ResultType evalDerivative( const typename super::SearchPointType & input, typename super::FirstOrderDerivative & derivative ) const {
126 ++this->m_evaluationCounter;
127 SHARK_RUNTIME_CHECK(this->m_features.test(super::HAS_FIRST_DERIVATIVE), "[CombinedObjectiveFunction::evalDerivative] At least one of the objective functions combined is not differentiable");
128 typename super::FirstOrderDerivative der;
129 std::size_t ic = m_elements.size();
130 typename super::ResultType ret = m_weight[0] * m_elements[0]->evalDerivative(input, der);
131 derivative = m_weight[0] * der;
132 for (std::size_t i=1; i != ic; i++)
133 {
134 ret += m_weight[i] * m_elements[i]->evalDerivative(input, der);
135 derivative += m_weight[i] * der;
136 }
137 return ret;
138 }
139
140 /// Evaluates the objective function
141 /// and calculates its gradient and
142 /// its Hessian.
143 typename super::ResultType evalDerivative( const typename super::SearchPointType & input, typename super::SecondOrderDerivative & derivative )const {
144 SHARK_RUNTIME_CHECK(this->m_features.test(super::HAS_SECOND_DERIVATIVE), "[CombinedObjectiveFunction::evalDerivative] At least one of the objective functions combined is not twice differentiable");
145 typename super::SecondOrderDerivative der;
146 std::size_t ic = m_elements.size();
147 typename super::ResultType ret = m_weight[0] * m_elements[0]->evalDerivative(input, der);
148 derivative.gradient = m_weight[0] * der.gradient;
149 derivative.hessian = m_weight[0] * der.hessian;
150 for (std::size_t i=1; i<ic; i++)
151 {
152 ret += m_weight[i] * m_elements[i]->evalDerivative(input, der);
153 derivative.gradient += m_weight[i] * der.gradient;
154 derivative.hessian += m_weight[i] * der.hessian;
155 }
156 return ret;
157 }
158
159protected:
160 /// list of weights
161 std::vector<double> m_weight;
162
163 /// list of "base" objective functions
164 std::vector<element*> m_elements;
165};
166
167
168}
169#endif // SHARK_CORE_COBINEDOBJECTIVEFUNCTION_H