LMMC
Lamina Mathematic core
Toggle main menu visibility
载入中...
搜索中...
未找到
quadrature_extrapolation.c
浏览该文件的文档.
1
#include "
internal/quadrature_internal.h
"
2
3
typedef
struct
{
4
lmmc_quad_func_t
func
;
5
void
*
user_data
;
6
lmmc_real_t
center
;
7
lmmc_real_t
half_length
;
8
lmmc_real_t
prev
[30];
9
lmmc_real_t
curr
[30];
10
lmmc_quad_result_t
*
out
;
11
}
lmmc_quad_romberg_state_t
;
12
13
static
int
lmmc_quad_romberg_arguments(
14
lmmc_real_t
a,
lmmc_real_t
b,
lmmc_real_t
abs_tol,
size_t
max_iter)
15
{
16
if
(!isfinite(a) || !isfinite(b) || a >= b) {
17
return
0;
18
}
19
if
(!isfinite(abs_tol)) {
20
return
0;
21
}
22
if
(abs_tol < 1e-15 || abs_tol > 1e-1) {
23
return
0;
24
}
25
return
max_iter >= 1 && max_iter <= 30;
26
}
27
28
static
int
lmmc_quad_romberg_initial(
29
lmmc_quad_romberg_state_t
* state,
lmmc_real_t
a,
lmmc_real_t
b)
30
{
31
lmmc_real_t
fa, fb;
32
lmmc_quad_center_half_length
(a, b, &state->
center
, &state->
half_length
);
33
if
(!isfinite(state->
center
) || !isfinite(state->
half_length
)) {
34
return
0;
35
}
36
fa = state->
func
(a, state->
user_data
);
37
fb = state->
func
(b, state->
user_data
);
38
state->
out
->
num_evals
= 2;
39
if
(!isfinite(fa) || !isfinite(fb)) {
40
return
0;
41
}
42
state->
prev
[0] = state->
half_length
* (fa + fb);
43
if
(!isfinite(state->
prev
[0])) {
44
return
0;
45
}
46
state->
out
->
value
= state->
prev
[0];
47
return
1;
48
}
49
50
static
int
lmmc_quad_romberg_sample_row(
51
lmmc_quad_romberg_state_t
* state,
size_t
row)
52
{
53
const
size_t
n = (size_t)1 << row;
54
const
lmmc_real_t
normalized_h = 2.0 / (
lmmc_real_t
)n;
55
lmmc_real_t
sum_new = 0.0;
56
for
(
size_t
k = 1; k <= n / 2; ++k) {
57
const
lmmc_real_t
normalized_x =
58
-1.0 + (2.0 * (
lmmc_real_t
)k - 1.0) * normalized_h;
59
const
lmmc_real_t
x = fma(state->
half_length
, normalized_x, state->
center
);
60
const
lmmc_real_t
value = state->
func
(x, state->
user_data
);
61
++state->
out
->
num_evals
;
62
if
(!isfinite(value)) {
63
return
0;
64
}
65
sum_new += value;
66
if
(!isfinite(sum_new)) {
67
return
0;
68
}
69
}
70
state->
curr
[0] = state->
prev
[0] / 2.0 +
71
state->
half_length
* normalized_h * sum_new;
72
return
isfinite(state->
curr
[0]);
73
}
74
75
static
int
lmmc_quad_romberg_extrapolate(
76
lmmc_quad_romberg_state_t
* state,
size_t
row)
77
{
78
lmmc_real_t
pow4 = 1.0;
79
for
(
size_t
j = 1; j <= row; ++j) {
80
pow4 *= 4.0;
81
state->
curr
[j] = state->
curr
[j - 1] +
82
(state->
curr
[j - 1] - state->
prev
[j - 1]) / (pow4 - 1.0);
83
if
(!isfinite(state->
curr
[j])) {
84
return
0;
85
}
86
}
87
state->
out
->
value
= state->
curr
[row];
88
state->
out
->
error
= lmmc_abs(state->
curr
[row] - state->
prev
[row - 1]);
89
return
isfinite(state->
out
->
error
);
90
}
91
92
lmmc_status_t
lmmc_quad_romberg
(
93
lmmc_quad_func_t
f,
void
* ud,
lmmc_real_t
a,
lmmc_real_t
b,
94
lmmc_real_t
abs_tol,
size_t
max_iter,
lmmc_quad_result_t
* out)
95
{
96
lmmc_quad_romberg_state_t
state = {0};
97
if
(f == NULL || out == NULL) {
98
return
LMMC_STATUS_INVALID_ARGUMENT
;
99
}
100
out->
value
= 0.0;
101
out->
error
= INFINITY;
102
out->
num_evals
= 0;
103
if
(!lmmc_quad_romberg_arguments(a, b, abs_tol, max_iter)) {
104
return
LMMC_STATUS_INVALID_ARGUMENT
;
105
}
106
state.
func
= f;
107
state.
user_data
= ud;
108
state.
out
= out;
109
if
(!lmmc_quad_romberg_initial(&state, a, b)) {
110
return
LMMC_STATUS_NUMERICAL_FAILURE
;
111
}
112
for
(
size_t
i = 1; i < max_iter; ++i) {
113
if
(!lmmc_quad_romberg_sample_row(&state, i) ||
114
!lmmc_quad_romberg_extrapolate(&state, i)) {
115
return
LMMC_STATUS_NUMERICAL_FAILURE
;
116
}
117
if
(out->
error
<= abs_tol) {
118
return
LMMC_STATUS_OK
;
119
}
120
for
(
size_t
j = 0; j <= i; ++j) state.
prev
[j] = state.
curr
[j];
121
}
122
return
LMMC_STATUS_CONVERGENCE_FAILED
;
123
}
lmmc_real_t
double lmmc_real_t
Public and internal LMMC real type.
定义
config.h:28
lmmc_quad_result_t::error
lmmc_real_t error
定义
quadrature.h:26
lmmc_quad_result_t::num_evals
size_t num_evals
定义
quadrature.h:27
lmmc_quad_romberg
lmmc_status_t lmmc_quad_romberg(lmmc_quad_func_t f, void *ud, lmmc_real_t a, lmmc_real_t b, lmmc_real_t abs_tol, size_t max_iter, lmmc_quad_result_t *out)
Romberg 积分(Richardson 外推加速梯形法则)。
定义
quadrature_extrapolation.c:92
lmmc_quad_func_t
lmmc_real_t(*) lmmc_quad_func_t(lmmc_real_t x, void *user_data)
被积函数签名 。
定义
quadrature.h:19
lmmc_quad_result_t::value
lmmc_real_t value
定义
quadrature.h:25
lmmc_quad_result_t
自适应积分输出结果。
定义
quadrature.h:24
lmmc_quad_romberg_state_t::curr
lmmc_real_t curr[30]
定义
quadrature_extrapolation.c:9
lmmc_quad_romberg_state_t::func
lmmc_quad_func_t func
定义
quadrature_extrapolation.c:4
lmmc_quad_romberg_state_t::center
lmmc_real_t center
定义
quadrature_extrapolation.c:6
lmmc_quad_romberg_state_t::out
lmmc_quad_result_t * out
定义
quadrature_extrapolation.c:10
lmmc_quad_romberg_state_t::half_length
lmmc_real_t half_length
定义
quadrature_extrapolation.c:7
lmmc_quad_romberg_state_t::user_data
void * user_data
定义
quadrature_extrapolation.c:5
lmmc_quad_romberg_state_t::prev
lmmc_real_t prev[30]
定义
quadrature_extrapolation.c:8
lmmc_quad_romberg_state_t
定义
quadrature_extrapolation.c:3
quadrature_internal.h
lmmc_quad_center_half_length
void lmmc_quad_center_half_length(lmmc_real_t a, lmmc_real_t b, lmmc_real_t *center, lmmc_real_t *half_length)
定义
quadrature_common.c:3
lmmc_status_t
lmmc_status_t
LMMC 库统一返回的状态码.
定义
status.h:22
LMMC_STATUS_CONVERGENCE_FAILED
@ LMMC_STATUS_CONVERGENCE_FAILED
定义
status.h:31
LMMC_STATUS_OK
@ LMMC_STATUS_OK
定义
status.h:23
LMMC_STATUS_NUMERICAL_FAILURE
@ LMMC_STATUS_NUMERICAL_FAILURE
定义
status.h:29
LMMC_STATUS_INVALID_ARGUMENT
@ LMMC_STATUS_INVALID_ARGUMENT
定义
status.h:24
src
quadrature_extrapolation.c
生成于
, 为 LMMC使用
1.18.0