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