OpenLB 1.7
Loading...
Searching...
No Matches
optiCase.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2012, 2021 Mathias J. Krause, Julius Jeßberger
4 * E-mail contact: info@openlb.net
5 * The most recent release of OpenLB can be downloaded at
6 * <http://www.openlb.net/>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the Free
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22*/
23
24
25#ifndef OPTI_CASE_H
26#define OPTI_CASE_H
27
28#include <functional>
29
30#include "io/xmlReader.h"
31
32namespace olb {
33
34namespace opti {
35
36
38// provides function evaluation and gradient computation
39template <typename S, typename C>
41
42protected:
43 std::function<void (void)> _postEvaluation { [](){} };
44
45public:
46 OptiCase() = default;
47
48 explicit OptiCase(std::function<void (void)> postEvaluation)
50 { }
51
52 virtual S evaluateObjective(const C& control, unsigned optiStep=0) = 0;
53 virtual void computeDerivatives (
54 const C& control, C& derivatives, unsigned optiStep=0) = 0;
55
58 }
59};
60
61
63template <typename S, typename C>
64class OptiCaseAnalytical : public OptiCase<S,C> {
65
66protected:
67 std::function<S (const C&)> _function;
68 std::function<void (const C&, C&)> _derivative;
69
70public:
71 OptiCaseAnalytical(std::function<S (const C&)> function,
72 std::function<void (const C&, C&)> derivative,
73 std::function<void (void)> postEvaluation = [](){})
75 { }
76
78 const C& control, unsigned optiStep=0) override {
79 return _function(control);
80 }
81
83 const C& control, C& derivatives, unsigned optiStep=0) override {
84 _derivative(control, derivatives);
85 }
86};
87
88template <typename S, typename C>
89OptiCaseAnalytical(std::function<S (const C&)>,
90 std::function<void (const C&, C&)>)
92
93template <typename S, typename C>
94OptiCaseAnalytical(std::function<S (const C&)>,
95 std::function<void (const C&, C&)>,
96 std::function<void (void)>)
98
99
100// Abstract base class for gradient computation with difference quotients
101template <typename S, typename C>
102class OptiCaseDQ : public OptiCase<S,C> {
103
104protected:
105 std::function<S (const C&)> _functionHelp { [](const C&){ return S{}; } };
106 std::function<S (const C&, unsigned)> _function;
107 S _stepWidth {1.e-8};
108
109 bool _objectiveComputed {false};
111
112public:
113 explicit OptiCaseDQ(std::function<S (const C&, unsigned)> function,
114 std::function<void (void)> postEvaluation)
115 : OptiCase<S,C>(postEvaluation), _function(function)
116 { }
117
118 // If function with (only) one argument is passed, use plain wrapper
119 explicit OptiCaseDQ(std::function<S (const C&)> function,
120 std::function<void (void)> postEvaluation)
121 : OptiCase<S,C>(postEvaluation),
122 _functionHelp(function),
123 _function([&](const C& arg, unsigned){ return _functionHelp(arg); })
124 { }
125
126 template <typename F>
127 OptiCaseDQ(F function, S stepWidth,
128 std::function<void (void)> postEvaluation)
129 : OptiCaseDQ(function, postEvaluation) {
130 _stepWidth = stepWidth;
131 }
132
134 const C& control, unsigned optiStep=0) override {
135 _objective = _function(control, optiStep);
136 _objectiveComputed = true;
137 return _objective;
138 }
139};
140
141
143template <typename S, typename C>
144class OptiCaseFDQ : public OptiCaseDQ<S,C> {
145private:
146 OstreamManager clout {std::cout, "OptiCaseFDQ"};
147
148public:
149 template <typename F>
150 explicit OptiCaseFDQ(F function,
151 std::function<void (void)> postEvaluation = [](){})
153 { }
154
155 template <typename F>
156 OptiCaseFDQ(F function, S stepWidth,
157 std::function<void (void)> postEvaluation = [](){})
158 : OptiCaseFDQ::OptiCaseDQ(function, stepWidth, postEvaluation)
159 { }
160
162 C& derivatives, unsigned optiStep=0) override
163 {
164 assert((control.size() == derivatives.size()));
165
166 if (!(this->_objectiveComputed)) {
167 this->evaluateObjective(control, optiStep);
168 }
169 const S objective(this->_objective);
170
171 for (std::size_t it = 0; it < control.size(); ++it)
172 {
173 C shiftedControl(control);
174 shiftedControl[it] += this->_stepWidth;
175 S shiftedObjective = this->evaluateObjective(shiftedControl, optiStep);
176 derivatives[it] = (shiftedObjective - objective) / this->_stepWidth;
177 }
178 this->_objectiveComputed = false;
179 }
180};
181
182template <typename S, typename C>
183OptiCaseFDQ(std::function<S (const C&)>, std::function<void (void)>)
185
186template <typename S, typename C>
187OptiCaseFDQ(std::function<S (const C&)>, S, std::function<void (void)>)
189
190template <typename S, typename C>
191OptiCaseFDQ(std::function<S (const C&, unsigned)>, std::function<void (void)>)
193
194template <typename S, typename C>
195OptiCaseFDQ(std::function<S (const C&, unsigned)>, S, std::function<void (void)>)
197
198template <typename S, typename C>
199OptiCaseFDQ(std::function<S (const C&)>)
201
202template <typename S, typename C>
203OptiCaseFDQ(std::function<S (const C&)>, S)
205
206template <typename S, typename C>
207OptiCaseFDQ(std::function<S (const C&, unsigned)>)
209
210template <typename S, typename C>
211OptiCaseFDQ(std::function<S (const C&, unsigned)>, S)
213
215template <typename S, typename C>
216class OptiCaseCDQ : public OptiCaseDQ<S,C> {
217private:
218 OstreamManager clout {std::cout, "OptiCaseCDQ"};
219
220public:
221 template <typename F>
222 explicit OptiCaseCDQ(F function,
223 std::function<void (void)> postEvaluation = [](){})
225 { }
226
227 template <typename F>
228 OptiCaseCDQ(F function, S stepWidth,
229 std::function<void (void)> postEvaluation = [](){})
230 : OptiCaseCDQ::OptiCaseDQ(function, stepWidth, postEvaluation)
231 { }
232
234 C& derivatives, unsigned optiStep=0) override
235 {
236 assert((control.size() == derivatives.size()));
237
238 for (std::size_t it = 0; it < control.size(); ++it)
239 {
240 C shiftedControl(control);
241 shiftedControl[it] += this->_stepWidth;
242 S shiftedObjective_plus = this->evaluateObjective(shiftedControl, optiStep);
243
244 shiftedControl[it] = control[it] - this->_stepWidth;
245 S shiftedObjective_minus = this->evaluateObjective(shiftedControl, optiStep);
246
247 derivatives[it] = 0.5 * (shiftedObjective_plus - shiftedObjective_minus) / this->_stepWidth;
248 }
249 }
250};
251
252template <typename S, typename C>
253OptiCaseCDQ(std::function<S (const C&)>, std::function<void (void)>)
255
256template <typename S, typename C>
257OptiCaseCDQ(std::function<S (const C&)>, S, std::function<void (void)>)
259
260template <typename S, typename C>
261OptiCaseCDQ(std::function<S (const C&, unsigned)>, std::function<void (void)>)
263
264template <typename S, typename C>
265OptiCaseCDQ(std::function<S (const C&, unsigned)>, S, std::function<void (void)>)
267
268template <typename S, typename C>
269OptiCaseCDQ(std::function<S (const C&)>)
271
272template <typename S, typename C>
273OptiCaseCDQ(std::function<S (const C&)>, S)
275
276template <typename S, typename C>
277OptiCaseCDQ(std::function<S (const C&, unsigned)>)
279
280template <typename S, typename C>
281OptiCaseCDQ(std::function<S (const C&, unsigned)>, S)
283
284} // namespace opti
285
286} // namespace olb
287
288#endif
class for marking output with some text
Gradient is just passed as a function (and not computed by an own routine)
Definition optiCase.h:64
std::function< S(const C &) _function)
Definition optiCase.h:67
OptiCaseAnalytical(std::function< S(const C &)> function, std::function< void(const C &, C &)> derivative, std::function< void(void)> postEvaluation=[](){})
Definition optiCase.h:71
void computeDerivatives(const C &control, C &derivatives, unsigned optiStep=0) override
Definition optiCase.h:82
std::function< void(const C &, C &) _derivative)
Definition optiCase.h:68
S evaluateObjective(const C &control, unsigned optiStep=0) override
Definition optiCase.h:77
Gradient computation with central difference quotients.
Definition optiCase.h:216
void computeDerivatives(const C &control, C &derivatives, unsigned optiStep=0) override
Definition optiCase.h:233
OptiCaseCDQ(F function, S stepWidth, std::function< void(void)> postEvaluation=[](){})
Definition optiCase.h:228
OptiCaseCDQ(F function, std::function< void(void)> postEvaluation=[](){})
Definition optiCase.h:222
OptiCaseDQ(std::function< S(const C &)> function, std::function< void(void)> postEvaluation)
Definition optiCase.h:119
std::function< S(const C &, unsigned) _function)
Definition optiCase.h:106
std::function< S(const C &) _functionHelp)
Definition optiCase.h:105
S evaluateObjective(const C &control, unsigned optiStep=0) override
Definition optiCase.h:133
OptiCaseDQ(F function, S stepWidth, std::function< void(void)> postEvaluation)
Definition optiCase.h:127
OptiCaseDQ(std::function< S(const C &, unsigned)> function, std::function< void(void)> postEvaluation)
Definition optiCase.h:113
Gradient computation with forward difference quotients.
Definition optiCase.h:144
void computeDerivatives(const C &control, C &derivatives, unsigned optiStep=0) override
Definition optiCase.h:161
OptiCaseFDQ(F function, S stepWidth, std::function< void(void)> postEvaluation=[](){})
Definition optiCase.h:156
OptiCaseFDQ(F function, std::function< void(void)> postEvaluation=[](){})
Definition optiCase.h:150
Abstract base class for optimization tasks.
Definition optiCase.h:40
void postEvaluation()
Definition optiCase.h:56
virtual S evaluateObjective(const C &control, unsigned optiStep=0)=0
std::function< void(void)> _postEvaluation
Definition optiCase.h:43
virtual void computeDerivatives(const C &control, C &derivatives, unsigned optiStep=0)=0
OptiCase(std::function< void(void)> postEvaluation)
Definition optiCase.h:48
OptiCaseCDQ(std::function< S(const C &)>, std::function< void(void)>) -> OptiCaseCDQ< S, C >
OptiCaseFDQ(std::function< S(const C &)>, std::function< void(void)>) -> OptiCaseFDQ< S, C >
OptiCaseAnalytical(std::function< S(const C &)>, std::function< void(const C &, C &)>) -> OptiCaseAnalytical< S, C >
Top level namespace for all of OpenLB.
Optimization Code.
Input/Output in XML format – header file.