Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2015-2023 The plumed team 3 : (see the PEOPLE file at the root of the distribution for a list of names) 4 : 5 : See http://www.plumed.org for more information. 6 : 7 : This file is part of plumed, version 2. 8 : 9 : plumed 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 : plumed 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 plumed. If not, see <http://www.gnu.org/licenses/>. 21 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ 22 : #ifndef __PLUMED_tools_MinimiseBase_h 23 : #define __PLUMED_tools_MinimiseBase_h 24 : 25 : #include "Minimise1DBrent.h" 26 : 27 : namespace PLMD { 28 : 29 : template <class FCLASS> 30 : class F1dim { 31 : private: 32 : /// This is the pointer to the member function in the energy 33 : /// calculating class that calculates the energy 34 : typedef double(FCLASS::*engf_pointer)( const std::vector<double>& p, std::vector<double>& der ) const ; 35 : typedef double(FCLASS::*engfnc_pointer)( const std::vector<double>& p, std::vector<double>& der ) ; 36 : /// Pointer to the vector containing an initial position on the vector 37 : const std::vector<double>& p; 38 : /// The direction of the vector we are minimising along 39 : const std::vector<double>& dir; 40 : /// Tempory vector that holds a point at which we want to calculate the energy 41 : std::vector<double> pt; 42 : /// Vector that holds the derivatives at the point at which we calculate the energy (these are not used) 43 : std::vector<double> fake_der; 44 : /// Class containging the function in the class 45 : FCLASS* func; 46 : /// Member of class that calculates the energy we are trying to mnimise 47 : engf_pointer calc; 48 : /// Member of class that calcualtes the energy we are trying to minimise 49 : engfnc_pointer calc2; 50 : public: 51 : explicit F1dim( const std::vector<double>& pp, const std::vector<double>& dd, FCLASS* ff, engf_pointer cc, engfnc_pointer cc2 ); 52 : /// Calculate the energy at \f$\mathbf{p} + xt*\mathbf{dir}\f$ 53 : double getEng( const double& xt ); 54 : }; 55 : 56 : template <class FCLASS> 57 2413 : F1dim<FCLASS>::F1dim( const std::vector<double>& pp, const std::vector<double>& dd, FCLASS* ff, engf_pointer cc, engfnc_pointer cc2 ): 58 2413 : p(pp), 59 2413 : dir(dd), 60 2413 : pt(pp.size()), 61 2413 : fake_der(pp.size()), 62 2413 : func(ff), 63 2413 : calc(cc), 64 2413 : calc2(cc2) 65 : { 66 2413 : plumed_assert( calc || calc2 ); 67 2413 : } 68 : 69 : template <class FCLASS> 70 28203 : double F1dim<FCLASS>::getEng( const double& xt ) { 71 465492 : for(unsigned j=0; j<pt.size(); ++j) pt[j] = p[j] + xt*dir[j]; 72 28203 : if( calc ) return (func->*calc)(pt,fake_der); 73 19960 : return (func->*calc2)(pt,fake_der); 74 : } 75 : 76 : template <class FCLASS> 77 : class MinimiseBase { 78 : private: 79 : /// This is the pointer to the member function in the energy 80 : /// calculating class that calculates the energy 81 : typedef double(FCLASS::*engf_pointer)( const std::vector<double>& p, std::vector<double>& der ); 82 : /// The class that calculates the energy given a position 83 : FCLASS* myclass_func; 84 : protected: 85 : /// This calculates the derivatives at a point 86 : double calcDerivatives( const std::vector<double>& p, std::vector<double>& der, engf_pointer myfunc ); 87 : public: 88 505 : explicit MinimiseBase( FCLASS* funcc ) : myclass_func(funcc) {} 89 : /// This is the line minimiser 90 : double linemin( const std::vector<double>& dir, std::vector<double>& p, engf_pointer myfunc ); 91 : }; 92 : 93 : template <class FCLASS> 94 897 : double MinimiseBase<FCLASS>::linemin( const std::vector<double>& dir, std::vector<double>& p, engf_pointer myfunc ) { 95 : // Construct the object that turns points on a line into vectors 96 897 : F1dim<FCLASS> f1dim( p, dir, myclass_func, NULL, myfunc ); 97 : 98 : // Construct an object that will do the line search for the minimum 99 897 : Minimise1DBrent<F1dim<FCLASS> > bb(f1dim); 100 : 101 : // This does the actual line minimisation 102 897 : double ax=0.0, xx=1.0; 103 897 : bb.bracket( ax, xx, &F1dim<FCLASS>::getEng ); 104 897 : double xmin=bb.minimise( &F1dim<FCLASS>::getEng ); 105 19725 : for(unsigned i=0; i<p.size(); ++i) p[i] += xmin*dir[i]; 106 1794 : return bb.getMinimumValue(); 107 897 : } 108 : 109 : template <class FCLASS> 110 897 : double MinimiseBase<FCLASS>::calcDerivatives( const std::vector<double>& p, std::vector<double>& der, engf_pointer myfunc ) { 111 897 : return (myclass_func->*myfunc)( p, der ); 112 : } 113 : 114 : } 115 : #endif