All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Moments.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 #include "vesselbase/VesselRegister.h"
23 #include "StoreColvarVessel.h"
24 #include "vesselbase/ActionWithVessel.h"
25 
26 namespace PLMD {
27 namespace multicolvar{
28 
29 // This is not the most efficient implementation
30 // The calculation of all the colvars is parallelized
31 // but the loops for calculating moments are not
32 // Feel free to reimplement this if you know how
33 class Moments : public StoreColvarVessel {
34 private:
35  std::vector<unsigned> powers;
36  std::vector<Value*> value_out;
37 public:
38  static void registerKeywords( Keywords& keys );
39  static void reserveKeyword( Keywords& keys );
41  std::string description();
43  void local_resizing();
44  bool applyForce( std::vector<double>& forces );
45 };
46 
48 
49 void Moments::registerKeywords( Keywords& keys ){
51 }
52 
54  keys.reserve("optional","MOMENTS","calculate the moments of the distribution of collective variables. "
55  "The \\f$m\\f$th moment of a distribution is calculated using \\f$\\frac{1}{N} \\sum_{i=1}^N ( s_i - \\overline{s} )^m \\f$, where \\f$\\overline{s}\\f$ is "
56  "the average for the distribution. The moments keyword takes a lists of integers as input or a range. Each integer is a value of \\f$m\\f$. The final "
57  "calculated values can be referenced using moment-\\f$m\\f$.");
58  keys.addOutputComponent("moment","MOMENTS","the central moments of the distribution of values. The second moment "
59  "would be referenced elsewhere in the input file using "
60  "<em>label</em>.moment-2, the third as <em>label</em>.moment-3, etc.");
61 }
62 
65 {
66  ActionWithValue* a=dynamic_cast<ActionWithValue*>( getAction() );
67  plumed_massert(a,"cannot create passable values as base action does not inherit from ActionWithValue");
68  plumed_massert(!diffweight,"cannot do weighted moments properly");
69 
70  std::vector<std::string> moments=Tools::getWords(getAllInput(),"\t\n ,");
71  Tools::interpretRanges(moments); unsigned nn;
72  for(unsigned i=0;i<moments.size();++i){
73  a->addComponentWithDerivatives( "moment-" + moments[i] );
74  a->componentIsNotPeriodic( "moment-" + moments[i] );
75  value_out.push_back( a->copyOutput( a->getNumberOfComponents()-1 ) );
76  Tools::convert( moments[i], nn );
77  if( nn<2 ) error("moments are only possible for m>=2" );
78  powers.push_back( nn ); std::string num; Tools::convert(powers[i],num);
79  }
80 }
81 
83  unsigned nder=getAction()->getNumberOfDerivatives();
84  for(unsigned i=0;i<value_out.size();++i) value_out[i]->resizeDerivatives( nder );
85 }
86 
87 std::string Moments::description(){
88  std::string descri, num;
89  Tools::convert(powers[0],num);
90  descri = "value " + getAction()->getLabel() + "." + "moment-" + num + " contains the " + num + "th moment of the distribution";
91  for(unsigned i=1;i<powers.size();++i){
92  Tools::convert(powers[i],num);
93  descri = descri + "\n value " + getAction()->getLabel() + "." + "moment-" + num + " contains the " + num + "th moment of the distribution";
94  }
95  return descri;
96 }
97 
99  const double pi=3.141592653589793238462643383279502884197169399375105820974944592307;
100  unsigned nvals=getNumberOfStoredColvars();
101 
102  double mean=0; Value myvalue;
103  if( getAction()->isPeriodic() ){
104  std::string str_min, str_max; getAction()->retrieveDomain( str_min, str_max );
105  double pfactor, min, max; Tools::convert(str_min,min); Tools::convert(str_max,max);
106  pfactor = 2*pi / ( max-min ); myvalue.setDomain( str_min, str_max );
107  double sinsum=0, cossum=0, val;
108  for(unsigned i=0;i<nvals;++i){ val=pfactor*( getValue(i) - min ); sinsum+=sin(val); cossum+=cos(val); }
109  mean = 0.5 + atan2( sinsum / static_cast<double>( nvals ) , cossum / static_cast<double>( nvals ) ) / (2*pi);
110  mean = min + (max-min)*mean;
111  } else {
112  for(unsigned i=0;i<nvals;++i) mean+=getValue(i);
113  mean/=static_cast<double>( nvals ); myvalue.setNotPeriodic();
114  }
115 
116  for(unsigned npow=0;npow<powers.size();++npow){
117  double dev1=0;
118  for(unsigned i=0;i<nvals;++i) dev1+=pow( myvalue.difference( mean, getValue(i) ), powers[npow] - 1 );
119  dev1/=static_cast<double>( nvals );
120 
121  double pref, tmp, moment=0;
122  for(unsigned i=0;i<nvals;++i){
123  tmp=myvalue.difference( mean, getValue(i) );
124  pref=pow( tmp, powers[npow] - 1 ) - dev1;
125  moment+=pow( tmp, powers[npow] );
126  addDerivatives( i, pref, value_out[npow] );
127  }
128  value_out[npow]->chainRule( powers[npow] / static_cast<double>( nvals ) );
129  value_out[npow]->set( moment / static_cast<double>( nvals ) );
130  }
131 }
132 
133 bool Moments::applyForce( std::vector<double>& forces ){
134  std::vector<double> tmpforce( forces.size() );
135  forces.assign(forces.size(),0.0); bool wasforced=false;
136  for(unsigned i=0;i<value_out.size();++i){
137  if( value_out[i]->applyForce( tmpforce ) ){
138  wasforced=true;
139  for(unsigned j=0;j<forces.size();++j) forces[j]+=tmpforce[j];
140  }
141  }
142  return wasforced;
143 }
144 
145 }
146 }
double difference(double) const
Calculate the difference between the instantaneous value of the function and some other point: other_...
Definition: Value.h:276
void performCalculationUsingAllValues()
Do the calculation.
Definition: Moments.cpp:98
void componentIsNotPeriodic(const std::string &name)
Set your value component to have no periodicity.
static void reserveKeyword(Keywords &keys)
Definition: Moments.cpp:53
A class for holding the value of a function together with its derivatives.
Definition: Value.h:46
virtual unsigned getNumberOfDerivatives()=0
Get the number of derivatives for final calculated quantity.
std::string description()
Return a description of the vessel contents.
Definition: Moments.cpp:87
static bool convert(const std::string &str, double &t)
Convert a string to a double, reading it.
Definition: Tools.cpp:74
unsigned getNumberOfStoredColvars() const
Get the number of stored colvar values.
const std::string & getLabel() const
Returns the label.
Definition: Action.h:263
void addDerivatives(const unsigned &ival, double &pref, Value *value_out)
Add the derivatives from the value.
double getValue(const unsigned &) const
Get the ith value in the vessel.
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
Used to create a PLMD::Action that has some scalar or vectorial output that may or may not have some ...
This class holds the keywords and their documentation.
Definition: Keywords.h:36
void setNotPeriodic()
Set the function not periodic.
Definition: Value.cpp:87
virtual void retrieveDomain(std::string &min, std::string &max)
What are the domains of the base quantities.
static void registerKeywords(Keywords &keys)
#define PLUMED_REGISTER_VESSEL(classname, keyword)
static std::vector< std::string > getWords(const std::string &line, const char *sep=NULL, int *parlevel=NULL, const char *parenthesis="{")
Split the line in words using separators.
Definition: Tools.cpp:112
std::vector< unsigned > powers
Definition: Moments.cpp:35
Value * copyOutput(const std::string &name) const
Return a pointer to the value with name (this is used to retrieve values in other PLMD::Actions) You ...
static void interpretRanges(std::vector< std::string > &)
Interpret atom ranges.
Definition: Tools.cpp:231
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
This class is used to pass the input to Vessels.
Definition: Vessel.h:53
const double pi(3.141592653589793238462643383279502884197169399375105820974944592307)
PI.
void local_resizing()
This makes sure things further down the chain are resized.
Definition: Moments.cpp:82
void int double * da
Definition: Matrix.h:47
void addComponentWithDerivatives(const std::string &name)
Add a value with a name like label.name that has derivatives.
static void registerKeywords(Keywords &keys)
Definition: Moments.cpp:49
bool applyForce(std::vector< double > &forces)
Retrieve the forces on the quantities in the vessel.
Definition: Moments.cpp:133
int getNumberOfComponents() const
Returns the number of values defined.
Moments(const vesselbase::VesselOptions &da)
Definition: Moments.cpp:63
bool diffweight
Are the weights differentiable.
void const char const char int double * a
Definition: Matrix.h:42
std::vector< Value * > value_out
Definition: Moments.cpp:36
void setDomain(const std::string &, const std::string &)
Set the domain of the function.
Definition: Value.cpp:91
std::string getAllInput()
This returns the whole input line (it is used for less_than/more_than/between)
Definition: Vessel.cpp:84
ActionWithVessel * getAction()
Return a pointer to the action we are working in.
Definition: Vessel.h:236