Vlasiator ebf0dd394 on dev (v5.4.0 + 1054 commits)
Loading...
Searching...
No Matches
histogram.h
Go to the documentation of this file.
1#pragma once
2/*
3 * This file is part of Vlasiator.
4 * Copyright 2010-2016 Finnish Meteorological Institute
5 *
6 * For details of usage, see the COPYING file and read the "Rules of the Road"
7 * at http://www.physics.helsinki.fi/vlasiator/
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program 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 General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 */
23#include <mpi.h>
24#include <string.h>
25#include <stdio.h>
26#include <math.h>
27#include <Eigen/Dense>
28#define Vec3d Eigen::Vector3d
29#define Vec2d Eigen::Vector2d
30
31
32#define ERROR(format, ...) fprintf (stderr, "E: " format, ##__VA_ARGS__)
33
34// Histograms of 1D data
36{
37 public:
38 Histogram1D(size_t n) : num_bins(n) {
39 bins = new double[num_bins];
40 memset(bins, 0, sizeof(double)*num_bins);
41 }
43 delete[] bins;
44 }
45
46 /* Using MPI_Reduce, sum up all CPUs. */
47 void mpi_reduce() {
48 double* targetbins = new double[num_bins];
49 if(!targetbins) {
50 ERROR("allocation failed while mpi-reducing histogram.\n");
51 return;
52 }
53
54 MPI_Allreduce(bins,targetbins,num_bins,MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD);
55
56
57 /* Throw away the old bins. */
58 delete[] bins;
59 bins = targetbins;
60 }
61
62 void save(const char* filename) const;
63 void load(const char* filename);
64 virtual void saveAscii(const char* filename) const;
65 virtual void addValue(double value) = 0;
66
67 // Access bins
68 double operator()(int x) {
69 return bins[x];
70 }
71
72 protected:
73 size_t num_bins;
74 double* bins;
75
76};
77
79{
80 public:
81 LinearHistogram1D(size_t n, double _low, double _high) :
82 Histogram1D(n), low(_low), high(_high) {};
83
84 virtual void addValue(double value) {
85 value -= low;
86 value /= high - low;
87
88 int histogram_bin = value * num_bins;
89
90 if(histogram_bin < 0) {
91 histogram_bin = 0;
92 } else if (histogram_bin + 1 >= (ssize_t)num_bins) {
93 histogram_bin = num_bins - 1;
94 }
95 bins[histogram_bin]++;
96 }
97
98 virtual void saveAscii(const char* filename) const;
99
100 private:
101 /* Low and high bound of the histogram */
102 double low, high;
103
104};
105
107{
108 public:
109 LogHistogram1D(size_t n, double _low, double _high) :
110 Histogram1D(n), low(_low), high(_high) {};
111
112 virtual void addValue(double value) {
113 value /= low;
114 value = log(value);
115 value /= log(high / low);
116
117 int histogram_bin = value * num_bins;
118
119 if(histogram_bin < 0) {
120 histogram_bin = 0;
121 } else if (histogram_bin + 1 >= (ssize_t)num_bins) {
122 histogram_bin = num_bins - 1;
123 }
124 bins[histogram_bin]++;
125 }
126
127 private:
128 // low and high bound of the histogram
129 double low, high;
130};
131
132
133// Histograms of 2D data
135{
136 public:
137 Histogram2D(size_t n[2]) {
138 num_bins[0] = n[0];
139 num_bins[1] = n[1];
140
141 bins = new double[num_bins[0] * num_bins[1]];
142 memset(bins, 0, sizeof(double) * num_bins[0] * num_bins[1]);
143 }
145 delete[] bins;
146 }
147
148 // Using MPI_Reduce, sum up all CPUs.
149 void mpi_reduce() {
150 double* targetbins = new double[num_bins[0] * num_bins[1]];
151 if(!targetbins) {
152 ERROR("allocation failed while mpi-reducing histogram.\n");
153 return;
154 }
155
156 MPI_Allreduce(bins,targetbins, num_bins[0] * num_bins[1], MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
157
158 /* Throw away the old bins. */
159 delete[] bins;
160 bins = targetbins;
161 }
162
163 void save(const char* filename) const;
164 void load(const char* filename);
165 virtual void addValue(Vec2d value, double weight=1.) = 0;
166
167 // Access bins
168 double operator()(int x, int y) {
169 return bins[x + num_bins[0] * y];
170 }
171
172 protected:
173 size_t num_bins[2];
174 double* bins;
175};
176
178{
179
180 public:
181 LinearHistogram2D(size_t n[2], Vec2d _low, Vec2d _high) :
182 Histogram2D(n),
183 low(_low), high(_high) {};
184 LinearHistogram2D(size_t nx, size_t ny, Vec2d _low, Vec2d _high) :
185 Histogram2D(&nx),
186 low(_low), high(_high) {};
187
188 virtual void addValue(Vec2d value, double weight=1.) {
189 value -= low;
190 value = value.cwiseQuotient(high - low);
191
192 int histogram_bin[2];
193 histogram_bin[0] = value[0] * num_bins[0];
194 histogram_bin[1] = value[1] * num_bins[1];
195
196 for(int i = 0; i < 2; i++) {
197 if(histogram_bin[i] < 0) {
198 histogram_bin[i] = 0;
199 } else if (histogram_bin[i] + 1 >= (ssize_t)num_bins[i]) {
200 histogram_bin[i] = num_bins[i] - 1;
201 }
202 }
203 bins[histogram_bin[0] + num_bins[0] * histogram_bin[1]] += weight;
204 }
205
206 void addValueLinearInterpolate(Vec2d value, double weight=1.) {
207
208 value -= low;
209 value = value.cwiseQuotient(high - low);
210
211 double v[2];
212 v[0] = value[0] * num_bins[0];
213 v[1] = value[1] * num_bins[1];
214
215 // Interpolation parameter
216 double a[2];
217 a[0] = v[0] - floor(v[0]);
218 a[1] = v[1] - floor(v[1]);
219
220 // Ensure we are within bounds.
221 if(v[0] < 0) {
222 v[0] = 0;
223 a[0] = 0;
224 }
225 if(v[1] < 0) {
226 v[1] = 0;
227 a[1] = 0;
228 }
229
230 if(v[0] >= num_bins[0]-1) {
231 v[0] = num_bins[0]-2;
232 a[0] = 1;
233 }
234 if(v[1] >= num_bins[1]-1) {
235 v[1] = num_bins[1]-2;
236 a[1] = 1;
237 }
238
239 // Assign.
240 int histogram_bin[2];
241 histogram_bin[0] = floor(v[0]);
242 histogram_bin[1] = floor(v[1]);
243
244 bins[histogram_bin[0] + num_bins[0] * histogram_bin[1]] += weight * (1. - a[0]) * (1. - a[1]);
245 bins[histogram_bin[0] + num_bins[0] * (histogram_bin[1] + 1)] += weight * (1. - a[0]) * a[1];
246 bins[histogram_bin[0] + 1 + num_bins[0] * histogram_bin[1]] += weight * a[0] * (1. - a[1]);
247 bins[histogram_bin[0] + 1 + num_bins[0] * (histogram_bin[1] + 1)] += weight * a[0] * a[1];
248 }
249
250 // Bin-wise arithmetic on histograms
251 void operator += (LinearHistogram2D& other);
252 void operator -= (LinearHistogram2D& other);
253
254 // Write and read a ASCII metadata file containing BOV data.
255 void writeBovAscii(const char* filename, int index, const char* datafilename);
256
257 private:
258 // Low and high bound of the histogram
260
261};
262
263// Histogram with one linear and one logarithmic axis
265{
266 public:
267 LinLogHistogram2D(size_t n[2], Vec2d _low, Vec2d _high) :
268 Histogram2D(n),
269 low(_low), high(_high) {};
270
271 virtual void addValue(Vec2d value, double weight=1.) {
272 double v[2];
273 v[0] -= low[0];
274 v[0] /= high[0] - low[0];
275 v[1] /= low[1];
276 v[1] = log(v[1]);
277 v[1] /= log(high[1] / low[1]);
278
279 int histogram_bin[2];
280 histogram_bin[0] = v[0] * num_bins[0];
281 histogram_bin[1] = v[1] * num_bins[1];
282
283 for(int i = 0; i < 2; i++) {
284 if(histogram_bin[i] < 0) {
285 histogram_bin[i] = 0;
286 } else if (histogram_bin[i] + 1 >= (ssize_t)num_bins[i]) {
287 histogram_bin[i] = num_bins[i] - 1;
288 }
289 }
290 bins[histogram_bin[0] + num_bins[0] * histogram_bin[1]] += weight;
291 }
292
293 void addValueLinearInterpolate(Vec2d value, double weight=1.) {
294
295 double v[2];
296 v[0] = value[0] - low[0];
297 v[0] /= high[0] - low[0];
298 v[1] = value[1] / low[1];
299 v[1] = log(v[1]) / log(high[1] / low[1]);
300
301 v[0] *= num_bins[0];
302 v[1] *= num_bins[1];
303
304 // Interpolation parameter
305 double a[2];
306 a[0] = value[0] - floor(value[0]);
307 a[1] = value[1] - floor(value[1]);
308
309 // Ensure we are within bounds.
310 if(v[0] < 0) {
311 v[0] = 0;
312 a[0] = 0;
313 }
314 if(v[1] < 0) {
315 v[1] = 0;
316 a[1] = 0;
317 }
318
319 if(v[0] >= num_bins[0] - 1) {
320 v[0] = num_bins[0] - 2;
321 a[0] = 1;
322 }
323 if(v[1] >= num_bins[1] - 1) {
324 v[1] = num_bins[1] - 2;
325 a[1] = 1;
326 }
327
328 // Assign.
329 int histogram_bin[2];
330 histogram_bin[0] = floor(v[0]);
331 histogram_bin[1] = floor(v[1]);
332
333 bins[histogram_bin[0] + num_bins[0] * histogram_bin[1]] += weight * (1. - a[0]) * (1. - a[1]);
334 bins[histogram_bin[0] + num_bins[0] * (histogram_bin[1] + 1)] += weight * (1. - a[0]) * a[1];
335 bins[histogram_bin[0] + 1 + num_bins[0] * histogram_bin[1]] += weight * a[0] * (1. - a[1]);
336 bins[histogram_bin[0] + 1 + num_bins[0] * (histogram_bin[1] + 1)] += weight * a[0] * a[1];
337 }
338
339 private:
340 // Low and high bound of the histogram
342};
343
345{
346 private:
347 // Low and high bound of the histogram
349
350 LogHistogram2D(size_t n[2], Vec2d _low, Vec2d _high) :
351 Histogram2D(n),
352 low(_low), high(_high) {};
353
354 virtual void addValue(Vec2d value, double weight=1.) {
355 value = value.cwiseQuotient(low);
356
357 double v[2];
358 v[0] = log(value[0]) / log(high[0] / low[0]);
359 v[1] = log(value[1]) / log(high[1] / low[1]);
360
361 int histogram_bin[2];
362 histogram_bin[0] = v[0] * num_bins[0];
363 histogram_bin[1] = v[1] * num_bins[1];
364
365 for(int i = 0; i < 2; i++) {
366 if(histogram_bin[i] < 0) {
367 histogram_bin[i] = 0;
368 } else if (histogram_bin[i] + 1 >= (ssize_t)num_bins[i]) {
369 histogram_bin[i] = num_bins[i] - 1;
370 }
371 }
372 bins[histogram_bin[0] + num_bins[0] * histogram_bin[1]] += weight;
373 }
374
375 /* Bin-wise arithmetic on histograms */
376 void operator += (LogHistogram2D& other);
377 void operator -= (LogHistogram2D& other);
378};
379
380// Histograms of 3D data
382{
383 public:
384 Histogram3D(size_t n[3]) {
385 num_bins[0] = n[0];
386 num_bins[1] = n[1];
387 num_bins[2] = n[2];
388
389 bins = new float[num_bins[0] * num_bins[1] * num_bins[2]];
390 memset(bins, 0, sizeof(float) * num_bins[0] * num_bins[1] * num_bins[2]);
391 }
393 delete[] bins;
394 }
395
396 // Using MPI_Reduce, sum up all CPUs.
397 void mpi_reduce() {
398 float* targetbins = new float[num_bins[0] * num_bins[1] * num_bins[2]];
399 if(!targetbins) {
400 ERROR("allocation failed while mpi-reducing histogram.\n");
401 return;
402 }
403
404 MPI_Allreduce(bins, targetbins, num_bins[0] * num_bins[1] * num_bins[2], MPI_FLOAT, MPI_SUM, MPI_COMM_WORLD);
405
406 /* Throw away the old bins. */
407 delete[] bins;
408 bins = targetbins;
409 }
410
411 void save(const char* filename) const;
412 void load(const char* filename);
413 virtual void addValue(Vec3d value) = 0;
414
415 // Access bins
416 double operator()(int x, int y, int z) {
417 return bins[x + num_bins[0] * y + num_bins[0] * num_bins[1] * z];
418 }
419
420 protected:
421 size_t num_bins[3];
422 float* bins;
423};
424
426{
427 public:
428 LinearHistogram3D(size_t n[3], Vec3d _low, Vec3d _high) :
429 Histogram3D(n),
430 low(_low), high(_high) {};
431
432 virtual void addValue(Vec3d value) {
433 value -= low;
434 value = value.cwiseQuotient(high - low);
435
436 int histogram_bin[3];
437 histogram_bin[0] = value[0] * num_bins[0];
438 histogram_bin[1] = value[1] * num_bins[1];
439 histogram_bin[2] = value[2] * num_bins[2];
440
441 for(int i = 0; i < 3; i++) {
442 if(histogram_bin[i] < 0) {
443 histogram_bin[i] = 0;
444 } else if (histogram_bin[i] + 1 >= (ssize_t)num_bins[i]) {
445 histogram_bin[i] = num_bins[i] - 1;
446 }
447 }
448 bins[histogram_bin[0] + num_bins[0] * histogram_bin[1] + num_bins[0] * num_bins[1] * histogram_bin[2]]++;
449 }
450
452 Vec3d nx(num_bins[0], num_bins[1], num_bins[2]);
453 return low + cell.cwiseQuotient(nx).cwiseProduct(high - low);
454 }
455
456 // Bin-wise arithmetic on histograms
459
460 // Write and read a ASCII metadata file containing BOV data.
461 void writeBovAscii(const char* filename, int index, const char* datafilename);
462 void readBov(const char* filename);
463
464 private:
465 // Low and high bound of the histogram
467
468};
for i
Definition Dispersion.m:24
Histogram1D(size_t n)
Definition histogram.h:38
double * bins
Definition histogram.h:74
virtual void saveAscii(const char *filename) const
Definition histogram.cpp:50
void save(const char *filename) const
Definition histogram.cpp:30
void load(const char *filename)
Definition histogram.cpp:84
virtual void addValue(double value)=0
void mpi_reduce()
Definition histogram.h:47
size_t num_bins
Definition histogram.h:73
double operator()(int x)
Definition histogram.h:68
double operator()(int x, int y)
Definition histogram.h:168
size_t num_bins[2]
Definition histogram.h:173
void load(const char *filename)
void save(const char *filename) const
virtual void addValue(Vec2d value, double weight=1.)=0
void mpi_reduce()
Definition histogram.h:149
double * bins
Definition histogram.h:174
Histogram2D(size_t n[2])
Definition histogram.h:137
double operator()(int x, int y, int z)
Definition histogram.h:416
size_t num_bins[3]
Definition histogram.h:421
Histogram3D(size_t n[3])
Definition histogram.h:384
void mpi_reduce()
Definition histogram.h:397
void load(const char *filename)
virtual void addValue(Vec3d value)=0
float * bins
Definition histogram.h:422
void save(const char *filename) const
void addValueLinearInterpolate(Vec2d value, double weight=1.)
Definition histogram.h:293
LinLogHistogram2D(size_t n[2], Vec2d _low, Vec2d _high)
Definition histogram.h:267
virtual void addValue(Vec2d value, double weight=1.)
Definition histogram.h:271
virtual void addValue(double value)
Definition histogram.h:84
virtual void saveAscii(const char *filename) const
Definition histogram.cpp:67
LinearHistogram1D(size_t n, double _low, double _high)
Definition histogram.h:81
LinearHistogram2D(size_t n[2], Vec2d _low, Vec2d _high)
Definition histogram.h:181
void addValueLinearInterpolate(Vec2d value, double weight=1.)
Definition histogram.h:206
void operator+=(LinearHistogram2D &other)
virtual void addValue(Vec2d value, double weight=1.)
Definition histogram.h:188
void operator-=(LinearHistogram2D &other)
void writeBovAscii(const char *filename, int index, const char *datafilename)
LinearHistogram2D(size_t nx, size_t ny, Vec2d _low, Vec2d _high)
Definition histogram.h:184
void operator-=(LinearHistogram3D &other)
LinearHistogram3D(size_t n[3], Vec3d _low, Vec3d _high)
Definition histogram.h:428
void readBov(const char *filename)
virtual void addValue(Vec3d value)
Definition histogram.h:432
void writeBovAscii(const char *filename, int index, const char *datafilename)
void operator+=(LinearHistogram3D &other)
Vec3d coords_for_cell(Vec3d cell)
Definition histogram.h:451
LogHistogram1D(size_t n, double _low, double _high)
Definition histogram.h:109
virtual void addValue(double value)
Definition histogram.h:112
void operator-=(LogHistogram2D &other)
virtual void addValue(Vec2d value, double weight=1.)
Definition histogram.h:354
void operator+=(LogHistogram2D &other)
LogHistogram2D(size_t n[2], Vec2d _low, Vec2d _high)
Definition histogram.h:350
#define Vec3d
Definition histogram.h:28
#define ERROR(format,...)
Definition histogram.h:32
#define Vec2d
Definition histogram.h:29
#define index(i, j, k)
static ARCH_HOSTDEV VecSimple< T > floor(VecSimple< T > const &a)