forked from plumed/plumed2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Grid.h
289 lines (246 loc) · 11.9 KB
/
Grid.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Copyright (c) 2011-2020 The plumed team
(see the PEOPLE file at the root of the distribution for a list of names)
See http://www.plumed.org for more information.
This file is part of plumed, version 2.
plumed is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
plumed is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with plumed. If not, see <http://www.gnu.org/licenses/>.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
#ifndef __PLUMED_tools_Grid_h
#define __PLUMED_tools_Grid_h
#include <vector>
#include <string>
#include <map>
#include <cmath>
#include <memory>
namespace PLMD {
// simple function to enable various weighting
class WeightBase {
public:
virtual double projectInnerLoop(double &input, double &v)=0;
virtual double projectOuterLoop(double &v)=0;
virtual ~WeightBase() {}
};
class BiasWeight:public WeightBase {
public:
double beta,invbeta;
explicit BiasWeight(double v) {beta=v; invbeta=1./beta;}
double projectInnerLoop(double &input, double &v) {return input+exp(beta*v);}
double projectOuterLoop(double &v) {return -invbeta*std::log(v);}
};
class ProbWeight:public WeightBase {
public:
double beta,invbeta;
explicit ProbWeight(double v) {beta=v; invbeta=1./beta;}
double projectInnerLoop(double &input, double &v) {return input+v;}
double projectOuterLoop(double &v) {return -invbeta*std::log(v);}
};
class Value;
class IFile;
class OFile;
class KernelFunctions;
class Communicator;
/// \ingroup TOOLBOX
class Grid
{
public:
// we use a size_t here
// should be 8 bytes on all 64-bit machines
// and more portable than "unsigned long long"
typedef size_t index_t;
// to restore old implementation (unsigned) use the following instead:
// typedef unsigned index_t;
/// Maximum dimension (exaggerated value).
/// Can be used to replace local std::vectors with std::arrays (allocated on stack).
static constexpr size_t maxdim=64;
private:
double contour_location;
std::vector<double> grid_;
std::vector< std::vector<double> > der_;
protected:
std::string funcname;
std::vector<std::string> argnames;
std::vector<std::string> str_min_, str_max_;
std::vector<double> min_,max_,dx_;
std::vector<unsigned> nbin_;
std::vector<bool> pbc_;
index_t maxsize_;
unsigned dimension_;
bool dospline_, usederiv_;
std::string fmt_; // format for output
/// get "neighbors" for spline
void getSplineNeighbors(const std::vector<unsigned> & indices, std::vector<index_t>& neigh, unsigned& nneigh )const;
// std::vector<index_t> getSplineNeighbors(const std::vector<unsigned> & indices)const;
public:
/// clear grid
virtual void clear();
/// this constructor here is Value-aware
Grid(const std::string& funcl, const std::vector<Value*> & args, const std::vector<std::string> & gmin,
const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline,
bool usederiv, bool doclear=true);
/// this constructor here is not Value-aware
Grid(const std::string& funcl, const std::vector<std::string> &names, const std::vector<std::string> & gmin,
const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline,
bool usederiv, bool doclear, const std::vector<bool> &isperiodic, const std::vector<std::string> &pmin,
const std::vector<std::string> &pmax );
/// this is the real initializator
void Init(const std::string & funcl, const std::vector<std::string> &names, const std::vector<std::string> & gmin,
const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline, bool usederiv,
bool doclear, const std::vector<bool> &isperiodic, const std::vector<std::string> &pmin, const std::vector<std::string> &pmax);
/// get lower boundary
std::vector<std::string> getMin() const;
/// get upper boundary
std::vector<std::string> getMax() const;
/// get bin size
std::vector<double> getDx() const;
double getDx(index_t j) const ;
/// get bin volume
double getBinVolume() const;
/// get number of bins
std::vector<unsigned> getNbin() const;
/// get if periodic
std::vector<bool> getIsPeriodic() const;
/// get grid dimension
unsigned getDimension() const;
/// get argument names of this grid
std::vector<std::string> getArgNames() const;
/// get if the grid has derivatives
bool hasDerivatives() const {return usederiv_;}
/// methods to handle grid indices
void getIndices(index_t index, std::vector<unsigned>& rindex) const;
void getIndices(const std::vector<double> & x, std::vector<unsigned>& rindex) const;
std::vector<unsigned> getIndices(index_t index) const;
std::vector<unsigned> getIndices(const std::vector<double> & x) const;
index_t getIndex(const std::vector<unsigned> & indices) const;
index_t getIndex(const std::vector<double> & x) const;
std::vector<double> getPoint(index_t index) const;
std::vector<double> getPoint(const std::vector<unsigned> & indices) const;
std::vector<double> getPoint(const std::vector<double> & x) const;
/// faster versions relying on preallocated vectors
void getPoint(index_t index,std::vector<double> & point) const;
void getPoint(const std::vector<unsigned> & indices,std::vector<double> & point) const;
void getPoint(const std::vector<double> & x,std::vector<double> & point) const;
/// get neighbors
std::vector<index_t> getNeighbors(index_t index,const std::vector<unsigned> & neigh) const;
std::vector<index_t> getNeighbors(const std::vector<unsigned> & indices,const std::vector<unsigned> & neigh) const;
std::vector<index_t> getNeighbors(const std::vector<double> & x,const std::vector<unsigned> & neigh) const;
/// get nearest neighbors (those separated by exactly one lattice unit)
std::vector<index_t> getNearestNeighbors(const index_t index) const;
std::vector<index_t> getNearestNeighbors(const std::vector<unsigned> &indices) const;
/// write header for grid file
void writeHeader(OFile& file);
/// read grid from file
static std::unique_ptr<Grid> create(const std::string&,const std::vector<Value*>&,IFile&,bool,bool,bool);
/// read grid from file and check boundaries are what is expected from input
static std::unique_ptr<Grid> create(const std::string&,const std::vector<Value*>&, IFile&,
const std::vector<std::string>&,const std::vector<std::string>&,
const std::vector<unsigned>&,bool,bool,bool);
/// get grid size
virtual index_t getSize() const;
/// get grid value
virtual double getValue(index_t index) const;
virtual double getValue(const std::vector<unsigned> & indices) const;
virtual double getValue(const std::vector<double> & x) const;
/// get minimum value
virtual double getMinValue() const;
/// get maximum value
virtual double getMaxValue() const;
/// get grid value and derivatives
virtual double getValueAndDerivatives(index_t index, std::vector<double>& der) const ;
virtual double getValueAndDerivatives(const std::vector<unsigned> & indices, std::vector<double>& der) const;
virtual double getValueAndDerivatives(const std::vector<double> & x, std::vector<double>& der) const;
/// Get the difference from the contour
double getDifferenceFromContour(const std::vector<double> & x, std::vector<double>& der) const ;
/// Find a set of points on a contour in the function
void findSetOfPointsOnContour(const double& target, const std::vector<bool>& nosearch, unsigned& npoints, std::vector<std::vector<double> >& points );
/// set grid value
virtual void setValue(index_t index, double value);
virtual void setValue(const std::vector<unsigned> & indices, double value);
/// set grid value and derivatives
virtual void setValueAndDerivatives(index_t index, double value, std::vector<double>& der);
virtual void setValueAndDerivatives(const std::vector<unsigned> & indices, double value, std::vector<double>& der);
/// add to grid value
virtual void addValue(index_t index, double value);
virtual void addValue(const std::vector<unsigned> & indices, double value);
/// add to grid value and derivatives
virtual void addValueAndDerivatives(index_t index, double value, std::vector<double>& der);
virtual void addValueAndDerivatives(const std::vector<unsigned> & indices, double value, std::vector<double>& der);
/// Scale all grid values and derivatives by a constant factor
virtual void scaleAllValuesAndDerivatives( const double& scalef );
/// Takes the scalef times the logarithm of all grid values and derivatives
virtual void logAllValuesAndDerivatives( const double& scalef );
/// Set the minimum value of the grid to zero and translates accordingly
virtual void setMinToZero();
/// apply function: takes pointer to function that accepts a double and apply
virtual void applyFunctionAllValuesAndDerivatives( double (*func)(double val), double (*funcder)(double valder) );
/// add a kernel function to the grid
void addKernel( const KernelFunctions& kernel );
/// dump grid on file
virtual void writeToFile(OFile&);
/// dump grid to gaussian cube file
void writeCubeFile(OFile&, const double& lunit);
virtual ~Grid() {}
/// project a high dimensional grid onto a low dimensional one: this should be changed at some time
/// to enable many types of weighting
Grid project( const std::vector<std::string> & proj, WeightBase *ptr2obj );
void projectOnLowDimension(double &val, std::vector<int> &varHigh, WeightBase* ptr2obj );
/// set output format
void setOutputFmt(const std::string & ss) {fmt_=ss;}
/// reset output format to the default %14.9f format
void resetToDefaultOutputFmt() {fmt_="%14.9f";}
/// Integrate the function calculated on the grid
double integrate( std::vector<unsigned>& npoints );
///
void mpiSumValuesAndDerivatives( Communicator& comm );
/// Find the maximum over paths of the minimum value of the gridded function along the paths
/// for all paths of neighboring grid lattice points from a source point to a sink point.
virtual double findMaximalPathMinimum(const std::vector<double> &source, const std::vector<double> &sink);
};
class SparseGrid : public Grid
{
std::map<index_t,double> map_;
std::map< index_t,std::vector<double> > der_;
protected:
void clear();
public:
SparseGrid(const std::string& funcl, const std::vector<Value*> & args, const std::vector<std::string> & gmin,
const std::vector<std::string> & gmax,
const std::vector<unsigned> & nbin, bool dospline, bool usederiv):
Grid(funcl,args,gmin,gmax,nbin,dospline,usederiv,false) {}
index_t getSize() const;
index_t getMaxSize() const;
/// this is to access to Grid:: version of these methods (allowing overloading of virtual methods)
using Grid::getValue;
using Grid::getValueAndDerivatives;
using Grid::setValue;
using Grid::setValueAndDerivatives;
using Grid::addValue;
using Grid::addValueAndDerivatives;
/// get grid value
double getValue(index_t index) const;
/// get grid value and derivatives
double getValueAndDerivatives(index_t index, std::vector<double>& der) const;
/// set grid value
void setValue(index_t index, double value);
/// set grid value and derivatives
void setValueAndDerivatives(index_t index, double value, std::vector<double>& der);
/// add to grid value
void addValue(index_t index, double value);
/// add to grid value and derivatives
void addValueAndDerivatives(index_t index, double value, std::vector<double>& der);
/// dump grid on file
void writeToFile(OFile&);
virtual ~SparseGrid() {}
virtual double getMaxValue() const;
virtual double getMinValue() const;
};
}
#endif