All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Between.cpp
Go to the documentation of this file.
1 /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2  Copyright (c) 2013 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-code.org for more information.
6 
7  This file is part of plumed, version 2.0.
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 
23 #include "VesselRegister.h"
24 #include "FunctionVessel.h"
25 #include "tools/HistogramBead.h"
26 #include "ActionWithVessel.h"
27 
28 namespace PLMD {
29 namespace vesselbase {
30 
31 class Between : public FunctionVessel {
32 private:
33  bool norm;
34  std::vector<double> df;
36 public:
37  static void registerKeywords( Keywords& keys );
38  static void reserveKeyword( Keywords& keys );
39  Between( const VesselOptions& da );
40  std::string function_description();
41  bool calculate();
42  void finish();
43 };
44 
46 
47 void Between::registerKeywords( Keywords& keys ){
50  keys.addFlag("NORM",false,"calculate the fraction of values rather than the number");
51 }
52 
54  keys.reserve("numbered","BETWEEN","calculate the number of values that are within a certain range. "
55  "These quantities are calculated using kernel density estimation as described on "
56  "\\ref histogrambead.",true);
57  keys.addOutputComponent("between","BETWEEN","the number/fraction of values within a certain range. This is calculated using one of the "
58  "formula described in the description of the keyword so as to make it continuous. "
59  "You can calculate this quantity multiple times using different parameters.");
60 }
61 
64 {
65 
66  bool isPeriodic=getAction()->isPeriodic();
67  double min, max; std::string str_min, str_max;
68  if( isPeriodic ){
69  getAction()->retrieveDomain( str_min, str_max );
70  Tools::convert(str_min,min); Tools::convert(str_max,max);
71  }
72 
73  parseFlag("NORM",norm); std::string errormsg; df.resize(2);
74 
75  hist.set( getAllInput(),"",errormsg );
76  if( !isPeriodic ) hist.isNotPeriodic();
77  else hist.isPeriodic( min, max );
78  if( errormsg.size()!=0 ) error( errormsg );
79 }
80 
82  if(norm) return "the fraction of values " + hist.description();
83  return "the number of values " + hist.description();
84 }
85 
87  double weight=getAction()->getElementValue(1);
88  plumed_dbg_assert( weight>=getTolerance() );
89  double val=getAction()->getElementValue(0);
90  double dval, f = hist.calculate(val, dval);
91 
92  addValueIgnoringTolerance(1,weight);
93  double contr=weight*f;
94  bool addval=addValueUsingTolerance(0,contr);
95  if( addval ){
96  getAction()->chainRuleForElementDerivatives( 0, 0, weight*dval, this );
97  if(diffweight){
98  getAction()->chainRuleForElementDerivatives( 0, 1, f, this );
99  if(norm) getAction()->chainRuleForElementDerivatives( 1, 1, 1.0, this );
100  }
101  }
102  return ( contr>getNLTolerance() );
103 }
104 
106  double denom=getFinalValue(1);
107  if( norm && diffweight ){
108  df[0] = 1.0 / denom;
109  setOutputValue( getFinalValue(0) / denom );
110  df[1] = -getFinalValue(0) / ( denom*denom );
112  } else if (norm) {
113  df[0] = 1.0 / denom; df[1]=0.0;
114  setOutputValue( getFinalValue(0) / denom );
116  } else {
118  df[0] = 1.0; df[1]=0.0;
120  }
121 }
122 
123 }
124 }
HistogramBead hist
Definition: Between.cpp:35
void finish()
Complete the calculation once the loop is finished.
Definition: Between.cpp:105
static void reserveKeyword(Keywords &keys)
Definition: Between.cpp:53
static void registerKeywords(Keywords &keys)
Definition: Between.cpp:47
double getTolerance() const
Return the value of the tolerance.
Definition: Vessel.h:226
double getFinalValue(const unsigned &j)
Get the nth value in the distribution.
bool diffweight
Are the derivatives differentiable.
void chainRuleForElementDerivatives(const unsigned &, const unsigned &, const double &, Vessel *)
Merge the derivatives.
static bool convert(const std::string &str, double &t)
Convert a string to a double, reading it.
Definition: Tools.cpp:74
static void registerKeywords(Keywords &keys)
void setOutputValue(const double &val)
Set the final value.
Objects that inherit from FunctionVessel can be used (in tandem with PLMD::ActionWithVessel) to calcu...
static void registerKeywords(Keywords &keys)
void mergeFinalDerivatives(const std::vector< double > &df)
This does a combination of the product and chain rules.
void isPeriodic(const double &mlow, const double &mhigh)
Definition: HistogramBead.h:78
void addOutputComponent(const std::string &name, const std::string &key, const std::string &descr)
Add a potential component which can be output by this particular action.
Definition: Keywords.cpp:565
This class holds the keywords and their documentation.
Definition: Keywords.h:36
void parseFlag(const std::string &key, bool &t)
Parse one keyword as boolean flag.
Definition: Vessel.cpp:93
void addValueIgnoringTolerance(const unsigned &jval, const double &val)
Add some value to the accumulator and ignore the tolerance.
A class for calculating whether or not values are within a given range using : .
Definition: HistogramBead.h:41
virtual void retrieveDomain(std::string &min, std::string &max)
What are the domains of the base quantities.
#define PLUMED_REGISTER_VESSEL(classname, keyword)
std::string description() const
Between(const VesselOptions &da)
Definition: Between.cpp:62
void reserve(const std::string &t, const std::string &k, const std::string &d, const bool isvessel=false)
Reserve a keyword.
Definition: Keywords.cpp:110
void error(const std::string &errmsg)
Report an error.
Definition: Vessel.cpp:122
void set(const std::string &params, const std::string &dd, std::string &errormsg)
This class is used to pass the input to Vessels.
Definition: Vessel.h:53
void int double * da
Definition: Matrix.h:47
virtual bool isPeriodic()=0
Are the base quantities periodic.
bool addValueUsingTolerance(const unsigned &jval, const double &val)
Add some value to the accumulator if it is greater than tolerance.
std::string function_description()
The rest of the description of what we are calculating.
Definition: Between.cpp:81
bool calculate()
Calculate the part of the vessel that is done in the loop.
Definition: Between.cpp:86
std::vector< double > df
Definition: Between.cpp:34
double calculate(double x, double &df) const
double getNLTolerance() const
Return the value of the neighbor list tolerance.
Definition: Vessel.h:231
std::string getAllInput()
This returns the whole input line (it is used for less_than/more_than/between)
Definition: Vessel.cpp:84
double getElementValue(const unsigned &ival) const
Get the value of this element.
ActionWithVessel * getAction()
Return a pointer to the action we are working in.
Definition: Vessel.h:236