Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2016-2018 The VES code team
3 : (see the PEOPLE-VES file at the root of this folder for a list of names)
4 :
5 : See http://www.ves-code.org for more information.
6 :
7 : This file is part of VES code module.
8 :
9 : The VES code module is free software: you can redistribute it and/or modify
10 : it under the terms of the GNU Lesser General Public License as published by
11 : the Free Software Foundation, either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : The VES code module is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU Lesser General Public License for more details.
18 :
19 : You should have received a copy of the GNU Lesser General Public License
20 : along with the VES code module. If not, see <http://www.gnu.org/licenses/>.
21 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
22 : #ifndef __PLUMED_ves_Optimizer_h
23 : #define __PLUMED_ves_Optimizer_h
24 :
25 : #include "VesBias.h"
26 :
27 : #include "core/ActionPilot.h"
28 : #include "core/ActionWithValue.h"
29 :
30 : #include <vector>
31 : #include <string>
32 : #include <cmath>
33 :
34 :
35 : #define PLUMED_VES_OPTIMIZER_INIT(ao) Action(ao),Optimizer(ao)
36 :
37 : namespace PLMD {
38 :
39 : /**
40 : \ingroup INHERIT
41 : Abstract base class for implenting new optimization methods
42 : */
43 :
44 : class OFile;
45 :
46 : namespace ves {
47 :
48 : class CoeffsVector;
49 : class VesBias;
50 :
51 :
52 : class Optimizer :
53 : public ActionPilot,
54 : public ActionWithValue
55 : {
56 : private:
57 : const std::string description_;
58 : const std::string type_;
59 : //
60 : std::vector<double> stepsizes_;
61 : std::vector<double> current_stepsizes;
62 : bool fixed_stepsize_;
63 : //
64 : unsigned int iter_counter;
65 : //
66 : bool use_hessian_;
67 : bool diagonal_hessian_;
68 : bool hessian_covariance_from_averages_;
69 : //
70 : bool monitor_instantaneous_gradient_;
71 : //
72 : bool use_mwalkers_mpi_;
73 : bool mwalkers_mpi_single_files_;
74 : //
75 : std::vector<bool> dynamic_targetdists_;
76 : unsigned int ustride_targetdist_;
77 : //
78 : unsigned int ustride_reweightfactor_;
79 : //
80 : std::string coeffssetid_prefix_;
81 : //
82 : unsigned int coeffs_wstride_;
83 : std::vector<OFile*> coeffsOFiles_;
84 : std::string coeffs_output_fmt_;
85 : //
86 : unsigned int gradient_wstride_;
87 : std::vector<OFile*> gradientOFiles_;
88 : std::string gradient_output_fmt_;
89 : //
90 : unsigned int hessian_wstride_;
91 : std::vector<OFile*> hessianOFiles_;
92 : std::string hessian_output_fmt_;
93 : //
94 : unsigned int targetdist_averages_wstride_;
95 : std::vector<OFile*> targetdist_averagesOFiles_;
96 : std::string targetdist_averages_output_fmt_;
97 : //
98 : unsigned int nbiases_;
99 : std::vector<VesBias*> bias_pntrs_;
100 : //
101 : unsigned int ncoeffssets_;
102 : std::vector<CoeffsVector*> coeffs_pntrs_;
103 : std::vector<CoeffsVector*> aux_coeffs_pntrs_;
104 : std::vector<CoeffsVector*> gradient_pntrs_;
105 : std::vector<CoeffsVector*> aver_gradient_pntrs_;
106 : std::vector<CoeffsMatrix*> hessian_pntrs_;
107 : std::vector<CoeffsVector*> coeffs_mask_pntrs_;
108 : std::vector<CoeffsVector*> targetdist_averages_pntrs_;
109 : //
110 : bool identical_coeffs_shape_;
111 : //
112 : bool bias_output_active_;
113 : unsigned int bias_output_stride_;
114 : bool fes_output_active_;
115 : unsigned int fes_output_stride_;
116 : bool fesproj_output_active_;
117 : unsigned int fesproj_output_stride_;
118 : bool targetdist_output_active_;
119 : unsigned int targetdist_output_stride_;
120 : bool targetdist_proj_output_active_;
121 : unsigned int targetdist_proj_output_stride_;
122 : //
123 : bool isFirstStep;
124 : //
125 : private:
126 : void updateOutputComponents();
127 : void writeOutputFiles(const unsigned int coeffs_id = 0);
128 : void readCoeffsFromFiles(const std::vector<std::string>&, const bool);
129 : void setAllCoeffsSetIterationCounters();
130 : protected:
131 : void turnOnHessian();
132 : void turnOffHessian();
133 : std::vector<CoeffsMatrix*> enableHessian(VesBias*, const bool diagonal_hessian=false);
134 : // CoeffsMatrix* switchToDiagonalHessian(VesBias*);
135 : // CoeffsMatrix* switchToFullHessian(VesBias*);
136 : //
137 : CoeffsVector& Coeffs(const unsigned int coeffs_id = 0) const;
138 : CoeffsVector& AuxCoeffs(const unsigned int coeffs_id = 0) const;
139 : CoeffsVector& Gradient(const unsigned int coeffs_id = 0) const;
140 : CoeffsMatrix& Hessian(const unsigned int coeffs_id = 0) const;
141 : CoeffsVector& CoeffsMask(const unsigned int coeffs_id = 0) const;
142 : CoeffsVector& TargetDistAverages(const unsigned int coeffs_id = 0) const;
143 : double StepSize(const unsigned int coeffs_id = 0) const;
144 : virtual void coeffsUpdate(const unsigned int coeffs_id = 0) = 0;
145 : void setCurrentStepSize(const double,const unsigned int i = 0);
146 : void setCurrentStepSizes(const std::vector<double>&);
147 : //
148 : void turnOffCoeffsOutputFiles();
149 : //
150 : template<class T>
151 : bool parseMultipleValues(const std::string&, std::vector<T>&);
152 : template<class T>
153 : bool parseMultipleValues(const std::string&, std::vector<T>&, const T&);
154 : void parseFilenames(const std::string&, std::vector<std::string>&, const std::string&);
155 : void parseFilenames(const std::string&, std::vector<std::string>&);
156 : void addCoeffsSetIDsToFilenames(std::vector<std::string>&, std::string&);
157 : void setupOFiles(std::vector<std::string>&, std::vector<OFile*>&, const bool multi_sim_single_files=false);
158 : public:
159 : static void registerKeywords(Keywords&);
160 : static void useMultipleWalkersKeywords(Keywords&);
161 : static void useHessianKeywords(Keywords&);
162 : static void useFixedStepSizeKeywords(Keywords&);
163 : static void useDynamicStepSizeKeywords(Keywords&);
164 : static void useMaskKeywords(Keywords&);
165 : static void useRestartKeywords(Keywords&);
166 : static void useMonitorAverageGradientKeywords(Keywords&);
167 : static void useDynamicTargetDistributionKeywords(Keywords&);
168 : static void useReweightFactorKeywords(Keywords&);
169 : //
170 : explicit Optimizer(const ActionOptions&ao);
171 : ~Optimizer();
172 : std::string getType() const {return type_;}
173 : std::string getDescription() const {return description_;}
174 : //
175 : unsigned int numberOfBiases() const {return nbiases_;}
176 12 : unsigned int numberOfCoeffsSets() const {return ncoeffssets_;}
177 : //
178 : std::vector<double> getStepSizes() const;
179 : std::vector<double> getCurrentStepSizes() const;
180 : double getStepSize(const unsigned int coeffs_id = 0) const;
181 : double getCurrentStepSize(const unsigned int coeffs_id = 0) const;
182 : void setStepSizes(const std::vector<double>&);
183 : void setStepSize(const double, const unsigned int coeffs_id = 0);
184 : //
185 : unsigned int getIterationCounter() const;
186 : double getIterationCounterDbl() const;
187 : std::string getIterationCounterStr(const int offset=0) const;
188 : void setIterationCounter(const unsigned int);
189 : void increaseIterationCounter();
190 : //
191 821 : void apply() {};
192 821 : void calculate() {};
193 : void update();
194 0 : unsigned int getNumberOfDerivatives() {return 0;}
195 : //
196 : bool fixedStepSize() const {return fixed_stepsize_;}
197 : bool dynamicStepSize() const {return !fixed_stepsize_;}
198 : //
199 : bool useHessian() const {return use_hessian_;}
200 : bool diagonalHessian() const {return diagonal_hessian_;}
201 : //
202 568 : bool useMultipleWalkers() const {return use_mwalkers_mpi_;}
203 : //
204 : std::vector<VesBias*> getBiasPntrs() const {return bias_pntrs_;}
205 : std::vector<CoeffsVector*> getCoeffsPntrs() const {return coeffs_pntrs_;}
206 : std::vector<CoeffsVector*> getAuxCoeffsPntrs() const {return aux_coeffs_pntrs_;}
207 12 : std::vector<CoeffsVector*> getGradientPntrs()const {return gradient_pntrs_;}
208 : std::vector<CoeffsMatrix*> getHessianPntrs() const {return hessian_pntrs_;}
209 : std::vector<CoeffsVector*> getCoeffsMaskPntrs() const {return coeffs_mask_pntrs_;}
210 : std::vector<CoeffsVector*> getTargetDistAveragesPntrs() const {return targetdist_averages_pntrs_;}
211 : //
212 781 : bool isBiasOutputActive() const {return bias_output_active_;}
213 770 : unsigned int getBiasOutputStride() const {return bias_output_stride_;}
214 : void setBiasOutputStride(unsigned int stride) {bias_output_stride_=stride;}
215 : void writeBiasOutputFiles() const;
216 : //
217 781 : bool isFesOutputActive() const {return fes_output_active_;}
218 770 : unsigned int getFesOutputStride() const {return fes_output_stride_;}
219 : void setFesOutputStride(unsigned int stride) {fes_output_stride_=stride;}
220 : void writeFesOutputFiles() const;
221 : //
222 781 : bool isFesProjOutputActive() const {return fesproj_output_active_;}
223 176 : unsigned int getFesProjOutputStride() const {return fesproj_output_stride_;}
224 : void setFesProjOutputStride(unsigned int stride) {fesproj_output_stride_=stride;}
225 : void writeFesProjOutputFiles() const;
226 : //
227 852 : bool isTargetDistOutputActive() const {return targetdist_output_active_;}
228 352 : unsigned int getTargetDistOutputStride() const {return targetdist_output_stride_;}
229 : void setTargetDistOutputStride(unsigned int stride) {targetdist_output_stride_=stride;}
230 : void writeTargetDistOutputFiles() const;
231 : //
232 781 : bool isTargetDistProjOutputActive() const {return targetdist_proj_output_active_;}
233 33 : unsigned int getTargetDistProjOutputStride() const {return targetdist_proj_output_stride_;}
234 : void setTargetDistProjOutputStride(unsigned int stride) {targetdist_proj_output_stride_=stride;}
235 : void writeTargetDistProjOutputFiles() const;
236 : //
237 : };
238 :
239 : inline
240 670 : double Optimizer::StepSize(const unsigned int coeffs_id) const {return stepsizes_[coeffs_id];}
241 :
242 : inline
243 2819 : CoeffsVector& Optimizer::Coeffs(const unsigned int coeffs_id) const {return *coeffs_pntrs_[coeffs_id];}
244 :
245 : inline
246 2150 : CoeffsVector& Optimizer::AuxCoeffs(const unsigned int coeffs_id) const {return *aux_coeffs_pntrs_[coeffs_id];}
247 :
248 : inline
249 730 : CoeffsVector& Optimizer::Gradient(const unsigned int coeffs_id) const {return *gradient_pntrs_[coeffs_id];}
250 :
251 : inline
252 730 : CoeffsMatrix& Optimizer::Hessian(const unsigned int coeffs_id) const {
253 730 : plumed_massert(use_hessian_,"You cannot use the Hessian without asking for before");
254 1460 : return *hessian_pntrs_[coeffs_id];
255 : }
256 :
257 : inline
258 670 : CoeffsVector& Optimizer::CoeffsMask(const unsigned int coeffs_id) const {return *coeffs_mask_pntrs_[coeffs_id];}
259 :
260 : inline
261 : std::vector<double> Optimizer::getStepSizes() const {return stepsizes_;}
262 :
263 : inline
264 : std::vector<double> Optimizer::getCurrentStepSizes() const {return current_stepsizes;}
265 :
266 : inline
267 : double Optimizer::getStepSize(const unsigned int coeffs_id) const {return stepsizes_[coeffs_id];}
268 :
269 : inline
270 0 : double Optimizer::getCurrentStepSize(const unsigned int coeffs_id) const {return current_stepsizes[coeffs_id];}
271 :
272 : inline
273 : void Optimizer::setStepSizes(const std::vector<double>& stepsizes_in) {
274 : plumed_assert(stepsizes_in.size()==ncoeffssets_);
275 : stepsizes_ = stepsizes_in;
276 : }
277 :
278 : inline
279 : void Optimizer::setStepSize(const double stepsize_in, const unsigned int coeffs_id) {
280 : stepsizes_[coeffs_id] = stepsize_in;
281 : }
282 :
283 : inline
284 : void Optimizer::setCurrentStepSize(const double current_stepsize_in, const unsigned int coeffs_id) {
285 : current_stepsizes[coeffs_id] = current_stepsize_in;
286 : }
287 :
288 : inline
289 70 : void Optimizer::setCurrentStepSizes(const std::vector<double>& current_stepsizes_in) {
290 70 : plumed_assert(current_stepsizes_in.size()==ncoeffssets_);
291 70 : current_stepsizes = current_stepsizes_in;
292 70 : }
293 :
294 : inline
295 4438 : unsigned int Optimizer::getIterationCounter() const {return iter_counter;}
296 :
297 : inline
298 670 : double Optimizer::getIterationCounterDbl() const {return static_cast<double>(iter_counter);}
299 :
300 : inline
301 710 : void Optimizer::increaseIterationCounter() {iter_counter++;}
302 :
303 : inline
304 13 : void Optimizer::setIterationCounter(const unsigned int iter_counter_in) {iter_counter = iter_counter_in;}
305 :
306 :
307 : template<class T>
308 565 : bool Optimizer::parseMultipleValues(const std::string& keyword, std::vector<T>& values) {
309 565 : plumed_assert(ncoeffssets_>0);
310 565 : plumed_assert(values.size()==0);
311 : bool identical_values=false;
312 : //
313 565 : parseVector(keyword,values);
314 565 : if(values.size()==1 && ncoeffssets_>1) {
315 9 : values.resize(ncoeffssets_,values[0]);
316 : identical_values=true;
317 : }
318 565 : if(values.size()>0 && values.size()!=ncoeffssets_) {
319 0 : std::string s1; Tools::convert(ncoeffssets_,s1);
320 0 : plumed_merror("Error in " + keyword + " keyword: either give 1 common value for all coefficient sets or " + s1 + " separate value for each set");
321 : }
322 565 : return identical_values;
323 : }
324 :
325 : template<class T>
326 142 : bool Optimizer::parseMultipleValues(const std::string& keyword, std::vector<T>& values, const T& default_value) {
327 142 : bool identical_values = parseMultipleValues(keyword,values);
328 142 : if(values.size()==0) {
329 71 : values.resize(ncoeffssets_,default_value);
330 : identical_values=true;
331 : }
332 142 : return identical_values;
333 : }
334 :
335 : inline
336 142 : void Optimizer::parseFilenames(const std::string& keyword, std::vector<std::string>& fnames, const std::string& default_fname) {
337 142 : if(parseMultipleValues<std::string>(keyword,fnames,default_fname)) {
338 73 : addCoeffsSetIDsToFilenames(fnames,coeffssetid_prefix_);
339 : }
340 142 : }
341 :
342 : inline
343 353 : void Optimizer::parseFilenames(const std::string& keyword, std::vector<std::string>& fnames) {
344 353 : if(parseMultipleValues<std::string>(keyword,fnames)) {
345 4 : addCoeffsSetIDsToFilenames(fnames,coeffssetid_prefix_);
346 : }
347 353 : }
348 :
349 :
350 : }
351 : }
352 :
353 : #endif
|