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 :
23 : #include "TargetDistribution.h"
24 :
25 : #include "core/ActionRegister.h"
26 :
27 :
28 : namespace PLMD {
29 : namespace ves {
30 :
31 : //+PLUMEDOC VES_TARGETDIST TD_EXPONENTIAL
32 : /*
33 : Exponential distribution (static).
34 :
35 : Employ a target distribution given by an
36 : [exponential distribution](https://en.wikipedia.org/wiki/Exponential_distribution)
37 : that is defined as
38 : \f[
39 : p(s) =
40 : \lambda e^{-\lambda(s-a)}
41 : \f]
42 : where \f$a\f$ is the minimum of the distribution that is defined on the interval \f$[a,\infty)\f$,
43 : and \f$\lambda>0\f$ is the so-called rate parameter.
44 :
45 : The minimum \f$a\f$ is given using the MINIMUM keyword, and the rate parameter \f$\lambda\f$ is given
46 : using the LAMBDA keyword.
47 :
48 : This target distribution action is only defined for one dimension, for multiple dimensions
49 : it should be used in combination with \ref TD_PRODUCT_DISTRIBUTION action.
50 :
51 : \par Examples
52 :
53 : Exponential distribution with \f$a=10.0\f$ and \f$\lambda=0.5\f$
54 : \plumedfile
55 : td: TD_EXPONENTIAL MINIMUM=-10.0 LAMBDA=0.5
56 : \endplumedfile
57 :
58 : The exponential distribution is only defined for one dimension so for multiple
59 : dimensions we have to use it in combination with the \ref TD_PRODUCT_DISTRIBUTION action as shown in
60 : the following example where we have a uniform distribution for argument 1 and
61 : and an exponential distribution for argument 2
62 : \plumedfile
63 : td_uni: TD_UNIFORM
64 :
65 : td_exp: TD_EXPONENTIAL MINIMUM=-10.0 LAMBDA=0.5
66 :
67 : td_pd: TD_PRODUCT_DISTRIBUTION DISTRIBUTIONS=td_uni,td_exp
68 : \endplumedfile
69 :
70 :
71 : */
72 : //+ENDPLUMEDOC
73 :
74 24 : class TD_Exponential: public TargetDistribution {
75 : std::vector<double> minima_;
76 : std::vector<double> lambda_;
77 : public:
78 : static void registerKeywords(Keywords&);
79 : explicit TD_Exponential(const ActionOptions& ao);
80 : double getValue(const std::vector<double>&) const;
81 : };
82 :
83 :
84 6460 : PLUMED_REGISTER_ACTION(TD_Exponential,"TD_EXPONENTIAL")
85 :
86 :
87 9 : void TD_Exponential::registerKeywords(Keywords& keys) {
88 9 : TargetDistribution::registerKeywords(keys);
89 36 : keys.add("compulsory","MINIMUM","The minimum of the exponential distribution.");
90 36 : keys.add("compulsory","LAMBDA","The \\f$\\lambda\\f$ parameter of the exponential distribution given as postive number.");
91 18 : keys.use("WELLTEMPERED_FACTOR");
92 18 : keys.use("SHIFT_TO_ZERO");
93 18 : keys.use("NORMALIZE");
94 9 : }
95 :
96 :
97 8 : TD_Exponential::TD_Exponential(const ActionOptions& ao):
98 : PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
99 : minima_(0),
100 8 : lambda_(0)
101 : {
102 16 : parseVector("MINIMUM",minima_);
103 16 : parseVector("LAMBDA",lambda_);
104 40 : for(unsigned int k=0; k<lambda_.size(); k++) {
105 8 : if(lambda_[k] < 0.0) {plumed_merror(getName()+": the value given in LAMBDA should be postive.");}
106 : }
107 :
108 :
109 8 : setDimension(minima_.size());
110 8 : if(getDimension()>1) {plumed_merror(getName()+": only defined for one dimension, for multiple dimensions it should be used in combination with the TD_PRODUCT_DISTRIBUTION action.");}
111 8 : if(lambda_.size()!=getDimension()) {plumed_merror(getName()+": the LAMBDA keyword does not match the given dimension in MINIMUM");}
112 8 : checkRead();
113 8 : }
114 :
115 :
116 1308 : double TD_Exponential::getValue(const std::vector<double>& argument) const {
117 : double value = 1.0;
118 6540 : for(unsigned int k=0; k<argument.size(); k++) {
119 3924 : double arg = (argument[k]-minima_[k])*lambda_[k];
120 1308 : if(arg<0.0) {plumed_merror(getName()+": the exponential distribution is not defined for values less that ones given in MINIMUM");}
121 1308 : value *= lambda_[k]*exp(-arg);
122 : }
123 1308 : return value;
124 : }
125 :
126 :
127 :
128 : }
129 4839 : }
|