-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathliouville.h
243 lines (192 loc) · 6.27 KB
/
liouville.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
#ifndef LIOUVILLE_H
#define LIOUVILLE_H
#include <vector>
#include <string>
#include <boost/random/mersenne_twister.hpp>
#include "utilities.h"
#include "Array.h"
#include "fftw++.h"
#define PI 3.141592653589
#define TWOBYPI 0.636619772367581
class RNGenerator {
public:
RNGenerator();
double RandomNormal();
double RandomReal(double min, double max);
double RandomExponential();
Complex RandomComplex();
void Seed(unsigned int seed);
private:
boost::mt19937 rng_;
};
class GaussianField {
public:
GaussianField(int width);
void GenerateRandom(RNGenerator & rng);
double getField(int x, int y) const;
int getWidth() const;
void PrecomputeRandom(RNGenerator & rng);
void SetMaxMomentum(double momentum);
void GetFieldList(std::ostream & stream) const;
void OutputFieldHistogram(std::ostream & stream,int i);
void DoFieldMeasurement(int i);
private:
Array::array2<Complex> field_;
int width_;
bool max_momentum_changed_;
bool usereal_;
void FillSpectrum();
std::vector<std::vector<double> > spectrum_;
std::vector<std::vector<double> > measure_;
std::vector<std::vector<double> > sqrtmeasure_;
std::vector<double> cumul_;
std::vector<int> field_measurements_;
std::vector<std::vector<int> > field_histogram_;
double min_field_, max_field_;
int field_bins_;
bool use_precomputed_random_;
std::vector<std::vector<Complex> > random_normal_;
bool use_max_momentum_;
double max_momentum_;
fftwpp::fft2d fourier_;
};
class VolumeMeasure {
public:
VolumeMeasure(int width);
void setFromGaussianField(const GaussianField & field, double gamma);
void NormalizeToUnitVolume();
enum AveragingMethod {
BOX_SUBDIVISION,
BOX_AVERAGING,
DISK_AVERAGING,
DISK_DIFFUSION
};
void performAveraging( VolumeMeasure & target, AveragingMethod method, double delta );
std::pair<int,int> RandomInMeasure(RNGenerator & rng);
double getMeasure(int x, int y) const;
double getSqrtMeasure(int x, int y) const;
void setMeasure(int x, int y, double measure);
void addMeasure(int x, int y, double measure);
void updateSqrtMeasure();
int getWidth() const;
double getTotalVolume() const;
void Flip();
void setToZero();
private:
int width_;
std::vector<std::vector<double> > measure_;
std::vector<std::vector<double> > sqrtmeasure_;
bool cumul_uptodate_;
std::vector<double> cumul_;
void UpdateCumulativeMeasure();
void UpdateSummedMeasure();
double GetSummedMeasure(int x0, int y0) const;
double GetSummedMeasure(int x0, int y0, int x1, int y1) const;
std::vector<std::vector<double> > summed_measure_;
bool summed_measure_uptodate_;
std::vector<std::pair<int,int> > spiral_;
void PrepareSpiral();
void doBoxSubdivision(VolumeMeasure & target, double delta);
void doBoxSubdivision(VolumeMeasure & target, int x0, int x1, int y0, int y1, double delta);
void doBoxAveraging(VolumeMeasure & target, double delta);
void doDiskAveraging(VolumeMeasure & target, double delta);
void doDiskDiffusion(VolumeMeasure & target, double delta);
};
struct Node
{
double distance;
int x[2];
short omega[2];
bool operator<(const Node & node) const { return distance > node.distance; }
};
typedef boost::array<int,2> Vertex;
struct Edge {
boost::array<Vertex,2> x;
bool belongsToLeftFace;
};
class ShortestCycle {
public:
enum DISTANCE_METHOD {
DIJKSTRA,
EIKONAL
};
ShortestCycle(VolumeMeasure * const measure, DISTANCE_METHOD method=EIKONAL,double maxLength = 1.5);
double FindLength();
void RetrieveCycle(std::vector<Vertex> & path);
void SetMethod(DISTANCE_METHOD method);
std::string Output();
private:
double FindLengthDijkstra();
double FindLengthEikonal();
double FindLengthDijkstra(int startX, int startY);
double FindLengthEikonal(int startX, int startY);
void HorizontalEikonalDistance(int startX);
std::pair<int,int> Neighbour(const std::pair<int,int> & x, int dir);
std::pair<short,short> NeighbourOmega( std::pair<int,int> x1, std::pair<int,int> x2, std::pair<short,short> omega ) const;
bool CrossesBoundary(int boundaryX, int n1x, int n2x) const;
VolumeMeasure * const measure_;
std::vector<std::vector<double> > distance_;
int width_;
DISTANCE_METHOD method_;
std::vector<int> histogram_;
double average_length_;
double min_length_, max_length_;
int bins_;
int measurements_;
Vertex cycle_base_point_;
boost::array<Vertex,2> cycle_tips_;
boost::array<Edge,2 > cycle_edges_;
};
class EikonalGeodesicRetriever {
public:
EikonalGeodesicRetriever(std::vector<std::vector<double> > & distance);
void FindGeodesicFromTips(std::vector<Vertex> & path, const boost::array<Vertex,2> & tips);
void FindGeodesic(std::vector<Vertex> & path);
void FindGeodesic(std::vector<Vertex> & path, Edge edge);
private:
std::vector<std::vector<double> > & distance_;
int width_;
void nextEdge(Edge & edge,double & lambda) const;
Edge Adjacent(const Edge & edge) const;
Edge Next(const Edge & edge) const;
Edge Previous(const Edge & edge) const;
Edge Reverse(const Edge & edge) const;
double DistanceChange(const Edge & edge) const;
};
class TwoPointFunction {
public:
enum DISTANCE_METHOD {
DIJKSTRA,
EIKONAL
};
TwoPointFunction(VolumeMeasure * const measure, DISTANCE_METHOD method, double maxdist = 1.3, int bins = 1000);
void Measure(RNGenerator & rng, int n=1);
double getDistance(int x, int y) const;
std::string Output();
void DijkstraDistance(int startX, int startY, bool measurement=true);
void EikonalDistance(int startX, int startY, bool measurement=true);
void SetMethod(DISTANCE_METHOD method);
void SaveDistance(std::string filename) const;
private:
VolumeMeasure * const measure_;
std::pair<int,int> Neighbour(const std::pair<int,int> & x, int dir);
std::vector<std::vector<double> > distance_;
int width_;
DISTANCE_METHOD method_;
double max_dist_;
int bins_;
std::vector<double> dist_histogram_;
int measurements_;
};
class CorrelationFunction {
public:
CorrelationFunction(VolumeMeasure * const measure);
void MeasureCorrelation(RNGenerator & rng, int n=1);
std::string Output();
private:
std::vector<double> correlation_;
int correlation_measurements_;
VolumeMeasure * const measure_;
int width_;
};
#endif