EvaluationArchive.h
Go to the documentation of this file.
1//===========================================================================
2/*!
3 *
4 *
5 * \brief Archive of evaluated points as an objective function wrapper.
6
7 *
8 *
9 * \author T. Glasmachers
10 * \date 2013
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_EVALUATIONARCHIVE_H
35#define SHARK_OBJECTIVEFUNCTIONS_EVALUATIONARCHIVE_H
36
37
39
40#include <set>
41#include <string>
42#include <sstream>
43
44
45namespace shark {
46
47
48///
49/// \brief Objective function wrapper storing all function evaluations.
50///
51/// \tparam PointType The search space the function is defined upon.
52/// \tparam ResultT The objective space the function is defined upon.
53///
54/// \par
55/// The EvaluationArchive class serves as an archive of all evaluated
56/// points and the corresponding result. It can be used transparently
57/// instead of the original objective function, e.g., by an optimizer.
58/// Point/result pairs are added to the archive only if the specific
59/// combination is not yet stored.
60///
61/// \par
62/// For fast-to-evaluate objective functions the archive wrapper can
63/// be a considerable performance killer. However, whenever function
64/// evaluations are costly (and an archive makes sense) then the
65/// storage and maintenance overhead should be negligible.
66/// \ingroup objfunctions
67template <typename PointType, typename ResultT>
68class EvaluationArchive : public AbstractObjectiveFunction<PointType, ResultT>
69{
70public:
74
77
78 /// \brief Pair of point and result.
80 {
81 public:
83 : point(p)
84 , result(r)
85 { }
86
88 : point(other.point)
89 , result(other.result)
90 { }
91
92 // Comparison is based on string representation.
93 // This is a hack, but it is quite generic.
94 // And a generic solution is needed for std::set.
95 bool operator == (PointResultPairType const& other) const
96 {
97 return (toString() == other.toString());
98 }
99 bool operator < (PointResultPairType const& other) const
100 {
101 return (toString() < other.toString());
102 }
103
106
107 private:
108 std::string toString() const
109 {
110 std::stringstream ss;
111 ss << point << " " << result;
112 return ss.str();
113 }
114 };
115
116 typedef std::set<PointResultPairType> PointResultPairContainer;
117 typedef typename PointResultPairContainer::iterator PointResultPairIterator;
118 typedef typename PointResultPairContainer::const_iterator PointResultPairConstIterator;
119
120 /// \brief Constructor.
121 ///
122 /// \par
123 /// The constructor takes the objective function to be wrapped
124 /// as an argument. It is assumed that the objective object's
125 /// life time exceeds the life time of the present instance.
127 : mep_objective(objective)
128 {
129 base_type::m_features = mep_objective->features();
130 base_type::m_constraintHandler = mep_objective->hasConstraintHandler() ? &mep_objective->getConstraintHandler() : NULL;
131 }
132
133
134 /// \brief Access to the underlying objective function.
136 { return mep_objective; }
137
138 /// \brief Access to the underlying objective function.
139 const base_type* objective() const
140 { return mep_objective; }
141
142 /// \brief Wrapper function.
143 void init(){
144 mep_objective->setRng(this->mep_rng);
145 mep_objective->init();
146 }
147
148 /// \brief Wrapper function.
149 virtual std::size_t numberOfObjectives() const
150 { return mep_objective->numberOfObjectives(); }
151
152 /// \brief Wrapper function.
154 { return mep_objective->hasScalableObjectives(); }
155
156 /// \brief Wrapper function.
159
160 /// \brief Wrapper function.
161 bool isFeasible(const SearchPointType& input) const
162 { return mep_objective->isFeasible(input); }
163
164 /// \brief Wrapper function.
166 { return mep_objective->closestFeasible(input); }
167
168 /// \brief Wrapper function.
169 void proposeStartingPoint(SearchPointType& startingPoint) const
170 { return mep_objective->proposeStartingPoint(startingPoint); }
171
172 /// \brief Wrapper function; conditional on vector space property.
173 std::size_t numberOfVariables() const
174 {
175 return mep_objective->numberOfVariables();
176 }
177
178 /// \brief Wrapper function storing point and result.
179 ResultType eval(const SearchPointType& input) const
180 {
181 ResultType r = mep_objective->eval(input);
183 m_archive.insert(PointResultPairType(input, r));
184 return r;
185 }
186
187 // TG: Could someone enlighten me: why do I have to copy this
188 // from the super class to make the compiler find the f**king
189 // operator??
190 ResultType operator()( const SearchPointType & input ) const
191 { return eval(input); }
192
193 /// \brief Wrapper function storing point and result.
195 {
196 ResultType r = mep_objective->evalDerivative(input, derivative);
198 m_archive.insert(PointResultPairType(input, r));
199 return r;
200 }
201
202 /// \brief Wrapper function storing point and result.
204 {
205 ResultType r = mep_objective->evalDerivative(input, derivative);
207 m_archive.insert(PointResultPairType(input, r));
208 return r;
209 }
210
211
212 ////////////////////////////////////////////////////////////
213 // access to the archive
214 //
215
216 /// Return the size of the archive; which is the number of point/result pairs.
217 std::size_t size() const
218 { return m_archive.size(); }
219
220 /// Begin iterator to the point/result pairs.
222 { return m_archive.begin(); }
223
224 /// Begin iterator to the point/result pairs.
226 { return m_archive.begin(); }
227
228 /// End iterator to the point/result pairs.
230 { return m_archive.end(); }
231
232 /// End iterator to the point/result pairs.
234 { return m_archive.end(); }
235
236private:
237 base_type* mep_objective; ///< objective function to be wrapped
238 mutable PointResultPairContainer m_archive; ///< evaluated point/result pairs
239};
240
241
242};
243#endif