SSAGES  0.9.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 namespace SSAGES
6 {
8 
14  struct BasisLUT
15  {
17  std::vector<double> values;
18 
20  std::vector<double> derivs;
21 
23 
27  BasisLUT(const std::vector<double>& values,
28  const std::vector<double>& derivs) :
30  {}
31  };
32 
34 
39  struct Map
40  {
42  double value;
43 
45  std::vector<int> map;
46 
48 
52  Map(const std::vector<int>& map,
53  double value) :
54  value(value), map(map)
55  {}
56  };
57 
60  {
61  protected:
62  unsigned int polyOrd_;
63  unsigned int nbins_;
64  bool isFinite_;
65  bool zeroOrder_;
66  double boundLow_;
67  double boundUp_;
68 
69  public:
71 
82  BasisFunction(unsigned int polyOrd,
83  unsigned int nbins,
84  bool isFinite,
85  bool zeroOrder,
86  double boundLow,
87  double boundUp) :
88  polyOrd_(polyOrd), nbins_(nbins), isFinite_(isFinite), zeroOrder_(zeroOrder),
89  boundLow_(boundLow), boundUp_(boundUp)
90  {
91  }
92 
94 
97  unsigned int GetOrder() {return polyOrd_;}
98 
100 
103  unsigned int GetBins() {return nbins_;}
104 
106 
109  bool GetZeroOrder() {return zeroOrder_;}
110 
112 
115  double GetLower() {return boundLow_;}
116 
118 
121  double GetUpper() {return boundUp_;}
122 
124 
127  double GetRange()
128  {
129  if(isFinite_)
130  return boundUp_ - boundLow_;
131  // No infinitely bounded basis functions are included currently so this is going to return nothing for right now
132  else
133  return 0.0;
134  }
135 
137 
142  virtual double GetNorm(int /* order */) {
143  return 0;
144  }
145 
147 
153  virtual double Evaluate(double /* val */, int /* order */) {
154  return 0;
155  }
156 
158 
164  virtual double EvalGrad(double /* val */, int /* order */) {
165  return 0;
166  }
167 
169 
174  virtual double Weight(double /* val */) {
175  return 1;
176  }
177 
179 
186  static BasisFunction* Build(const Json::Value& json, const std::string& path, unsigned int nbins);
187 
189  virtual ~BasisFunction() {}
190  };
191 
193  class Chebyshev : public BasisFunction
194  {
195  private:
196  protected:
197  public:
199 
207  Chebyshev(unsigned int polyOrd, double boundLow, double boundUp, unsigned int nbins) :
208  BasisFunction(polyOrd, nbins, true, false, boundLow, boundUp)
209  {
210  }
211 
213 
218  double ChangeVariable(double x)
219  {
220  return (x-boundLow_)*2.0/(boundUp_ - boundLow_)-1.0;
221  }
222 
223  double Evaluate(double x, int n)
224  {
225  double xMod = ChangeVariable(x);
226  return n == 0 ? 1.0 :
227  n == 1 ? xMod :
228  2.0*xMod*Evaluate(x,n-1) - Evaluate(x,n-2);
229  }
230 
231  double EvalGrad(double x, int n)
232  {
233  double xMod = ChangeVariable(x);
234  return n == 0 ? 0.0 :
235  n == 1 ? 1.0 :
236  2.0*(Evaluate(x,n-1) + xMod * EvalGrad(x,n-1)) - EvalGrad(x,n-2);
237  }
238 
239  double Weight(double x)
240  {
241  double xMod = ChangeVariable(x);
242  return 1.0/sqrt(1.0-xMod*xMod);
243  }
244 
245  double GetNorm(int /* n */)
246  {
247  return 2.0/M_PI;
248  }
249 
252  static Chebyshev* Build(const Json::Value& json, const std::string& path, unsigned int nbins);
253 
254  };
255 
257  class Legendre : public BasisFunction
258  {
259  private:
260  protected:
261  public:
263 
269  Legendre(unsigned int polyOrd, unsigned int nbins) :
270  BasisFunction(polyOrd, nbins, true, false, -1.0, 1.0)
271  {
272  }
273 
274  double Evaluate(double x, int n)
275  {
276  return n == 0 ? 1.0 :
277  n == 1 ? x :
278  (2.0*n-1.0)/(double)n*x*Evaluate(x,n-1) - (n-1.0)/(double)n*Evaluate(x,n-2);
279  }
280 
281  double EvalGrad(double x, int n)
282  {
283  return n == 0 ? 0.0 :
284  n == 1 ? 1.0 :
285  (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);
286  }
287 
288  double GetNorm(int n)
289  {
290  return n + 0.5;
291  }
292 
295  static Legendre* Build(const Json::Value& json, const std::string& path, unsigned int nbins);
296  };
297 
299  class Fourier : public BasisFunction
300  {
301  private:
302  protected:
303  public:
305 
313  Fourier(unsigned int polyOrd, double boundLow, double boundUp, unsigned int nbins) :
314  BasisFunction(polyOrd, nbins, true, true, boundLow, boundUp)
315  {
316  }
317 
318  //For the Fourier series, I am choosing to split the coefficients in two
319  //The first odd coefficients are the sine series and the even are cosine
320  //However when evaluated, they will be treated as n, just stored differently
321  double Evaluate(double x, int n)
322  {
323  return n == 0 ? 0.5 :
324  n % 2 == 1 ? std::sin(2.0*floor(double(n)*0.5)*M_PI*x/(boundUp_-boundLow_)) :
325  std::cos(2.0*floor(double(n)*0.5)*M_PI*x/(boundUp_-boundLow_));
326  }
327 
328  double EvalGrad(double x, int n)
329  {
330  return n == 0 ? 0.0 :
331  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_))) :
332  (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_));
333  }
334 
335  double GetNorm(int /* n */)
336  {
337  //Assumes the period of the function is the range of the CV
338  return 2.0/(boundUp_-boundLow_);
339  }
340 
343  static Fourier* Build(const Json::Value& json, const std::string& path, unsigned int nbins);
344  };
345 
348  {
349  private:
350  std::vector<Map> coeff_;
351  std::vector<BasisFunction*> functions_;
352  std::vector<BasisLUT> lookup_;
353 
354  public:
356 
361  BasisEvaluator(const std::vector<BasisFunction*>& functions) :
362  functions_(functions)
363  {
364  CoeffInit();
365  BasisInit();
366  }
367 
370  void CoeffInit();
371  void BasisInit();
372 
374 
378  void UpdateBias(Grid<double> *bias, Grid<std::vector<double>> *grad);
379 
382 
388  double UpdateCoeff(const std::vector<double> &array, Grid<unsigned int> *hist);
389 
391 
394  std::vector<double> GetCoeff(void)
395  {
396  std::vector<double> coeffArray (coeff_.size(),0);
397  for (size_t i=0; i<coeff_.size(); i++)
398  {
399  coeffArray[i] = coeff_[i].value;
400  }
401  return coeffArray;
402  }
403 
405 
408  void SetCoeff(const std::vector<double>& coeff)
409  {
410  size_t ii = 0;
411  for(auto& val : coeff_)
412  {
413  val.value = coeff[ii];
414  ii++;
415  }
416  }
417 
418  ~BasisEvaluator() {}
419  };
420 }
Calculates the inner product of all the basis functions and the histogram.
Definition: Basis.h:348
void SetCoeff(const std::vector< double > &coeff)
Set the coefficient array in the event of a restart run.
Definition: Basis.h:408
std::vector< double > GetCoeff(void)
Gets the coefficient array.
Definition: Basis.h:394
BasisEvaluator(const std::vector< BasisFunction * > &functions)
Constructor.
Definition: Basis.h:361
std::vector< BasisLUT > lookup_
Lookup table for basis functions.
Definition: Basis.h:352
std::vector< Map > coeff_
Vector of basis function coefficients.
Definition: Basis.h:350
void BasisInit()
Creates lookup table for basis functions.
Definition: Basis.cpp:132
void UpdateBias(Grid< double > *bias, Grid< std::vector< double >> *grad)
Outputs the basis projection at a specific coordinate.
Definition: Basis.cpp:154
double UpdateCoeff(const std::vector< double > &array, Grid< unsigned int > *hist)
Definition: Basis.cpp:194
std::vector< BasisFunction * > functions_
Vector of basis functions.
Definition: Basis.h:351
void CoeffInit()
Initializes coefficient lookup vector.
Definition: Basis.cpp:100
Abstract class for all BasisFunction inheritance.
Definition: Basis.h:60
double GetUpper()
Gets the upper bound on the CV.
Definition: Basis.h:121
static BasisFunction * Build(const Json::Value &json, const std::string &path, unsigned int nbins)
Build BasisFunction from JSON value.
Definition: Basis.cpp:9
virtual double Evaluate(double, int)
Calculates the output of the basis function.
Definition: Basis.h:153
bool zeroOrder_
Flag for constant-order polynomials.
Definition: Basis.h:65
virtual ~BasisFunction()
Destructor.
Definition: Basis.h:189
double boundLow_
Lower bound on CV.
Definition: Basis.h:66
bool GetZeroOrder()
Gets the flag for constant-order polynomials.
Definition: Basis.h:109
double boundUp_
Upper bound on CV.
Definition: Basis.h:67
unsigned int GetBins()
Gets the number of bins for the discretization.
Definition: Basis.h:103
unsigned int nbins_
Number of bins.
Definition: Basis.h:63
virtual double Weight(double)
Calculates the weight of the basis function.
Definition: Basis.h:174
unsigned int GetOrder()
Gets the order of the current polynomial.
Definition: Basis.h:97
double GetRange()
Gets the magnitude of the range of bounds.
Definition: Basis.h:127
unsigned int polyOrd_
Order of the polynomial.
Definition: Basis.h:62
bool isFinite_
Flag for finite-range polynomials.
Definition: Basis.h:64
BasisFunction(unsigned int polyOrd, unsigned int nbins, bool isFinite, bool zeroOrder, double boundLow, double boundUp)
Constructor.
Definition: Basis.h:82
virtual double EvalGrad(double, int)
Calculates the gradient of the basis function.
Definition: Basis.h:164
virtual double GetNorm(int)
Gets the norm of the basis function.
Definition: Basis.h:142
double GetLower()
Gets the lower bound on the CV.
Definition: Basis.h:115
Defines the class of Chebyshev polynomials.
Definition: Basis.h:194
double GetNorm(int)
Gets the norm of the basis function.
Definition: Basis.h:245
double EvalGrad(double x, int n)
Calculates the gradient of the basis function.
Definition: Basis.h:231
Chebyshev(unsigned int polyOrd, double boundLow, double boundUp, unsigned int nbins)
Constructor.
Definition: Basis.h:207
double Weight(double x)
Calculates the weight of the basis function.
Definition: Basis.h:239
double Evaluate(double x, int n)
Calculates the output of the basis function.
Definition: Basis.h:223
double ChangeVariable(double x)
Transforms variable from absolute value to [-1,1] between boundaries.
Definition: Basis.h:218
static Chebyshev * Build(const Json::Value &json, const std::string &path, unsigned int nbins)
Build BasisFunction from JSON value.
Definition: Basis.cpp:22
Defines the class of Fourier polynomials.
Definition: Basis.h:300
Fourier(unsigned int polyOrd, double boundLow, double boundUp, unsigned int nbins)
Constructor.
Definition: Basis.h:313
double EvalGrad(double x, int n)
Calculates the gradient of the basis function.
Definition: Basis.h:328
double Evaluate(double x, int n)
Calculates the output of the basis function.
Definition: Basis.h:321
double GetNorm(int)
Gets the norm of the basis function.
Definition: Basis.h:335
static Fourier * Build(const Json::Value &json, const std::string &path, unsigned int nbins)
Build BasisFunction from JSON value.
Definition: Basis.cpp:49
Defines the class of Legendre polynomials.
Definition: Basis.h:258
double EvalGrad(double x, int n)
Calculates the gradient of the basis function.
Definition: Basis.h:281
static Legendre * Build(const Json::Value &json, const std::string &path, unsigned int nbins)
Build BasisFunction from JSON value.
Definition: Basis.cpp:75
double GetNorm(int n)
Gets the norm of the basis function.
Definition: Basis.h:288
Legendre(unsigned int polyOrd, unsigned int nbins)
Constructor.
Definition: Basis.h:269
double Evaluate(double x, int n)
Calculates the output of the basis function.
Definition: Basis.h:274
Look-up table for basis functions.
Definition: Basis.h:15
std::vector< double > values
The values of the basis sets.
Definition: Basis.h:17
BasisLUT(const std::vector< double > &values, const std::vector< double > &derivs)
Constructor.
Definition: Basis.h:27
std::vector< double > derivs
The values of the derivatives of the basis sets.
Definition: Basis.h:20
Map for histogram and coefficients.
Definition: Basis.h:40
Map(const std::vector< int > &map, double value)
Constructor.
Definition: Basis.h:52
double value
The coefficient value.
Definition: Basis.h:42
std::vector< int > map
The mapping in an array of integers.
Definition: Basis.h:45