LMMC
Lamina Mathematic core
Toggle main menu visibility
载入中...
搜索中...
未找到
statistics_selection.c
浏览该文件的文档.
1
#include <float.h>
2
#include <math.h>
3
#include <
stdlib.h
>
4
5
#include "
memory_bridge.h
"
6
#include "
lmmc/config.h
"
7
#include "
lmmc/numeric.h
"
8
#include "
lmmc/stats.h
"
9
10
#include "
statistics_internal.h
"
11
13
static
int
lmmc_real_compare(
const
void
* a,
const
void
* b) {
14
lmmc_real_t
va = *(
const
lmmc_real_t
*)a;
15
lmmc_real_t
vb = *(
const
lmmc_real_t
*)b;
16
if
(va < vb) {
return
-1; }
17
if
(va > vb) {
return
1; }
18
return
0;
19
}
20
21
22
static
int
lmmc_vec_values_are_finite(
const
lmmc_vec_t
* x) {
23
return
lmmc_real_range_is_finite(x->
data
, x->
size
);
24
}
25
26
lmmc_status_t
lmmc_vec_median
(
const
lmmc_vec_t
* x,
lmmc_real_t
* out) {
27
lmmc_real_t
* sorted = NULL;
28
size_t
n;
29
30
if
(out == NULL) {
return
LMMC_STATUS_INVALID_ARGUMENT
; }
31
if
(x == NULL || x->
data
== NULL || x->
size
== 0) {
return
LMMC_STATUS_INVALID_ARGUMENT
; }
32
if
(!lmmc_vec_values_are_finite(x)) {
33
return
LMMC_STATUS_NUMERICAL_FAILURE
;
34
}
35
36
n = x->
size
;
37
sorted = (
lmmc_real_t
*)
lmmc_memory_alloc_array
(n,
sizeof
(
lmmc_real_t
));
38
if
(sorted == NULL) {
return
LMMC_STATUS_ALLOCATION_FAILED
; }
39
40
for
(
size_t
i = 0; i < n; ++i) {
41
sorted[i] = x->
data
[i];
42
}
43
qsort(sorted, n,
sizeof
(
lmmc_real_t
), lmmc_real_compare);
44
45
if
(n % 2 == 1) {
46
*out = sorted[n / 2];
47
}
else
{
48
*out = lmmc_interval_midpoint(
49
sorted[n / 2 - 1], sorted[n / 2]);
50
}
51
52
lmmc_memory_free
(sorted);
53
return
LMMC_STATUS_OK
;
54
}
55
56
lmmc_status_t
lmmc_vec_quantile
(
const
lmmc_vec_t
* x,
lmmc_real_t
p,
lmmc_real_t
* out) {
57
lmmc_real_t
* sorted = NULL;
58
size_t
n;
59
double
h, frac;
60
size_t
lo, hi;
61
62
if
(out == NULL) {
return
LMMC_STATUS_INVALID_ARGUMENT
; }
63
if
(x == NULL || x->
data
== NULL || x->
size
== 0) {
return
LMMC_STATUS_INVALID_ARGUMENT
; }
64
if
(!lmmc_is_finite(&p) || p < 0.0 || p > 1.0) {
65
return
LMMC_STATUS_INVALID_ARGUMENT
;
66
}
67
if
(!lmmc_vec_values_are_finite(x)) {
68
return
LMMC_STATUS_NUMERICAL_FAILURE
;
69
}
70
71
n = x->
size
;
72
sorted = (
lmmc_real_t
*)
lmmc_memory_alloc_array
(n,
sizeof
(
lmmc_real_t
));
73
if
(sorted == NULL) {
return
LMMC_STATUS_ALLOCATION_FAILED
; }
74
75
for
(
size_t
i = 0; i < n; ++i) {
76
sorted[i] = x->
data
[i];
77
}
78
qsort(sorted, n,
sizeof
(
lmmc_real_t
), lmmc_real_compare);
79
81
h = p * (double)(n - 1);
82
lo = (size_t)h;
83
hi = lo + 1;
84
frac = h - (double)lo;
85
86
if
(hi >= n) {
87
*out = sorted[n - 1];
88
}
else
{
89
*out = sorted[lo] * (1.0 - frac) + sorted[hi] * frac;
90
}
91
92
lmmc_memory_free
(sorted);
93
return
LMMC_STATUS_OK
;
94
}
95
96
static
void
lmmc_histogram_bounds(
97
const
lmmc_vec_t
* x,
lmmc_real_t
* xmin,
lmmc_real_t
* xmax) {
98
size_t
i;
99
(*xmin) = x->
data
[0];
100
(*xmax) = x->
data
[0];
101
for
(i = 1; i < x->
size
; ++i) {
102
if
(x->
data
[i] < (*xmin)) {
103
(*xmin) = x->
data
[i];
104
}
105
if
(x->
data
[i] > (*xmax)) {
106
(*xmax) = x->
data
[i];
107
}
108
}
109
110
if
((*xmax) == (*xmin)) {
111
const
lmmc_real_t
value = (*xmin);
112
const
lmmc_real_t
lower = value - 0.5;
113
const
lmmc_real_t
upper = value + 0.5;
114
if
(lower < value && upper > value &&
115
lmmc_is_finite(&lower) && lmmc_is_finite(&upper)) {
116
(*xmin) = lower;
117
(*xmax) = upper;
118
}
else
if
(value > 0.0) {
119
(*xmin) = value * 0.5;
120
(*xmax) = value <= DBL_MAX / 1.5 ? value * 1.5 : value;
121
}
else
if
(value < 0.0) {
122
(*xmin) = value >= -DBL_MAX / 1.5 ? value * 1.5 : value;
123
(*xmax) = value * 0.5;
124
}
else
{
125
(*xmin) = -0.5;
126
(*xmax) = 0.5;
127
}
128
}
129
}
130
131
static
void
lmmc_histogram_edges(
132
lmmc_real_t
xmin,
lmmc_real_t
xmax,
size_t
nbins,
lmmc_real_t
* edges) {
133
size_t
i;
134
edges[0] = xmin;
135
for
(i = 1; i < nbins; ++i) {
136
const
lmmc_real_t
t =
137
(
lmmc_real_t
)i / (
lmmc_real_t
)nbins;
138
if
((xmin < 0.0 && xmax > 0.0) ||
139
(xmin > 0.0 && xmax < 0.0)) {
140
edges[i] = (1.0 - t) * xmin + t * xmax;
141
}
else
{
142
edges[i] = xmin + t * (xmax - xmin);
143
}
144
}
145
edges[nbins] = xmax;
146
147
}
148
149
static
size_t
lmmc_histogram_bin(
150
lmmc_real_t
value,
size_t
nbins,
lmmc_real_t
xmin,
lmmc_real_t
xmax,
151
int
crosses_zero,
lmmc_real_t
range_scale,
lmmc_real_t
scaled_min,
152
lmmc_real_t
scaled_span) {
153
size_t
bin;
154
if
(value <= xmin) {
155
bin = 0;
156
}
else
if
(value >= xmax) {
157
bin = nbins - 1;
158
}
else
{
159
lmmc_real_t
position;
160
lmmc_real_t
bin_position;
161
if
(crosses_zero) {
162
position =
163
(value / range_scale - scaled_min) /
164
scaled_span;
165
}
else
{
166
position =
167
(value - xmin) / (xmax - xmin);
168
}
169
bin_position = position * (
lmmc_real_t
)nbins;
170
if
(position >= 1.0 ||
171
bin_position >= (
lmmc_real_t
)(nbins - 1)) {
172
bin = nbins - 1;
173
}
else
if
(position <= 0.0) {
174
bin = 0;
175
}
else
{
176
bin = (size_t)bin_position;
177
}
178
}
179
return
bin;
180
}
181
182
lmmc_status_t
lmmc_vec_histogram
(
const
lmmc_vec_t
* x,
size_t
nbins,
lmmc_real_t
* edges,
size_t
* counts) {
183
size_t
n, i;
184
lmmc_real_t
xmin, xmax, range_scale = 1.0;
185
lmmc_real_t
scaled_min = 0.0, scaled_span = 0.0;
186
int
crosses_zero;
187
188
if
(x == NULL || x->
data
== NULL || x->
size
== 0) {
return
LMMC_STATUS_INVALID_ARGUMENT
; }
189
if
(nbins == 0 || edges == NULL || counts == NULL) {
return
LMMC_STATUS_INVALID_ARGUMENT
; }
190
if
(!lmmc_vec_values_are_finite(x)) {
191
return
LMMC_STATUS_NUMERICAL_FAILURE
;
192
}
193
194
n = x->
size
;
195
196
lmmc_histogram_bounds(x, &xmin, &xmax);
197
crosses_zero = xmin < 0.0 && xmax > 0.0;
198
if
(crosses_zero) {
199
range_scale = fmax(-xmin, xmax);
200
scaled_min = xmin / range_scale;
201
scaled_span = xmax / range_scale - scaled_min;
202
}
203
204
205
lmmc_histogram_edges(xmin, xmax, nbins, edges);
206
207
for
(i = 0; i < nbins; ++i) {
208
counts[i] = 0;
209
}
210
211
for
(i = 0; i < n; ++i) {
212
const
size_t
bin = lmmc_histogram_bin(x->
data
[i], nbins, xmin, xmax,
213
crosses_zero, range_scale, scaled_min, scaled_span);
214
counts[bin]++;
215
}
216
217
return
LMMC_STATUS_OK
;
218
}
config.h
LMMC binary real type and arithmetic spelling.
lmmc_real_t
double lmmc_real_t
Public and internal LMMC real type.
定义
config.h:28
lmmc_vec_t::size
size_t size
定义
dense_types.h:32
lmmc_vec_t::data
lmmc_real_t * data
定义
dense_types.h:33
lmmc_vec_t
一维稠密向量。
定义
dense_types.h:31
lmmc_memory_alloc_array
void * lmmc_memory_alloc_array(size_t count, size_t element_size)
定义
memory_bridge.c:55
lmmc_memory_free
void lmmc_memory_free(void *pointer)
定义
memory_bridge.c:75
memory_bridge.h
Private recoverable allocator for persistent LMMC ownership.
numeric.h
数值标量、特殊函数和 FFT 公共接口。
statistics_internal.h
stats.h
基础统计量与组合数学接口。
lmmc_vec_quantile
lmmc_status_t lmmc_vec_quantile(const lmmc_vec_t *x, lmmc_real_t p, lmmc_real_t *out)
计算向量的 p 分位数(线性插值法)。
定义
statistics_selection.c:56
lmmc_vec_histogram
lmmc_status_t lmmc_vec_histogram(const lmmc_vec_t *x, size_t nbins, lmmc_real_t *edges, size_t *counts)
计算向量的等宽直方图。
定义
statistics_selection.c:182
lmmc_vec_median
lmmc_status_t lmmc_vec_median(const lmmc_vec_t *x, lmmc_real_t *out)
计算向量中位数。
定义
statistics_selection.c:26
lmmc_status_t
lmmc_status_t
LMMC 库统一返回的状态码.
定义
status.h:22
LMMC_STATUS_OK
@ LMMC_STATUS_OK
定义
status.h:23
LMMC_STATUS_NUMERICAL_FAILURE
@ LMMC_STATUS_NUMERICAL_FAILURE
定义
status.h:29
LMMC_STATUS_ALLOCATION_FAILED
@ LMMC_STATUS_ALLOCATION_FAILED
定义
status.h:26
LMMC_STATUS_INVALID_ARGUMENT
@ LMMC_STATUS_INVALID_ARGUMENT
定义
status.h:24
stdlib.h
src
statistics_selection.c
生成于
, 为 LMMC使用
1.18.0