OpenLB 1.7
Loading...
Searching...
No Matches
optimizerBarzilaiBorwein.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2012-2016 Mathias J. Krause, Benjamin Förster
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
29#ifndef OPTIMIZER_BARZILAI_BORWEIN_H
30#define OPTIMIZER_BARZILAI_BORWEIN_H
31
32#include "optimizerLineSearch.h"
33#include "utilities/norm.h"
34
35
36
37// All OpenLB code is contained in this namespace.
38namespace olb {
39
41namespace opti {
42
44
55template<typename S, typename C>
57
58private:
59 mutable OstreamManager clout;
60
61 S _startLambda;
62
63 C _lastControl;
64 C _lastDerivative;
65
66 C _sStore;
67 C _yStore;
68
69
70public:
72 int dim, S eps, int maxIt, S lambda, int maxStepAttempts, std::string stepCondition,
73 bool verboseOn=true, const std::string fname="", const std::string logFileName="",
74 bool withUpperBound=false, S upperBound=S(), bool withLowerBound=false, S lowerBound=S(),
75 bool vectorBounds=false, S controlEps=S(std::numeric_limits<double>::epsilon() ),
76 std::vector<OptimizerLogType> gplotAnalysis = {})
77 : OptimizerLineSearch<S,C>(dim, eps, maxIt, /*lambda*/ 1., maxStepAttempts, stepCondition,
78 verboseOn, fname, logFileName, withUpperBound, upperBound, withLowerBound,
79 lowerBound, vectorBounds, controlEps, true, gplotAnalysis),
80 clout(std::cout,"OptimizerBarzilaiBorwein")
81 {
82
83 // Starting lambda for iT==0: steepest descent
84 // Line Search will be initialised with the natural lambda = 1
85 _startLambda = lambda;
86
87 _lastControl = util::ContainerCreator<C>::create(this->_dimCtrl);
88 _lastDerivative = util::ContainerCreator<C>::create(this->_dimCtrl);
89
92
93 };
94
96 {
97 S normDir = util::euklidN(this->_direction.data(), this->_dimCtrl);
98 if (std::isnan(normDir)) {
99 clout << "Warning: Derivative is null at first iteration. Check derivative calculations.\nProgram terminated" << std::endl;
100 exit(1);
101 }
102 }
103
104 virtual void computeDirection()
105 {
106 for (int i=0; i<this->_dimCtrl; i++) {
107 _sStore[i] = 0.;
108 _yStore[i] = 0.;
109 }
110 S sTy = 0.;
111 S sTs = 0.;
112 S yTy = 0.;
113 // Alternating between lambda_1 and lambda_2, see:
114 // http://www.math.ucla.edu/~wotaoyin/math273a/slides/Lec4a_Baizilai_Borwein_method_273a_2015_f.pdf, p.6
115 bool alternate = false;
116
117
118 // Compute Derivatives
119 // computeDerivative only if not already done by wolfeCondition()
120 if (!this->_nextDerivFlag) {
121 this->computeDerivatives(this->_control, this->_derivative);
122 }
123 else {
124 for (int iDim=0; iDim<this->_dimCtrl; iDim++) {
125 this->_derivative[iDim] = this->_nextDerivative[iDim];
126 }
127 }
128
129
130 if (this->_it == 0) {
131 // On first step do normalised steepest descent
132 S normDerivative = util::euklidN(this->_derivative.data(), this->_dimCtrl);
133 for (int iDim=0; iDim<this->_dimCtrl; iDim++) {
134 this->_direction[iDim] = _startLambda * this->_derivative[iDim] / normDerivative;
135 }
136 // terminate early if we recieve nan controls
138 // Store control and derivative
139 for (int iDim=0; iDim<this->_dimCtrl; iDim++) {
140 _lastControl[iDim] = this->_control[iDim];
141 _lastDerivative[iDim] = this->_derivative[iDim];
142 }
143
144 }
145 else {
146 // Calculate lambda as quasi Newton
147 for (int iDim=0; iDim<this->_dimCtrl; iDim++) {
148 _sStore[iDim] = this->_control[iDim] - _lastControl[iDim];
149 _yStore[iDim] = this->_derivative[iDim] - _lastDerivative[iDim];
150 sTs += _sStore[iDim]*_sStore[iDim];
151 sTy += _sStore[iDim]*_yStore[iDim];
152 if (alternate) {
153 yTy += _yStore[iDim]*_yStore[iDim];
154 }
155 }
156 // lambda_1 is minimizing || sD - y ||
157 this->_lambda = sTs/sTy; //lambda_1
158 // lambda_2 is minimizing || s - yD^-1 ||
159 //this->_lambda = sTy/yTy; //lambda_2
160
161 //Alternate lambda_1 and lambda_2
162 if (alternate && this->_it%2 != 0) {
163 this->_lambda = sTy/yTy;
164 }
165
166 for (int iDim=0; iDim<this->_dimCtrl; iDim++) {
167 _lastControl[iDim] = this->_control[iDim];
168 _lastDerivative[iDim] = this->_derivative[iDim];
169 }
170
171 for (int iDim=0; iDim<this->_dimCtrl; iDim++) {
172 this->_direction[iDim] = this->_derivative[iDim];
173 }
174 }
175 };
176};
177
178
180template<typename S, typename C = std::vector<S>>
182{
183 OstreamManager clout(std::cout,"createOptimizerBarzilaiBorwein");
184
185 // create variables with default values
186 int maxIt = 100;
187
188 S controlEps = S(0);
189 S eps = S(1.e-10);
190
191 S lambda = 1.; //starting lambda for steepest descent step (it==0)
192 int maxStepAttempts = 100;
193 std::string stepCondition = "None";
194
195 bool verboseOn=true;
196 std::string fname = "control.dat";
197 std::string logFileName = "log.txt";
198
199 bool vectorBounds = false;
200 bool withUpperBound = false;
201 S upperBound = S();
202 bool withLowerBound = false;
203 S lowerBound = S();
204
205 std::vector<OptimizerLogType> gplotAnalysis = {};
206 std::string gplotAnalysisString = "";
207
208 // Read Values from XML File
209 params.readOrWarn<int>("Optimization", "MaxIter", "", maxIt);
210
211 params.readOrWarn<S>("Optimization", "Tolerance", "", eps);
212 params.readOrWarn<S>("Optimization", "ControlTolerance", "", controlEps);
213 params.readOrWarn<S>("Optimization", "Lambda", "", lambda);
214 params.readOrWarn<int>("Optimization", "MaxStepAttempts", "", maxStepAttempts);
215 params.readOrWarn<std::string>("Optimization", "StepCondition", "", stepCondition);
216
217 params.readOrWarn<bool>("Optimization", "Verbose", "", verboseOn);
218 params.readOrWarn<std::string>("Optimization", "InputFileName", "", fname);
219 params.readOrWarn<std::string>("Optimization", "LogFileName", "", logFileName);
220
221 params.readOrWarn<bool>("Optimization", "VectorBounds", "", vectorBounds);
222 if ( params.readOrWarn<S>("Optimization", "UpperBound", "", upperBound, false, false) ) {
223 withUpperBound = true;
224 }
225 if ( params.readOrWarn<S>("Optimization", "LowerBound", "", lowerBound, false, false) ) {
226 withLowerBound = true;
227 }
228
229 // get the parameters for the gnuplot Analysis from the xml file from the VisualizationGnuplot area
230 params.readOrWarn<std::string>("Optimization", "VisualizationGnuplot", "VisualizedParameters", "", gplotAnalysisString, false, false);
231 // transform the data from the xml file to the enums needed for continueing
232 getGnuplotTagsFromString(gplotAnalysisString, gplotAnalysis);
233
234 // Create Optimizer Object
235 return new OptimizerBarzilaiBorwein<S,C>(dimCtrl, eps, maxIt, lambda, maxStepAttempts, stepCondition,
236 verboseOn, fname, logFileName, withUpperBound, upperBound, withLowerBound, lowerBound,
237 vectorBounds, controlEps, gplotAnalysis);
238}
239
240} // namespace opti
241
242} // namespace olb
243
244#endif
class for marking output with some text
bool readOrWarn(std::string name_parameter_1, std::string name_parameter_2, std::string name_parameter_3, ParameterType &var, bool defaultAvailable=true, bool exitIfMissing=false, bool showWarning=true) const
This wrapper function reads the given parameter from the "type_parameter" and "name_parameter_1" or "...
Definition xmlReader.h:178
Optimization algorithm: BarzilaiBorwein.
OptimizerBarzilaiBorwein(int dim, S eps, int maxIt, S lambda, int maxStepAttempts, std::string stepCondition, bool verboseOn=true, const std::string fname="", const std::string logFileName="", bool withUpperBound=false, S upperBound=S(), bool withLowerBound=false, S lowerBound=S(), bool vectorBounds=false, S controlEps=S(std::numeric_limits< double >::epsilon()), std::vector< OptimizerLogType > gplotAnalysis={})
Optimization algorithm: LineSearch.
int _it
Current iteration no.
Definition optimizer.h:73
C _derivative
Vector of derivatives of the object functional with respect to the controlled variables.
Definition optimizer.h:71
int _dimCtrl
Number of controlled variables.
Definition optimizer.h:63
C _control
Vector of controlled variables (size _dimCtrl)
Definition optimizer.h:65
void computeDerivatives(const C &control, C &derivatives)
Definition optimizer.h:144
OptimizerBarzilaiBorwein< S, C > * createOptimizerBarzilaiBorwein(XMLreader const &params, std::size_t dimCtrl)
Creator Function for Barzilai-Borwein.
void getGnuplotTagsFromString(std::string gplotAnalysisString, std::vector< OptimizerLogType > &gplotAnalysis)
the gplotAnalysisString is gained from the xml file and the function than separates and prepares it t...
Definition optimizer.hh:236
T euklidN(const T x[], int dim)
Euclidean norm of an array.
Definition norm.h:60
Top level namespace for all of OpenLB.
Optimization Code.
Implements Euclidean norm for arrays.
The description of line search optimization algorithm – header file.
Creates a container of type C.