|
LAMMP 4.2.0
Lamina High-Precision Arithmetic Library
|
#include "../../../include/lammp/impl/inlines.h"#include "../../../include/lammp/impl/longlong.h"#include "../../../include/lammp/impl/log2_exp2.h"#include "../../../include/lammp/impl/tmp_alloc.h"#include "../../../include/lammp/numth.h"#include "../../../include/lammp/lmmpn.h"
cbrt.c 的引用(Include)关系图:宏定义 | |
| #define | Ahr (dst + nlo) |
| #define | MMIN 1728 |
函数 | |
| mp_limb_t | lmmp_cbrt_3_ (mp_limb_t a0, mp_limb_t a1, mp_limb_t a2) |
| 计算算数立方根 floor(cbrt(a0+a1*B+a2*B^2)) | |
| void | lmmp_cbrt_6_ (mp_ptr dst, mp_srcptr numa, mp_size_t na) |
| 计算算数立方根 floor(cbrt([numa,na])) | |
| mp_size_t | lmmp_cbrtapprox_ (mp_ptr restrict dst, mp_srcptr restrict numa, mp_size_t na, mp_size_t ni) |
| mp_limb_t | lmmp_cbrtapprox_3_ (mp_limb_t a0, mp_limb_t a1, mp_limb_t a2) |
| 计算近似立方根 floor(cbrt(a0+a1*B+a2*B^2))-[0|1] | |
| void | lmmp_cbrtapprox_6_ (mp_ptr dst, mp_srcptr numa, mp_size_t na) |
| 计算近似立方根 floor(cbrt([numa,na]))-[0|1] | |
| static void | lmmp_cube_3_ (mp_ptr restrict dst, mp_limb_t a) |
| Copyright (C) 2026 HJimmyK(Jericho Knox) | |
| static mp_size_t | lmmp_cube_6_ (mp_ptr restrict dst, mp_srcptr restrict numa) |
| #define MMIN 1728 |
计算算数立方根 floor(cbrt(a0+a1*B+a2*B^2))
| a0 | 低位 limb |
| a1 | 中位 limb |
| a2 | 高位 limb |
引用了 a0, a1, a2, LIMB_MAX, lmmp_cbrtapprox_3_(), lmmp_cmp_(), lmmp_cube_3_(), lmmp_param_assert, n , 以及 t.
函数调用图:计算算数立方根 floor(cbrt([numa,na]))
| dst | 结果指针(长度为 2 个limb) |
| numa | 被开方数指针 |
| na | 被开方数的 limb 长度 |
引用了 LIMB_MAX, lmmp_cbrtapprox_6_(), lmmp_cmp_(), lmmp_cube_6_(), lmmp_debug_assert, n , 以及 t.
函数调用图:| mp_size_t lmmp_cbrtapprox_ | ( | mp_ptr restrict | dst, |
| mp_srcptr restrict | numa, | ||
| mp_size_t | na, | ||
| mp_size_t | ni | ||
| ) |
假设计算 n 次根式:A^(1/n) 设 beta = B^b,alpha = Ah^(1/n),rho = A^(1/n)。 已知 tk 满足 floor(Ah^(1/n)) - 1 <= tk <= floor(Ah^(1/n)), 因此 xk = tk * beta 与真实根 rho 的误差满足(最坏情况): e = rho - xk <= 2 * beta。
牛顿迭代实数形式为: F(x) = ((n-1)*x + A / x^(n-1)) / n。 令 x = rho - e,在 rho 处泰勒展开可得: F(x) - rho = (n(n-1)/2) * (e^2 / rho) + O(e^3 / rho^2)。
由于 rho >= alpha * beta(因为 A >= Ah * beta^n,开方后略大于 alpha*beta), 将 e <= 2*beta 代入,忽略高阶小量,得到误差上限: F(x) - rho <= (n(n-1)/2) * ((2*beta)^2 / (alpha*beta)) = (2*n*(n-1)*beta) / alpha。
为使得最终取整后的绝对误差控制在 1 以内,只需令上式 <= 1: (2*n*(n-1)*beta) / alpha <= 1 => alpha >= 2*n*(n-1)*beta。
两边同时取 n 次方: Ah >= [2*n*(n-1)]^n * beta^n = [2*n*(n-1)]^n * B^(n*b)。
因此,若要保证递归校正始终收敛且误差不超过 1,常数 m 至少取: m_min = [2*n*(n-1)]^n。
对于立方根,即有:m_min = 1728
注:1728 是一个保守的上界,不满足此上界并不意味着迭代一定不收敛。
引用了 Ahr, lmmp_add_n_(), lmmp_cbrt_ulong_(), lmmp_cbrtapprox_(), lmmp_cbrtapprox_3_(), lmmp_cbrtapprox_6_(), lmmp_copy, lmmp_debug_assert, lmmp_div_(), lmmp_div_1_(), lmmp_param_assert, lmmp_shl_(), lmmp_sqr_, lmmp_zero, MMIN, n, TALLOC_TYPE, TEMP_DECL , 以及 TEMP_FREE.
被这些函数引用 lmmp_cbrtapprox_().
函数调用图:
这是这个函数的调用关系图:计算近似立方根 floor(cbrt(a0+a1*B+a2*B^2))-[0|1]
| a0 | 低位 limb |
| a1 | 中位 limb |
| a2 | 高位 limb |
引用了 a0, a1, a2, exp2_fixed_64(), LIMB_BITS, LIMB_MAX, lmmp_debug_assert, lmmp_div_1_(), lmmp_inc, lmmp_limb_bits_, lmmp_param_assert, log2_fixed_64() , 以及 n.
被这些函数引用 lmmp_cbrt_3_() , 以及 lmmp_cbrtapprox_().
函数调用图:
这是这个函数的调用关系图:计算近似立方根 floor(cbrt([numa,na]))-[0|1]
| dst | 结果指针(长度为 2 个limb) |
| numa | 被开方数指针 |
| na | 被开方数的 limb 长度 |
引用了 exp2_fixed_128(), LIMB_BITS, LIMB_MAX, lmmp_debug_assert, lmmp_div_1_(), lmmp_inc, lmmp_limb_bits_, lmmp_param_assert, log2_fixed_128(), n , 以及 t.
被这些函数引用 lmmp_cbrt_6_() , 以及 lmmp_cbrtapprox_().
函数调用图:
这是这个函数的调用关系图:Copyright (C) 2026 HJimmyK(Jericho Knox)
This file is part of LAMMP.
LAMMP is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
This program is distributed WITHOUT ANY WARRANTY.
See https://www.gnu.org/licenses/.
引用了 lmmp_mullh_, n , 以及 t.
被这些函数引用 lmmp_cbrt_3_().
这是这个函数的调用关系图:引用了 lmmp_mul_basecase_(), lmmp_sqr_basecase_(), n , 以及 t.
被这些函数引用 lmmp_cbrt_6_().
函数调用图:
这是这个函数的调用关系图: