SSAGES  0.8.3
Software Suite for Advanced General Ensemble Simulations
Basis.h
1 #include <cmath>
2 #include "json/json.h"
3 #include "../Grids/Grid.h"
4 
5 #define UNUSED(x) (void)(x)
6 
7 namespace SSAGES
8 {
10 
16  struct BasisLUT
17  {
19  std::vector<double> values;
20 
22  std::vector<double> derivs;
23 
25 
29  BasisLUT(const std::vector<double>& values,
30  const std::vector<double>& derivs) :
31  values(values), derivs(derivs)
32  {}
33  };
34 
36 
41  struct Map
42  {
44  double value;
45 
47  std::vector<int> map;
48 
50 
54  Map(const std::vector<int>& map,
55  double value) :
56  value(value), map(map)
57  {}
58  };
59 
62  {
63  protected:
64  unsigned int polyOrd_;
65  unsigned int nbins_;
66  bool isFinite_;
67  bool zeroOrder_;
68  double boundLow_;
69  double boundUp_;
70 
71  public:
73 
84  BasisFunction(unsigned int polyOrd,
85  unsigned int nbins,
86  bool isFinite,
87  bool zeroOrder,
88  double boundLow,
89  double boundUp) :
90  polyOrd_(polyOrd), nbins_(nbins), isFinite_(isFinite), zeroOrder_(zeroOrder),
91  boundLow_(boundLow), boundUp_(boundUp)
92  {
93  }
94 
96  unsigned int GetOrder() {return polyOrd_;}
97 
99  unsigned int GetBins() {return nbins_;}
100 
102  bool GetZeroOrder() {return zeroOrder_;}
103 
105  double GetLower() {return boundLow_;}
106 
108  double GetUpper() {return boundUp_;}
109 
111  double GetRange()
112  {
113  if(isFinite_)
114  return boundUp_ - boundLow_;
115  // No infinitely bounded basis functions are included currently so this is going to return nothing for right now
116  else
117  return 0.0;
118  }
119 
121 
126  virtual double GetNorm(int order) {
127  UNUSED(order);
128  return 0;
129  }
130 
132 
138  virtual double Evaluate(double val, int order) {
139  UNUSED(val);
140  UNUSED(order);
141  return 0;
142  }
143 
145 
151  virtual double EvalGrad(double val, int order) {
152  UNUSED(val);
153  UNUSED(order);
154  return 0;
155  }
156 
158 
163  virtual double Weight(double val) {
164  UNUSED(val);
165  return 1;
166  }
167 
169 
176  static BasisFunction* Build(const Json::Value& json, const std::string& path, unsigned int nbins);
177 
179  virtual ~BasisFunction() {}
180  };
181 
183  class Chebyshev : public BasisFunction
184  {
185  private:
186  protected:
187  public:
189 
197  Chebyshev(unsigned int polyOrd, double boundLow, double boundUp, unsigned int nbins) :
198  BasisFunction(polyOrd, nbins, true, false, boundLow, boundUp)
199  {
200  }
201 
202  double ChangeVariable(double x)
203  {
204  return (x-boundLow_)*2.0/(boundUp_ - boundLow_)-1.0;
205  }
206 
207  //Quick recursive relation to evaluate the basis sets
208  double Evaluate(double x, int n)
209  {
210  double xMod = ChangeVariable(x);
211  return n == 0 ? 1.0 :
212  n == 1 ? xMod :
213  2.0*xMod*Evaluate(x,n-1) - Evaluate(x,n-2);
214  }
215  //Same but for the gradients
216  double EvalGrad(double x, int n)
217  {
218  double xMod = ChangeVariable(x);
219  return n == 0 ? 0.0 :
220  n == 1 ? 1.0 :
221  2.0*(Evaluate(x,n-1) + xMod * EvalGrad(x,n-1)) - EvalGrad(x,n-2);
222  }
223 
224  double Weight(double x)
225  {
226  double xMod = ChangeVariable(x);
227  return 1.0/sqrt(1.0-xMod*xMod);
228  }
229 
230  double GetNorm(int /* n */)
231  {
232  return 2.0/M_PI;
233  }
234 
236  static Chebyshev* Build(const Json::Value& json, const std::string& path, unsigned int nbins);
237 
238  };
239 
241  class Legendre : public BasisFunction
242  {
243  private:
244  protected:
245  public:
247 
253  Legendre(unsigned int polyOrd, unsigned int nbins) :
254  BasisFunction(polyOrd, nbins, true, false, -1.0, 1.0)
255  {
256  }
257 
258  //Quick recursive relation to evaluate the basis sets
259  double Evaluate(double x, int n)
260  {
261  return n == 0 ? 1.0 :
262  n == 1 ? x :
263  (2.0*n-1.0)/(double)n*x*Evaluate(x,n-1) - (n-1.0)/(double)n*Evaluate(x,n-2);
264  }
265 
266  //Same but for the gradients
267  double EvalGrad(double x, int n)
268  {
269  return n == 0 ? 0.0 :
270  n == 1 ? 1.0 :
271  (2.0*n-1.0)/(double)n*(Evaluate(x,n-1) + x * EvalGrad(x,n-1)) - (n-1.0)/(double)n*EvalGrad(x,n-2);
272  }
273 
274  double GetNorm(int n)
275  {
276  return n + 0.5;
277  }
278 
280  static Legendre* Build(const Json::Value& json, const std::string& path, unsigned int nbins);
281  };
282 
284  class Fourier : public BasisFunction
285  {
286  private:
287  protected:
288  public:
290 
298  Fourier(unsigned int polyOrd, double boundLow, double boundUp, unsigned int nbins) :
299  BasisFunction(polyOrd, nbins, true, true, boundLow, boundUp)
300  {
301  }
302 
303  //For the Fourier series, I am choosing to split the coefficients in two
304  //The first odd coefficients are the sine series and the even are cosine
305  //However when evaluated, they will be treated as n, just stored differently
306  double Evaluate(double x, int n)
307  {
308  return n == 0 ? 0.5 :
309  n % 2 == 1 ? std::sin(2.0*floor(double(n)*0.5)*M_PI*x/(boundUp_-boundLow_)) :
310  std::cos(2.0*floor(double(n)*0.5)*M_PI*x/(boundUp_-boundLow_));
311  }
312 
313  //Same but for the gradients
314  double EvalGrad(double x, int n)
315  {
316  return n == 0 ? 0.0 :
317  n % 2 == 0 ? (-2.0*floor(double(n)*0.5)*M_PI/(boundUp_-boundLow_))*(std::sin(2.0*floor(double(n)*0.5)*M_PI*x/(boundUp_-boundLow_))) :
318  (2.0*floor(double(n)*0.5)*M_PI/(boundUp_-boundLow_))*std::cos(2.0*floor(double(n)*0.5)*M_PI*x/(boundUp_-boundLow_));
319  }
320 
321  double GetNorm(int /* n */)
322  {
323  //Assumes the period of the function is the range of the CV
324  return 2.0/(boundUp_-boundLow_);
325  }
326 
328  static Fourier* Build(const Json::Value& json, const std::string& path, unsigned int nbins);
329  };
330 
333  {
334  private:
335  std::vector<Map> coeff_;
336  std::vector<BasisFunction*> functions_;
337  std::vector<BasisLUT> lookup_;
338 
339  public:
341 
346  BasisEvaluator(const std::vector<BasisFunction*>& functions) :
347  functions_(functions)
348  {
349  CoeffInit();
350  BasisInit();
351  }
352 
355  void CoeffInit();
356  void BasisInit();
357 
359  void UpdateBias(Grid<double> *bias, Grid<std::vector<double>> *grad);
360 
363 
369  double UpdateCoeff(const std::vector<double> &array, Grid<unsigned int> *hist);
370 
372  std::vector<double> GetCoeff(void)
373  {
374  std::vector<double> coeffArray (coeff_.size(),0);
375  for (size_t i=0; i<coeff_.size(); i++)
376  {
377  coeffArray[i] = coeff_[i].value;
378  }
379  return coeffArray;
380  }
381 
383  void SetCoeff(const std::vector<double>& coeff)
384  {
385  size_t ii = 0;
386  for(auto& val : coeff_)
387  {
388  val.value = coeff[ii];
389  ii++;
390  }
391  }
392 
393  ~BasisEvaluator() {}
394  };
395 }
double value
The coefficient value.
Definition: Basis.h:44
Legendre(unsigned int polyOrd, unsigned int nbins)
Constructor.
Definition: Basis.h:253
std::vector< BasisFunction * > functions_
Vector of basis functions.
Definition: Basis.h:336
BasisLUT(const std::vector< double > &values, const std::vector< double > &derivs)
Constructor.
Definition: Basis.h:29
double GetRange()
Gets the magnitude of the range of bounds.
Definition: Basis.h:111
double Weight(double x)
Calculates the gradient of the basis function.
Definition: Basis.h:224
bool GetZeroOrder()
Gets the flag for constant-order polynomials.
Definition: Basis.h:102
double GetNorm(int)
Gets the norm of the basis function.
Definition: Basis.h:230
BasisEvaluator(const std::vector< BasisFunction *> &functions)
Constructor.
Definition: Basis.h:346
Map(const std::vector< int > &map, double value)
Constructor.
Definition: Basis.h:54
unsigned int GetBins()
Gets the number of bins for the discretization.
Definition: Basis.h:99
double Evaluate(double x, int n)
Calculates the output of the basis function.
Definition: Basis.h:306
Fourier(unsigned int polyOrd, double boundLow, double boundUp, unsigned int nbins)
Constructor.
Definition: Basis.h:298
double GetNorm(int)
Gets the norm of the basis function.
Definition: Basis.h:321
Map for histogram and coefficients.
Definition: Basis.h:41
bool isFinite_
Flag for finite-range polynomials.
Definition: Basis.h:66
virtual double Evaluate(double val, int order)
Calculates the output of the basis function.
Definition: Basis.h:138
std::vector< Map > coeff_
Vector of basis function coefficients.
Definition: Basis.h:335
double EvalGrad(double x, int n)
Calculates the gradient of the basis function.
Definition: Basis.h:267
unsigned int nbins_
Number of bins.
Definition: Basis.h:65
double EvalGrad(double x, int n)
Calculates the gradient of the basis function.
Definition: Basis.h:216
double boundUp_
Upper bound on CV.
Definition: Basis.h:69
double boundLow_
Lower bound on CV.
Definition: Basis.h:68
Calculates the inner product of all the basis functions and the histogram.
Definition: Basis.h:332
Abstract class for all BasisFunction inheritance.
Definition: Basis.h:61
Look-up table for basis functions.
Definition: Basis.h:16
unsigned int polyOrd_
Order of the polynomial.
Definition: Basis.h:64
double GetNorm(int n)
Gets the norm of the basis function.
Definition: Basis.h:274
Chebyshev(unsigned int polyOrd, double boundLow, double boundUp, unsigned int nbins)
Constructor.
Definition: Basis.h:197
Defines the class of Legendre polynomials.
Definition: Basis.h:241
std::vector< double > values
The values of the basis sets.
Definition: Basis.h:19
double Evaluate(double x, int n)
Calculates the output of the basis function.
Definition: Basis.h:259
virtual double GetNorm(int order)
Gets the norm of the basis function.
Definition: Basis.h:126
double GetUpper()
Gets the upper bound on the CV.
Definition: Basis.h:108
unsigned int GetOrder()
Gets the order of the current polynomial.
Definition: Basis.h:96
std::vector< double > derivs
The values of the derivatives of the basis sets.
Definition: Basis.h:22
Defines the class of Chebyshev polynomials.
Definition: Basis.h:183
Defines the class of Fourier polynomials.
Definition: Basis.h:284
void SetCoeff(const std::vector< double > &coeff)
Set the coefficient array in the event of a restart run.
Definition: Basis.h:383
virtual double EvalGrad(double val, int order)
Calculates the gradient of the basis function.
Definition: Basis.h:151
std::vector< double > GetCoeff(void)
Gets the coefficient array.
Definition: Basis.h:372
bool zeroOrder_
Flag for constant-order polynomials.
Definition: Basis.h:67
virtual double Weight(double val)
Calculates the gradient of the basis function.
Definition: Basis.h:163
double Evaluate(double x, int n)
Calculates the output of the basis function.
Definition: Basis.h:208
double GetLower()
Gets the lower bound on the CV.
Definition: Basis.h:105
double EvalGrad(double x, int n)
Calculates the gradient of the basis function.
Definition: Basis.h:314
std::vector< int > map
The mapping in an array of integers.
Definition: Basis.h:47
std::vector< BasisLUT > lookup_
Lookup table for basis functions.
Definition: Basis.h:337
virtual ~BasisFunction()
Destructor.
Definition: Basis.h:179
BasisFunction(unsigned int polyOrd, unsigned int nbins, bool isFinite, bool zeroOrder, double boundLow, double boundUp)
Constructor.
Definition: Basis.h:84