31 if (!spline || !out_y || !isfinite(query_x)) {
34 if (query_x < spline->xs[0] || query_x > spline->
xs[spline->
n - 1]) {
37 if (query_x == spline->
xs[spline->
n - 1]) {
38 *out_y = spline->
ys[spline->
n - 1];
42 dx = query_x - spline->
xs[seg];
43 a = spline->
coeffs[4 * seg + 0];
44 b = spline->
coeffs[4 * seg + 1];
45 c = spline->
coeffs[4 * seg + 2];
46 d = spline->
coeffs[4 * seg + 3];
47 result = a + dx * (b + dx * (c + dx * d));
48 if (!isfinite(result)) {
63 size_t i, nm1 = spline->
n - 1;
64 for (i = 0; i < nm1; i++) {
69 - h[i] * (2.0 * M[i] + M[i + 1]) / 6.0;
70 spline->
coeffs[4 * i + 0] = ai;
71 spline->
coeffs[4 * i + 1] = bi;
72 spline->
coeffs[4 * i + 2] = ci;
73 spline->
coeffs[4 * i + 3] = di;
77static int interp_spline_check_boundary(
const lmmc_real_t* ys,
size_t n,
85 return isfinite(left) && isfinite(right);
104 if (!spline->
xs || !spline->
ys || !spline->
coeffs) {
117 size_t i, n = spline->
n;
127 w->
sub = storage + 2 * n;
128 w->
dia = storage + 3 * n;
129 w->
sup = storage + 4 * n;
130 w->
rhs = storage + 5 * n;
137 for (i = 0; i < n - 1; ++i) w->
h[i] = spline->
xs[i + 1] - spline->
xs[i];
155 if (!interp_spline_check_boundary(ys, n, bc, deriv_left, deriv_right)) {
158 spline = interp_spline_allocate(xs, ys, n);
162 if (!interp_spline_workspace_init(&work, spline, bc)) {
177 cspline_compute_coeffs(spline, work.
h, work.
moments);
183 *out_spline = spline;
double lmmc_real_t
Public and internal LMMC real type.
lmmc_status_t lmmc_interp_cspline_eval(const lmmc_interp_cspline_t *spline, lmmc_real_t query_x, lmmc_real_t *out_y)
在样条上求值.
lmmc_status_t lmmc_interp_cspline_create(const lmmc_real_t *xs, const lmmc_real_t *ys, size_t n, lmmc_interp_cspline_t **out_spline)
由节点构造自然三次样条.
lmmc_spline_bc_t
样条边界条件类型.
lmmc_status_t lmmc_interp_cspline_create_ex(const lmmc_real_t *xs, const lmmc_real_t *ys, size_t n, lmmc_spline_bc_t bc, lmmc_real_t deriv_left, lmmc_real_t deriv_right, lmmc_interp_cspline_t **out_spline)
由节点构造带指定边界条件的三次样条.
void lmmc_interp_cspline_destroy(lmmc_interp_cspline_t *spline)
销毁三次样条上下文,释放内部分配的所有内存.
void interp_spline_standard(interp_spline_workspace_t *work, lmmc_spline_bc_t bc, lmmc_real_t deriv_left, lmmc_real_t deriv_right)
lmmc_real_t * diagonal_copy
size_t interp_find_interval(const lmmc_real_t *xs, size_t n, lmmc_real_t query_x)
int interp_check_finite_values(const lmmc_real_t *values, size_t n)
int interp_check_samples(const lmmc_real_t *xs, const lmmc_real_t *ys, size_t n, size_t minimum)
void interp_spline_periodic(interp_spline_workspace_t *work)
void interp_spline_not_a_knot(interp_spline_workspace_t *work)
void * lmmc_memory_alloc_array(size_t count, size_t element_size)
void * lmmc_memory_alloc(size_t size)
void * lmmc_memory_alloc_array_2d(size_t rows, size_t cols, size_t element_size)
void lmmc_memory_free(void *pointer)
Private recoverable allocator for persistent LMMC ownership.
lmmc_status_t
LMMC 库统一返回的状态码.
@ LMMC_STATUS_NUMERICAL_FAILURE
@ LMMC_STATUS_ALLOCATION_FAILED
@ LMMC_STATUS_INVALID_ARGUMENT
@ LMMC_STATUS_OUT_OF_RANGE