LAMMP 4.1.0
Lamina High-Precision Arithmetic Library
载入中...
搜索中...
未找到
bninv.c 文件参考
+ bninv.c 的引用(Include)关系图:

浏览源代码.

函数

void lmmp_bninv_ (mp_ptr restrict dstq, mp_srcptr restrict numa, mp_size_t na, mp_size_t ni)
 
static void lmmp_bninv_appr_newton_ (mp_ptr restrict dstq, mp_srcptr restrict numa, mp_size_t na, mp_size_t ni)
 牛顿法求精确逆元(至多产生1的误差)
 

函数说明

◆ lmmp_bninv_()

void lmmp_bninv_ ( mp_ptr restrict  dstq,
mp_srcptr restrict  numa,
mp_size_t  na,
mp_size_t  ni 
)

在文件 bninv.c125 行定义.

125 {
126 lmmp_param_assert(na > 0);
127 lmmp_param_assert(dstq != NULL && numa != NULL);
128 lmmp_param_assert(numa[na - 1] > 0);
129 TEMP_DECL;
130 if (na == 1) {
131 mp_ptr restrict bnp = TALLOC_TYPE(3 + ni, mp_limb_t);
132 lmmp_zero(bnp, 2 + ni);
133 bnp[2 + ni] = 1;
134 lmmp_div_1_(dstq, bnp, 3 + ni, numa[0]);
135 } else if (na == 2) {
136 mp_size_t bn = 2 * 2 + ni + 1;
137 mp_ptr restrict bnp = TALLOC_TYPE(bn, mp_limb_t);
138 lmmp_zero(bnp, bn - 1);
139 bnp[bn - 1] = 1;
140 mp_limb_t d[2] = {numa[0], numa[1]};
141 lmmp_div_2_(dstq, bnp, bn, d);
142 } else if (ni > na) {
143 mp_ptr restrict B = TALLOC_TYPE(2 * na + ni + 1, mp_limb_t);
144 lmmp_zero(B, 2 * na + ni);
145 B[2 * na + ni] = 1;
146 lmmp_div_(dstq, NULL, B, 2 * na + ni + 1, numa, na);
147 } else {
148 int shift = lmmp_leading_zeros_(numa[na - 1]);
149 if (shift > 0) {
150 mp_ptr restrict numa_shift = TALLOC_TYPE(na, mp_limb_t);
151 lmmp_shl_(numa_shift, numa, na, shift);
152 lmmp_bninv_appr_newton_(dstq, numa_shift, na, ni + 1);
153 lmmp_shr_(dstq, dstq, na + ni + 2, LIMB_BITS - shift);
154 } else {
155 lmmp_bninv_appr_newton_(dstq, numa, na, ni + 1);
156 lmmp_copy(dstq, dstq + 1, na + ni + 1);
157 dstq[na + ni + 1] = 0;
158 }
159 }
160 TEMP_FREE;
161 return;
162}
static void lmmp_bninv_appr_newton_(mp_ptr restrict dstq, mp_srcptr restrict numa, mp_size_t na, mp_size_t ni)
牛顿法求精确逆元(至多产生1的误差)
Definition bninv.c:74
#define bn
#define B
mp_limb_t * mp_ptr
Definition lmmp.h:215
#define lmmp_copy(dst, src, n)
Definition lmmp.h:364
#define lmmp_zero(dst, n)
Definition lmmp.h:366
uint64_t mp_size_t
Definition lmmp.h:212
uint64_t mp_limb_t
Definition lmmp.h:211
#define LIMB_BITS
Definition lmmp.h:221
#define lmmp_param_assert(x)
Definition lmmp.h:398
mp_limb_t lmmp_div_1_(mp_ptr dstq, mp_srcptr numa, mp_size_t na, mp_limb_t x)
单精度数除法
Definition div.c:66
int lmmp_leading_zeros_(mp_limb_t x)
计算一个单精度数(limb)中前导零的个数
Definition tiny.c:35
void lmmp_div_2_(mp_ptr dstq, mp_srcptr numa, mp_size_t na, mp_ptr numb)
双精度数除法 (除数为2个limb)
Definition div.c:223
mp_limb_t lmmp_shr_(mp_ptr dst, mp_srcptr numa, mp_size_t na, mp_size_t shr)
大数右移操作 [dst,na] = [numa,na] >> shr,dst的高shr位填充0
Definition shr.c:9
mp_limb_t lmmp_shl_(mp_ptr dst, mp_srcptr numa, mp_size_t na, mp_size_t shl)
大数左移操作 [dst,na] = [numa,na]<<shl,dst的低shl位填充0
Definition shl.c:9
void lmmp_div_(mp_ptr dstq, mp_ptr dstr, mp_srcptr numa, mp_size_t na, mp_srcptr numb, mp_size_t nb)
大数除法和取模操作
Definition div.c:57
#define TEMP_DECL
Definition tmp_alloc.h:72
#define TEMP_FREE
Definition tmp_alloc.h:93
#define TALLOC_TYPE(n, type)
Definition tmp_alloc.h:91

引用了 B, bn, LIMB_BITS, lmmp_bninv_appr_newton_(), lmmp_copy, lmmp_div_(), lmmp_div_1_(), lmmp_div_2_(), lmmp_leading_zeros_(), lmmp_param_assert, lmmp_shl_(), lmmp_shr_(), lmmp_zero, TALLOC_TYPE, TEMP_DECL , 以及 TEMP_FREE.

+ 函数调用图:

◆ lmmp_bninv_appr_newton_()

static void lmmp_bninv_appr_newton_ ( mp_ptr restrict  dstq,
mp_srcptr restrict  numa,
mp_size_t  na,
mp_size_t  ni 
)
static

牛顿法求精确逆元(至多产生1的误差)

注解
dstq := B^(2*(na+ni)) // ([numa,na] * B^ni) + [0|1]
警告
eqsep(dstq,numa), dstq!=NULL, numa!=NULL, na>=3, MSB(numa)=1

在文件 bninv.c74 行定义.

74 {
75 lmmp_param_assert(na >= 3);
76 lmmp_param_assert(dstq != NULL && numa != NULL);
77 lmmp_param_assert(numa[na - 1] > LIMB_B_2);
79 if (na < BNINV_NEWTON_THRESHOLD) {
80 mp_ptr restrict bnp = TALLOC_TYPE(2 * na + ni + 1, mp_limb_t);
81 lmmp_zero(bnp, 2 * na + ni + 1);
82 bnp[2 * na + ni] = 1;
83 mp_limb_t inv21 = lmmp_inv_2_1_(numa[na - 1], numa[na - 2]);
84 lmmp_div_basecase_(dstq, bnp, 2 * na + ni + 1, numa, na, inv21);
85 } else {
86 mp_srcptr restrict a_hat;
87
88 mp_size_t N = na + ni;
89 mp_size_t a_hatn = N / 2 + 1;
90 mp_size_t remn = N - a_hatn;
91 mp_size_t ni_hat;
92 if (remn > ni) {
93 ni_hat = 0;
94 a_hat = numa + na - a_hatn;
95 } else {
96 ni_hat = ni - remn;
97 a_hat = numa;
98 a_hatn = na;
99 }
100 mp_size_t q_hatn = a_hatn + ni_hat + 1;
101 mp_size_t qrn = N + 1 - q_hatn;
102 mp_ptr restrict q_hat = dstq + qrn;
103
104 mp_ptr restrict q_hat_sqr = TALLOC_TYPE(2 * q_hatn, mp_limb_t);
105 mp_ptr restrict q_hat_sqr_a = TALLOC_TYPE(2 * q_hatn + na, mp_limb_t);
106
107 lmmp_bninv_appr_newton_(q_hat, a_hat, a_hatn, ni_hat);
108 lmmp_sqr_(q_hat_sqr, q_hat, q_hatn);
109 lmmp_mul_(q_hat_sqr_a, q_hat_sqr, 2 * q_hatn, numa, na);
110 // we can assert q_hat_sqr_a[2*q_hatn+na-1] == 0
111 lmmp_zero(dstq, qrn);
112 if (2 * qrn + ni > 2 * N) {
113 mp_size_t start = 2 * qrn + ni - 2 * N;
114 lmmp_shl_(q_hat, q_hat, q_hatn, 1); // assert no carry
115 lmmp_sub_n_(dstq + start, dstq + start, q_hat_sqr_a, N + 1 - start);
116 } else {
117 mp_size_t start = 2 * N - 2 * qrn - ni;
118 lmmp_shl_(q_hat, q_hat, q_hatn, 1); // assert no carry
119 lmmp_sub_n_(dstq, dstq, q_hat_sqr_a + start, N + 1);
120 }
121 }
122 TEMP_FREE;
123}
const mp_limb_t * mp_srcptr
Definition lmmp.h:216
void lmmp_mul_(mp_ptr dst, mp_srcptr numa, mp_size_t na, mp_srcptr numb, mp_size_t nb)
不等长大数乘法操作 [dst,na+nb] = [numa,na] * [numb,nb]
void lmmp_sqr_(mp_ptr dst, mp_srcptr numa, mp_size_t na)
大数平方操作 [dst,2*na] = [numa,na]^2
Definition sqr.c:10
mp_limb_t lmmp_sub_n_(mp_ptr dst, mp_srcptr numa, mp_srcptr numb, mp_size_t n)
无借位的n位减法 [dst,n] = [numa,n] - [numb,n]
Definition sub_n.c:70
mp_limb_t lmmp_inv_2_1_(mp_limb_t xh, mp_limb_t xl)
2-1阶逆元计算 (inv21)
Definition inv.c:10
mp_limb_t lmmp_div_basecase_(mp_ptr dstq, mp_ptr numa, mp_size_t na, mp_srcptr numb, mp_size_t nb, mp_limb_t inv21)
基础除法运算
#define LIMB_B_2
Definition mparam.h:160
#define BNINV_NEWTON_THRESHOLD
Definition mparam.h:62

引用了 BNINV_NEWTON_THRESHOLD, LIMB_B_2, lmmp_bninv_appr_newton_(), lmmp_div_basecase_(), lmmp_inv_2_1_(), lmmp_mul_(), lmmp_param_assert, lmmp_shl_(), lmmp_sqr_(), lmmp_sub_n_(), lmmp_zero, TALLOC_TYPE, TEMP_DECL , 以及 TEMP_FREE.

被这些函数引用 lmmp_bninv_() , 以及 lmmp_bninv_appr_newton_().

+ 函数调用图:
+ 这是这个函数的调用关系图: