LMMC
Lamina Mathematic core
Toggle main menu visibility
载入中...
搜索中...
未找到
interp_lagrange.c
浏览该文件的文档.
1
#include "
memory_bridge.h
"
2
#include "
internal.h
"
3
#include "
internal/interp_internal.h
"
4
5
#include <math.h>
6
#include <string.h>
7
8
struct
lmmc_interp_lagrange_t
{
9
size_t
n
;
10
lmmc_real_t
*
xs
;
11
lmmc_real_t
*
ys
;
12
lmmc_real_t
*
weights
;
13
};
14
15
lmmc_status_t
lmmc_interp_lagrange_create
(
16
const
lmmc_real_t
* xs,
const
lmmc_real_t
* ys,
size_t
n,
17
lmmc_interp_lagrange_t
** out_lagrange)
18
{
19
lmmc_interp_lagrange_t
* lag = NULL;
20
size_t
alloc_size;
21
lmmc_status_t
status;
22
23
if
(!out_lagrange) {
24
return
LMMC_STATUS_INVALID_ARGUMENT
;
25
}
26
*out_lagrange = NULL;
27
if
(!xs || !ys || n < 1 ||
28
!
interp_check_finite_values
(xs, n) ||
29
!
interp_check_finite_values
(ys, n)) {
30
return
LMMC_STATUS_INVALID_ARGUMENT
;
31
}
32
33
lag = (
lmmc_interp_lagrange_t
*)
lmmc_memory_alloc
(
sizeof
(*lag));
34
if
(!lag) {
35
return
LMMC_STATUS_ALLOCATION_FAILED
;
36
}
37
lag->
n
= n; lag->
xs
= NULL; lag->
ys
= NULL; lag->
weights
= NULL;
38
39
if
(!lmmc_safe_mul_size(n,
sizeof
(
lmmc_real_t
), &alloc_size)) {
40
lmmc_memory_free
(lag);
41
return
LMMC_STATUS_ALLOCATION_FAILED
;
42
}
43
44
lag->
xs
= (
lmmc_real_t
*)
lmmc_memory_alloc
(alloc_size);
45
lag->
ys
= (
lmmc_real_t
*)
lmmc_memory_alloc
(alloc_size);
46
lag->
weights
= (
lmmc_real_t
*)
lmmc_memory_alloc
(alloc_size);
47
if
(!lag->
xs
|| !lag->
ys
|| !lag->
weights
) {
48
lmmc_interp_lagrange_destroy
(lag);
49
return
LMMC_STATUS_ALLOCATION_FAILED
;
50
}
51
memcpy(lag->
xs
, xs, alloc_size);
52
memcpy(lag->
ys
, ys, alloc_size);
53
54
status =
interp_barycentric_weights
(lag->
xs
, lag->
n
, lag->
weights
);
55
if
(status !=
LMMC_STATUS_OK
) {
56
lmmc_interp_lagrange_destroy
(lag);
57
return
status;
58
}
59
60
*out_lagrange = lag;
61
return
LMMC_STATUS_OK
;
62
}
63
64
lmmc_status_t
lmmc_interp_lagrange_eval
(
65
const
lmmc_interp_lagrange_t
* lagrange,
66
lmmc_real_t
query_x,
lmmc_real_t
* out_y)
67
{
68
size_t
j;
69
lmmc_real_t
numer = 0.0, denom = 0.0, largest = -INFINITY;
70
lmmc_real_t
value_scale = 0.0, result;
71
if
(!lagrange || !out_y || !isfinite(query_x)) {
72
return
LMMC_STATUS_INVALID_ARGUMENT
;
73
}
74
75
for
(j = 0; j < lagrange->
n
; j++) {
76
if
(query_x == lagrange->
xs
[j]) {
77
*out_y = lagrange->
ys
[j];
78
return
LMMC_STATUS_OK
;
79
}
80
if
(fabs(lagrange->
ys
[j]) > value_scale) {
81
value_scale = fabs(lagrange->
ys
[j]);
82
}
83
}
84
85
for
(j = 0; j < lagrange->
n
; j++) {
86
lmmc_real_t
diff = query_x - lagrange->
xs
[j];
87
lmmc_real_t
log_distance = isfinite(diff) ? log(fabs(diff)) :
88
log(fabs(query_x / 2.0 - lagrange->
xs
[j] / 2.0)) + log(2.0);
89
lmmc_real_t
log_term = log(fabs(lagrange->
weights
[j])) - log_distance;
90
lmmc_real_t
term;
91
if
(log_term > largest) {
92
lmmc_real_t
factor = exp(largest - log_term);
93
numer *= factor;
94
denom *= factor;
95
largest = log_term;
96
}
97
term = copysign(exp(log_term - largest), lagrange->
weights
[j]) *
98
(diff < 0.0 ? -1.0 : 1.0);
99
numer += term * (value_scale == 0.0 ? 0.0 : lagrange->
ys
[j] / value_scale);
100
denom += term;
101
}
102
if
(denom == 0.0 || !isfinite(denom)) {
103
return
LMMC_STATUS_NUMERICAL_FAILURE
;
104
}
105
result = (numer / denom) * value_scale;
106
if
(!isfinite(result)) {
107
return
LMMC_STATUS_NUMERICAL_FAILURE
;
108
}
109
*out_y = result;
110
return
LMMC_STATUS_OK
;
111
}
112
113
void
lmmc_interp_lagrange_destroy
(
lmmc_interp_lagrange_t
* lagrange)
114
{
115
if
(!lagrange) {
116
return
;
117
}
118
lmmc_memory_free
(lagrange->
weights
);
119
lmmc_memory_free
(lagrange->
ys
);
120
lmmc_memory_free
(lagrange->
xs
);
121
lmmc_memory_free
(lagrange);
122
}
lmmc_real_t
double lmmc_real_t
Public and internal LMMC real type.
定义
config.h:28
internal.h
LMMC 内部使用的公共工具(仅源文件可见).
lmmc_interp_lagrange_eval
lmmc_status_t lmmc_interp_lagrange_eval(const lmmc_interp_lagrange_t *lagrange, lmmc_real_t query_x, lmmc_real_t *out_y)
在 Lagrange 插值多项式上求值.
定义
interp_lagrange.c:64
lmmc_interp_lagrange_destroy
void lmmc_interp_lagrange_destroy(lmmc_interp_lagrange_t *lagrange)
销毁 Lagrange 插值上下文.
定义
interp_lagrange.c:113
lmmc_interp_lagrange_create
lmmc_status_t lmmc_interp_lagrange_create(const lmmc_real_t *xs, const lmmc_real_t *ys, size_t n, lmmc_interp_lagrange_t **out_lagrange)
由节点构造 Lagrange 插值多项式(基于重心权重).
定义
interp_lagrange.c:15
interp_internal.h
interp_check_finite_values
int interp_check_finite_values(const lmmc_real_t *values, size_t n)
定义
interp.c:33
interp_barycentric_weights
lmmc_status_t interp_barycentric_weights(const lmmc_real_t *nodes, size_t n, lmmc_real_t *weights)
定义
interp.c:48
lmmc_interp_lagrange_t::xs
lmmc_real_t * xs
定义
interp_lagrange.c:10
lmmc_interp_lagrange_t::ys
lmmc_real_t * ys
定义
interp_lagrange.c:11
lmmc_interp_lagrange_t::n
size_t n
定义
interp_lagrange.c:9
lmmc_interp_lagrange_t::weights
lmmc_real_t * weights
定义
interp_lagrange.c:12
lmmc_interp_lagrange_t
Lagrange 多项式插值上下文(不透明类型).
定义
interp_lagrange.c:8
lmmc_memory_alloc
void * lmmc_memory_alloc(size_t size)
定义
memory_bridge.c:46
lmmc_memory_free
void lmmc_memory_free(void *pointer)
定义
memory_bridge.c:75
memory_bridge.h
Private recoverable allocator for persistent LMMC ownership.
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
src
interp_lagrange.c
生成于
, 为 LMMC使用
1.18.0