-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhist.c
160 lines (127 loc) · 3.28 KB
/
hist.c
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
#include "hist.h"
#include "fp.h"
#include "size.h"
#include <gsl/gsl_math.h>
#include <math.h>
#include <stdint.h>
#include <stdlib.h>
struct hist {
size_t* m;
size_t* tmp;
size_t ndim;
size_t nlin;
size_t ncub;
double a;
double b;
size_t nsum;
};
void hist_free(struct hist* const hist) {
if (hist != NULL) {
free(hist->tmp);
free(hist->m);
}
free(hist);
}
void hist_forget(struct hist* const hist) {
for (size_t i = 0; i < hist->ncub; ++i)
hist->m[i] = 0;
hist->nsum = 0;
}
struct hist* hist_alloc(size_t const ndim, size_t const nlin,
double const a, double const b) {
bool p = true;
struct hist* const hist = malloc(sizeof *hist);
if (hist == NULL)
p = false;
else {
hist->ndim = ndim;
hist->nlin = nlin;
hist->ncub = size_pow(nlin, ndim);
hist->a = a;
hist->b = b;
hist->m = malloc(hist->ncub * sizeof *hist->m);
if (hist->m == NULL)
p = false;
else
hist_forget(hist);
hist->tmp = malloc(ndim * sizeof *hist->tmp);
if (hist->tmp == NULL)
p = false;
}
if (p)
return hist;
else {
hist_free(hist);
return NULL;
}
}
size_t hist_bin(struct hist const* const hist, double const* const x) {
for (size_t i = 0; i < hist->ndim; ++i)
if (x[i] >= hist->a && x[i] < hist->b)
hist->tmp[i] = size_uclamp((size_t) floor(fp_lerp(x[i],
hist->a, hist->b, 0.0, (double) hist->nlin)), hist->nlin);
else
return SIZE_MAX;
return size_unhc(hist->nlin, hist->tmp, hist->ndim);
}
__attribute__ ((__nonnull__))
static void unbin(struct hist const* const hist, double* const x,
size_t const j, double const h) {
size_hc(j, hist->nlin, hist->tmp, hist->ndim);
for (size_t i = 0; i < hist->ndim; ++i)
x[i] = fp_lerp((double) hist->tmp[i] + h,
0.0, (double) hist->nlin, hist->a, hist->b);
}
void hist_unbin(struct hist const* const hist, double* const x,
size_t const j) {
unbin(hist, x, j, 0.5);
}
void hist_funbin(struct hist const* const hist, double* const x,
size_t const j) {
unbin(hist, x, j, 0.0);
}
void hist_cunbin(struct hist const* const hist, double* const x,
size_t const j) {
unbin(hist, x, j, 1.0);
}
bool hist_accum(struct hist* const hist, double const* const x) {
size_t const i = hist_bin(hist, x);
if (i == SIZE_MAX)
return false;
else {
++hist->m[i];
++hist->nsum;
return true;
}
}
size_t hist_ndim(struct hist const* const hist) {
return hist->ndim;
}
size_t hist_nsubdiv(struct hist const* const hist) {
return hist->nlin;
}
size_t hist_nbin(struct hist const* const hist) {
return hist->ncub;
}
double hist_min(struct hist const* const hist) {
return hist->a;
}
double hist_max(struct hist const* const hist) {
return hist->b;
}
double hist_length(struct hist const* const hist) {
return hist->b - hist->a;
}
double hist_volume(struct hist const* const hist) {
return gsl_pow_int(hist->b - hist->a, (int) hist->ndim);
}
size_t hist_hits(struct hist const* const hist, size_t const i) {
return hist->m[i];
}
size_t hist_sumhits(struct hist const* const hist) {
return hist->nsum;
}
double hist_normhits(struct hist const* const hist, size_t const i) {
return hist->nsum == 0 ? 0.0 : (double) hist->m[i] /
(hist_volume(hist) * ((double) hist->nsum / (double) hist->ncub));
}