LAMMP 4.1.0
Lamina High-Precision Arithmetic Library
载入中...
搜索中...
未找到
toom_interp.h 文件参考
#include "tmp_alloc.h"
#include "../lmmpn.h"
+ toom_interp.h 的引用(Include)关系图:
+ 此图展示该文件直接或间接的被哪些文件引用了:

浏览源代码.

枚举

enum  toom6_flags { toom6_all_pos = 0 , toom6_vm1_neg = 1 , toom6_vm2_neg = 2 }
 
enum  toom7_flags { toom7_w1_neg = 1 , toom7_w3_neg = 2 }
 

函数

int lmmp_toom_eval_dgr3_pm1_ (mp_ptr xp1, mp_ptr xm1, mp_srcptr xp, mp_size_t n, mp_size_t x3n, mp_ptr tp)
 Toom-3 专用:3次多项式在 x = +1 和 x = -1 处求值 计算 P(+1) 和 P(-1),其中 P(x) 是一个3次多项式(4段系数)。
 
int lmmp_toom_eval_dgr3_pm2_ (mp_ptr xp2, mp_ptr xm2, mp_srcptr xp, mp_size_t n, mp_size_t x3n, mp_ptr tp)
 Toom-3 专用:3次多项式在 x = +2 和 x = -2 处求值 计算 P(+2) 和 P(-2),其中 P(x) 是一个3次多项式(4段系数)。
 
int lmmp_toom_eval_pm1_ (mp_ptr xp1, mp_ptr xm1, unsigned k, mp_srcptr xp, mp_size_t n, mp_size_t hn, mp_ptr tp)
 通用高阶 Toom 求值:k次多项式在 x = +1 和 x = -1 处求值
 
int lmmp_toom_eval_pm2_ (mp_ptr xp2, mp_ptr xm2, unsigned k, mp_srcptr xp, mp_size_t n, mp_size_t hn, mp_ptr tp)
 通用高阶 Toom 求值:k次多项式在 x = +2 和 x = -2 处求值
 
void lmmp_toom_interp5_ (mp_ptr dst, mp_ptr v2, mp_ptr vm1, mp_size_t n, mp_size_t spt, int vm1_neg, mp_limb_t vinf0)
 Toom插值计算(5点插值),用于Toom-33和Toom-42乘法算法
 
void lmmp_toom_interp6_ (mp_ptr dst, mp_size_t n, enum toom6_flags flags, mp_ptr w4, mp_ptr w2, mp_ptr w1, mp_size_t w0n)
 Toom插值计算(6点插值):用于Toom-43和Toom-52 乘法算法
 
void lmmp_toom_interp7_ (mp_ptr dst, mp_size_t n, enum toom7_flags flags, mp_ptr w1, mp_ptr w3, mp_ptr w4, mp_ptr w5, mp_size_t w6n, mp_ptr tp)
 Toom插值计算(7点插值):用于Toom-44、Toom-53、Toom-62 乘法算法
 

枚举类型说明

◆ toom6_flags

枚举值
toom6_all_pos 
toom6_vm1_neg 
toom6_vm2_neg 

在文件 toom_interp.h25 行定义.

@ toom6_vm2_neg
Definition toom_interp.h:25
@ toom6_vm1_neg
Definition toom_interp.h:25
@ toom6_all_pos
Definition toom_interp.h:25

◆ toom7_flags

枚举值
toom7_w1_neg 
toom7_w3_neg 

在文件 toom_interp.h27 行定义.

27{ toom7_w1_neg = 1, toom7_w3_neg = 2 };
@ toom7_w1_neg
Definition toom_interp.h:27
@ toom7_w3_neg
Definition toom_interp.h:27

函数说明

◆ lmmp_toom_eval_dgr3_pm1_()

int lmmp_toom_eval_dgr3_pm1_ ( mp_ptr  xp1,
mp_ptr  xm1,
mp_srcptr  xp,
mp_size_t  n,
mp_size_t  x3n,
mp_ptr  tp 
)

Toom-3 专用:3次多项式在 x = +1 和 x = -1 处求值 计算 P(+1) 和 P(-1),其中 P(x) 是一个3次多项式(4段系数)。

参数
xp1输出:P(+1) 的结果(n+1 个 limbs 空间)
xm1输出:P(-1) 的结果(n+1 个 limbs 空间)
xp输入:多项式系数数组(共4段,每段 n limbs)
n输入:每段完整系数的 limb 长度
x3n输入:最后一段系数的实际长度(通常等于 n)
tp临时缓存空间(至少 n+1 limbs)
警告
0<x3n<=n
返回
符号位:0=正,~0=负(对应 P(-1))

在文件 mul_toom_eval.c9 行定义.

9 {
10 int neg;
11 lmmp_param_assert(x3n > 0);
12 lmmp_param_assert(x3n <= n);
13
14 xp1[n] = lmmp_add_n_(xp1, xp, xp + 2 * n, n);
15 tp[n] = lmmp_add_(tp, xp + n, n, xp + 3 * n, x3n);
16
17 neg = (lmmp_cmp_(xp1, tp, n + 1) < 0) ? ~0 : 0;
18 if (neg)
19 lmmp_add_n_sub_n_(xp1, xm1, tp, xp1, n + 1);
20 else
21 lmmp_add_n_sub_n_(xp1, xm1, xp1, tp, n + 1);
22
23 lmmp_debug_assert(xp1[n] <= 3);
24 lmmp_debug_assert(xm1[n] <= 1);
25
26 return neg;
27}
#define lmmp_debug_assert(x)
Definition lmmp.h:387
#define lmmp_param_assert(x)
Definition lmmp.h:398
static mp_limb_t lmmp_add_(mp_ptr dst, mp_srcptr numa, mp_size_t na, mp_srcptr numb, mp_size_t nb)
大数加法静态内联函数 [dst,na]=[numa,na]+[numb,nb]
Definition lmmpn.h:1058
static int lmmp_cmp_(mp_srcptr numa, mp_srcptr numb, mp_size_t n)
大数比较函数(内联)
Definition lmmpn.h:1004
mp_limb_t lmmp_add_n_sub_n_(mp_ptr dsta, mp_ptr dstb, mp_srcptr numa, mp_srcptr numb, mp_size_t n)
同时执行n位加法和减法 ([dsta,n],[dstb,n]) = ([numa,n]+[numb,n],[numa,n]-[numb,n])
Definition add_n_sub_n.c:10
mp_limb_t lmmp_add_n_(mp_ptr dst, mp_srcptr numa, mp_srcptr numb, mp_size_t n)
无进位的n位加法 [dst,n] = [numa,n] + [numb,n]
Definition add_n.c:71
#define tp

引用了 lmmp_add_(), lmmp_add_n_(), lmmp_add_n_sub_n_(), lmmp_cmp_(), lmmp_debug_assert, lmmp_param_assert , 以及 tp.

被这些函数引用 lmmp_mul_toom43_(), lmmp_mul_toom44_() , 以及 lmmp_sqr_toom4_().

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

◆ lmmp_toom_eval_dgr3_pm2_()

int lmmp_toom_eval_dgr3_pm2_ ( mp_ptr  xp2,
mp_ptr  xm2,
mp_srcptr  xp,
mp_size_t  n,
mp_size_t  x3n,
mp_ptr  tp 
)

Toom-3 专用:3次多项式在 x = +2 和 x = -2 处求值 计算 P(+2) 和 P(-2),其中 P(x) 是一个3次多项式(4段系数)。

参数
xp2输出:P(+2) 的结果(n+1 个 limbs 空间)
xm2输出:P(-2) 的结果(n+1 个 limbs 空间)
xp输入:多项式系数数组(共4段,每段 n limbs)
n输入:每段完整系数的 limb 长度
x3n输入:最后一段系数的实际长度
tp临时缓存空间(至少 n+1 limbs)
警告
0<x3n<=n
返回
符号位:0=正,~0=负(对应 P(-2))

在文件 mul_toom_eval.c29 行定义.

29 {
30 mp_limb_t cy;
31 int neg;
32 lmmp_param_assert(x3n > 0);
33 lmmp_param_assert(x3n <= n);
34 /* (x0 + 4 * x2) +/- (2 x1 + 8 x_3) */
35
36 cy = lmmp_shl_(tp, xp + 2 * n, n, 2);
37 xp2[n] = cy + lmmp_add_n_(xp2, tp, xp, n);
38
39 tp[x3n] = lmmp_shl_(tp, xp + 3 * n, x3n, 2);
40 if (x3n < n)
41 tp[n] = lmmp_add_(tp, xp + n, n, tp, x3n + 1);
42 else
43 tp[n] += lmmp_add_n_(tp, xp + n, tp, n);
44
45 lmmp_shl_(tp, tp, n + 1, 1);
46
47 neg = (lmmp_cmp_(xp2, tp, n + 1) < 0) ? ~0 : 0;
48
49 if (neg)
50 lmmp_add_n_sub_n_(xp2, xm2, tp, xp2, n + 1);
51 else
52 lmmp_add_n_sub_n_(xp2, xm2, xp2, tp, n + 1);
53
54 lmmp_debug_assert(xp2[n] < 15);
55 lmmp_debug_assert(xm2[n] < 10);
56
57 return neg;
58}
uint64_t mp_limb_t
Definition lmmp.h:211
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

引用了 lmmp_add_(), lmmp_add_n_(), lmmp_add_n_sub_n_(), lmmp_cmp_(), lmmp_debug_assert, lmmp_param_assert, lmmp_shl_() , 以及 tp.

被这些函数引用 lmmp_mul_toom43_(), lmmp_mul_toom44_() , 以及 lmmp_sqr_toom4_().

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

◆ lmmp_toom_eval_pm1_()

int lmmp_toom_eval_pm1_ ( mp_ptr  xp1,
mp_ptr  xm1,
unsigned  k,
mp_srcptr  xp,
mp_size_t  n,
mp_size_t  hn,
mp_ptr  tp 
)

通用高阶 Toom 求值:k次多项式在 x = +1 和 x = -1 处求值

参数
xp1输出:P(+1) 的结果(n+1 limbs)
xm1输出:P(-1) 的结果(n+1 limbs)
k输入:多项式次数(也是完整段的数量)
xp输入:多项式系数数组
n输入:每段完整系数的 limb 长度
hn输入:最后一段系数的实际长度
tp临时缓存空间(n+1 limbs)
警告
0<hn<=n, 3 < k
返回
符号位:0=正,~0=负

在文件 mul_toom_eval.c60 行定义.

60 {
61 unsigned i;
62 int neg;
63 lmmp_param_assert(k >= 4);
64
65 lmmp_param_assert(hn > 0);
66 lmmp_param_assert(hn <= n);
67
68 /* The degree k is also the number of full-size coefficients, so
69 * that last coefficient, of size hn, starts at xp + k*n. */
70
71 xp1[n] = lmmp_add_n_(xp1, xp, xp + 2 * n, n);
72 for (i = 4; i < k; i += 2) lmmp_add_(xp1, xp1, n + 1, xp + i * n, n);
73
74 tp[n] = lmmp_add_n_(tp, xp + n, xp + 3 * n, n);
75 for (i = 5; i < k; i += 2) lmmp_add_(tp, tp, n + 1, xp + i * n, n);
76
77 if (k & 1)
78 lmmp_add_(tp, tp, n + 1, xp + k * n, hn);
79 else
80 lmmp_add_(xp1, xp1, n + 1, xp + k * n, hn);
81
82 neg = (lmmp_cmp_(xp1, tp, n + 1) < 0) ? ~0 : 0;
83
84 if (neg)
85 lmmp_add_n_sub_n_(xp1, xm1, tp, xp1, n + 1);
86 else
87 lmmp_add_n_sub_n_(xp1, xm1, xp1, tp, n + 1);
88
89 lmmp_debug_assert(xp1[n] <= k);
90 lmmp_debug_assert(xm1[n] <= k / 2 + 1);
91
92 return neg;
93}
#define k

引用了 k, lmmp_add_(), lmmp_add_n_(), lmmp_add_n_sub_n_(), lmmp_cmp_(), lmmp_debug_assert, lmmp_param_assert , 以及 tp.

被这些函数引用 lmmp_mul_toom52_(), lmmp_mul_toom53_(), lmmp_mul_toom62_(), lmmp_mul_toom62_cache_() , 以及 lmmp_mul_toom62_cache_init_().

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

◆ lmmp_toom_eval_pm2_()

int lmmp_toom_eval_pm2_ ( mp_ptr  xp2,
mp_ptr  xm2,
unsigned  k,
mp_srcptr  xp,
mp_size_t  n,
mp_size_t  hn,
mp_ptr  tp 
)

通用高阶 Toom 求值:k次多项式在 x = +2 和 x = -2 处求值

参数
xp2输出:P(+2) 的结果(n+1 limbs)
xm2输出:P(-2) 的结果(n+1 limbs)
k输入:多项式次数
xp输入:多项式系数数组
n输入:每段完整系数的 limb 长度
hn输入:最后一段系数的实际长度
tp临时缓存空间(n+1 limbs)
警告
0<hn<=n, 3 < k < LIMB_BITS
返回
符号位:0=正,~0=负

在文件 mul_toom_eval.c107 行定义.

107 {
108 int i;
109 int neg;
110 mp_limb_t cy;
111 lmmp_param_assert(k >= 3);
113
114 lmmp_param_assert(hn > 0);
115 lmmp_param_assert(hn <= n);
116
117 /* The degree k is also the number of full-size coefficients, so
118 * that last coefficient, of size hn, starts at xp + k*n. */
119
120 cy = 0;
121 DO_addlsh2(xp2, xp + (k - 2) * n, xp + k * n, hn, cy);
122 if (hn != n)
123 cy = lmmp_add_1_(xp2 + hn, xp + (k - 2) * n + hn, n - hn, cy);
124 for (i = k - 4; i >= 0; i -= 2) DO_addlsh2(xp2, xp + i * n, xp2, n, cy);
125 xp2[n] = cy;
126
127 k--;
128
129 cy = 0;
130 DO_addlsh2(tp, xp + (k - 2) * n, xp + k * n, n, cy);
131 for (i = k - 4; i >= 0; i -= 2) DO_addlsh2(tp, xp + i * n, tp, n, cy);
132 tp[n] = cy;
133
134 if (k & 1)
135 lmmp_shl_(tp, tp, n + 1, 1);
136 else
137 lmmp_shl_(xp2, xp2, n + 1, 1);
138
139 neg = (lmmp_cmp_(xp2, tp, n + 1) < 0) ? ~0 : 0;
140
141 if (neg)
142 lmmp_add_n_sub_n_(xp2, xm2, tp, xp2, n + 1);
143 else
144 lmmp_add_n_sub_n_(xp2, xm2, xp2, tp, n + 1);
145
146 lmmp_debug_assert(xp2[n] < (1ull << (k + 2)) - 1);
147 lmmp_debug_assert(xm2[n] < ((1 << (k + 3)) - 1 - (1 ^ (k & 1))) / 3);
148
149 neg ^= ((k & 1) - 1);
150
151 return neg;
152}
#define LIMB_BITS
Definition lmmp.h:221
static mp_limb_t lmmp_add_1_(mp_ptr dst, mp_srcptr numa, mp_size_t na, mp_limb_t x)
大数加单精度数静态内联函数 [dst,na]=[numa,na]+x
Definition lmmpn.h:1111
#define DO_addlsh2(d, a, b, n, cy)

引用了 DO_addlsh2, k, LIMB_BITS, lmmp_add_1_(), lmmp_add_n_sub_n_(), lmmp_cmp_(), lmmp_debug_assert, lmmp_param_assert, lmmp_shl_() , 以及 tp.

被这些函数引用 lmmp_mul_toom52_(), lmmp_mul_toom53_(), lmmp_mul_toom62_(), lmmp_mul_toom62_cache_() , 以及 lmmp_mul_toom62_cache_init_().

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

◆ lmmp_toom_interp5_()

void lmmp_toom_interp5_ ( mp_ptr  dst,
mp_ptr  v2,
mp_ptr  vm1,
mp_size_t  n,
mp_size_t  spt,
int  vm1_neg,
mp_limb_t  vinf0 
)

Toom插值计算(5点插值),用于Toom-33和Toom-42乘法算法

参数
dst输出结果缓冲区,存储插值计算结果 v(0)储存在[dst,2n],v(1)储存在[dst+2n,2n]
v2v(2)插值点值,长度为 2n+1
vm1v(-1)插值点值,长度为 2n+1
n操作数的 limb 长度
spt系数r4的长度
vm1_neg符号标记:v(-1)是否为负数(1表示负,0表示正)
vinf0无穷远点插值的低64位值

在文件 mul_toom_interp5.c10 行定义.

10 {
11 mp_limb_t cy, saved;
12 mp_size_t dnp = 2 * n + 1;
13
14#define r0 (dst)
15#define r1 (dst + n)
16#define r2 (dst + 2 * n)
17#define r3 (dst + 3 * n)
18#define r4 (dst + 4 * n)
19#define v0 r0
20#define v1 r2
21#define vinf r4
22
23 // v2=(v2-vm1)/3
24 if (vm1_neg)
25 lmmp_add_n_(v2, v2, vm1, dnp);
26 else
27 lmmp_sub_n_(v2, v2, vm1, dnp);
29
30 // vm1=(v1-vm1)/2
31 if (vm1_neg)
32 lmmp_shr1add_n_(vm1, v1, vm1, dnp);
33 else
34 lmmp_shr1sub_n_(vm1, v1, vm1, dnp);
35
36 // v1=v1-v0
37 v1[2 * n] -= lmmp_sub_n_(v1, v1, v0, 2 * n);
38
39 // v2=(v2-v1)/2
40 lmmp_shr1sub_n_(v2, v2, v1, dnp);
41
42 // v1=v1-vm1
43 lmmp_sub_n_(v1, v1, vm1, dnp);
44
45 // add vm1 at correct place.
46 cy = lmmp_add_n_(r1, r1, vm1, dnp);
47 lmmp_inc_1(r3 + 1, cy); // at most propagate to v1[2*n]
48
49 saved = v1[2 * n]; // it is vinf[0]
50 vinf[0] = vinf0; // correct value of vinf
51
52 // v2=v2-vinf*2
53 cy = lmmp_shl_(vm1, vinf, spt, 1);
54 cy += lmmp_sub_n_(v2, v2, vm1, spt);
55 lmmp_dec_1(v2 + spt, cy);
56
57 // vinf+=v2h, no overflow
58 cy = lmmp_add_n_(vinf, vinf, v2 + n, n + 1);
59 lmmp_inc_1(r3 + dnp, cy);
60
61 // v1-=vinf, (same time vmh-=v2h)
62 cy = lmmp_sub_n_(v1, v1, vinf, spt);
63 vinf0 = vinf[0];
64 v1[2 * n] = saved; // correct value of v1
65 lmmp_dec_1(v1 + spt, cy);
66
67 // vml-=v2l
68 cy = lmmp_sub_n_(r1, r1, v2, n);
69 lmmp_dec_1(v1, cy);
70
71 // last v2l
72 cy = lmmp_add_n_(r3, r3, v2, n);
73 v1[2 * n] += cy; // no carry
74 lmmp_inc_1(vinf, vinf0);
75}
static void lmmp_divexact_by3_(mp_ptr dst, mp_srcptr numa, mp_size_t na)
精确除以3([dst,na] = [numa,na] / 3)
Definition divexact.h:33
uint64_t mp_size_t
Definition lmmp.h:212
mp_limb_t lmmp_shr1add_n_(mp_ptr dst, mp_srcptr numa, mp_srcptr numb, mp_size_t n)
加法后右移1位 [dst,n] = ([numa,n] + [numb,n]) >> 1
Definition shr.c:52
#define lmmp_dec_1(p, dec)
大数减指定值宏(预期无借位)
Definition lmmpn.h:985
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_shr1sub_n_(mp_ptr dst, mp_srcptr numa, mp_srcptr numb, mp_size_t n)
减法后右移1位 [dst,n] = ([numa,n] - [numb,n]) >> 1
Definition shr.c:106
#define lmmp_inc_1(p, inc)
大数加指定值宏(预期无进位)
Definition lmmpn.h:958
#define vm1
#define v2
#define v0
#define r1
#define vinf
#define v1
#define r3

引用了 lmmp_add_n_(), lmmp_dec_1, lmmp_divexact_by3_(), lmmp_inc_1, lmmp_shl_(), lmmp_shr1add_n_(), lmmp_shr1sub_n_(), lmmp_sub_n_(), r1, r3, v0, v1, v2, vinf , 以及 vm1.

被这些函数引用 lmmp_mul_toom33_(), lmmp_mul_toom42_(), lmmp_mul_toom42_cache_(), lmmp_mul_toom42_cache_init_() , 以及 lmmp_sqr_toom3_().

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

◆ lmmp_toom_interp6_()

void lmmp_toom_interp6_ ( mp_ptr  dst,
mp_size_t  n,
enum toom6_flags  flags,
mp_ptr  w4,
mp_ptr  w2,
mp_ptr  w1,
mp_size_t  w0n 
)

Toom插值计算(6点插值):用于Toom-43和Toom-52 乘法算法

参数
dst输出:最终乘积结果缓冲区(5n + w0n limbs) w5 储存在[dst,2n], w3 储存在[dst+2n,2n+1], w0 储存在[dst+5n,w0n].
n输入:Toom-6 拆分后每段标准 limb 长度
flags输入:Toom-6 插值符号标志位(控制正负号运算)
  • toom6_vm2_neg: 对应 x=-2 点值符号
  • toom6_vm1_neg: 对应 x=-1 点值符号
w4输入/临时:点值 W4 缓冲区(2n+1 limbs)
w2输入/临时:点值 W2 缓冲区(2n+1 limbs)
w1输入/临时:点值 W1 缓冲区(2n+1 limbs)
w0n输入:最低位段 W0 的实际 limb 长度(0 < w0n <= 2n)
注解
w5=f(0), w4=f(-1), w3=f(1), w2=f(-2), w1=f(2), w0=f(inf)
警告
n>0, 0<w0n<=2n

在文件 mul_toom_interp6.c39 行定义.

47 {
48
49 lmmp_param_assert(n > 0);
50 lmmp_param_assert(2 * n >= w0n && w0n > 0);
51 mp_limb_t cy;
52 /* cy6 can be stored in w1[2*n], cy4 in w4[0], embankment in w2[0] */
53 mp_limb_t cy4, cy6, embankment;
54
55#define w5 dst /* 2n */
56#define w3 (dst + 2 * n) /* 2n+1 */
57#define w0 (dst + 5 * n) /* w0n */
58
59 /* W2 =(W1 - W2)>>2 */
60 if (flags & toom6_vm2_neg)
61 lmmp_add_n_(w2, w1, w2, 2 * n + 1);
62 else
63 lmmp_sub_n_(w2, w1, w2, 2 * n + 1);
64 lmmp_shr_(w2, w2, 2 * n + 1, 2);
65
66 /* W1 =(W1 - W5)>>1 */
67 w1[2 * n] -= lmmp_sub_n_(w1, w1, w5, 2 * n);
68 lmmp_shr_(w1, w1, 2 * n + 1, 1);
69
70 /* W1 =(W1 - W2)>>1 */
71 lmmp_shr1sub_n_(w1, w1, w2, 2 * n + 1);
72
73 /* W4 =(W3 - W4)>>1 */
74 if (flags & toom6_vm1_neg) {
75 lmmp_shr1add_n_(w4, w3, w4, 2 * n + 1);
76 } else {
77 lmmp_shr1sub_n_(w4, w3, w4, 2 * n + 1);
78 }
79
80 /* W2 =(W2 - W4)/3 */
81 lmmp_sub_n_(w2, w2, w4, 2 * n + 1);
82 lmmp_divexact_by3_(w2, w2, 2 * n + 1);
83
84 /* W3 = W3 - W4 - W5 */
85 lmmp_sub_n_(w3, w3, w4, 2 * n + 1);
86 w3[2 * n] -= lmmp_sub_n_(w3, w3, w5, 2 * n);
87
88 /* W1 =(W1 - W3)/3 */
89 lmmp_sub_n_(w1, w1, w3, 2 * n + 1);
90 lmmp_divexact_by3_(w1, w1, 2 * n + 1);
91
92 cy = lmmp_add_n_(dst + n, dst + n, w4, 2 * n + 1);
93 lmmp_inc_1(dst + 3 * n + 1, cy);
94
95 /* W2 -= W0<<2 */
96 /* {W4,2*n+1} is now free and can be overwritten. */
97 cy = lmmp_shl_(w4, w0, w0n, 2);
98 cy += lmmp_sub_n_(w2, w2, w4, w0n);
99
100 lmmp_dec_1(w2 + w0n, cy);
101
102 /* W4L = W4L - W2L */
103 cy = lmmp_sub_n_(dst + n, dst + n, w2, n);
104 lmmp_dec_1(w3, cy);
105
106 /* W3H = W3H + W2L */
107 cy4 = w3[2 * n] + lmmp_add_n_(dst + 3 * n, dst + 3 * n, w2, n);
108 /* W1L + W2H */
109 cy = w2[2 * n] + lmmp_add_n_(dst + 4 * n, w1, w2 + n, n);
110 lmmp_inc_1(w1 + n, cy);
111
112 /* W0 = W0 + W1H */
113 if (w0n > n)
114 cy6 = w1[2 * n] + lmmp_add_n_(w0, w0, w1 + n, n);
115 else
116 cy6 = lmmp_add_n_(w0, w0, w1 + n, w0n);
117
118 cy = lmmp_sub_n_(dst + 2 * n, dst + 2 * n, dst + 4 * n, n + w0n);
119
120 /* embankment is a "dirty trick" to avoid carry/borrow propagation
121 beyond allocated memory */
122 embankment = w0[w0n - 1] - 1;
123 w0[w0n - 1] = 1;
124 if (w0n > n) {
125 if (cy4 > cy6)
126 lmmp_inc_1(dst + 4 * n, cy4 - cy6);
127 else
128 lmmp_dec_1(dst + 4 * n, cy6 - cy4);
129 lmmp_dec_1(dst + 3 * n + w0n, cy);
130 lmmp_inc_1(w0 + n, cy6);
131 } else {
132 lmmp_inc_1(dst + 4 * n, cy4);
133 lmmp_dec_1(dst + 3 * n + w0n, cy + cy6);
134 }
135 w0[w0n - 1] += embankment;
136
137#undef w5
138#undef w3
139#undef w0
140}
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
#define w3
#define w0
#define w5
#define w2

引用了 lmmp_add_n_(), lmmp_dec_1, lmmp_divexact_by3_(), lmmp_inc_1, lmmp_param_assert, lmmp_shl_(), lmmp_shr1add_n_(), lmmp_shr1sub_n_(), lmmp_shr_(), lmmp_sub_n_(), toom6_vm1_neg, toom6_vm2_neg, w0, w2, w3 , 以及 w5.

被这些函数引用 lmmp_mul_toom43_() , 以及 lmmp_mul_toom52_().

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

◆ lmmp_toom_interp7_()

void lmmp_toom_interp7_ ( mp_ptr  dst,
mp_size_t  n,
enum toom7_flags  flags,
mp_ptr  w1,
mp_ptr  w3,
mp_ptr  w4,
mp_ptr  w5,
mp_size_t  w6n,
mp_ptr  tp 
)

Toom插值计算(7点插值):用于Toom-44、Toom-53、Toom-62 乘法算法

参数
dst输出结果缓冲区,存储插值计算结果(6*n + w6n limbs) w0 储存在[dst,2n], w2 储存在[dst+2n,2n+1], w6 储存在[dst+6n,w6n].
n输入:Toom-7 拆分后每段标准 limb 长度
flags输入:Toom-7 符号标志位,控制插值中的正负号运算
  • toom7_w1_neg: 点值 W1 符号位
  • toom7_w3_neg: 点值 W3 符号位
w1输入/临时:点值 W1 缓冲区(2n+1 limbs)
w3输入/临时:点值 W3 缓冲区(2n+1 limbs)
w4输入/临时:点值 W4 缓冲区(2n+1 limbs)
w5输入/临时:点值 W5 缓冲区(2n+1 limbs)
w6n输入:最低位段 W6 的实际 limb 长度 (0 < w6n ≤ 2n)
tp临时缓存空间(2*n+1 limbs)
注解
w0=f(0), w1=f(-2), w2=f(1), w3=f(-1), w4=f(2), w5=64*f(1/2), w6=f(inf),
警告
n>0, 0<w6n<=2n

在文件 mul_toom_interp7.c45 行定义.

55 {
56 lmmp_param_assert(w6n > 0);
57 lmmp_param_assert(w6n <= 2 * n);
58 mp_size_t m;
59 mp_limb_t cy;
60
61 m = 2 * n + 1;
62#define w0 dst
63#define w2 (dst + 2 * n)
64#define w6 (dst + 6 * n)
65
66 lmmp_add_n_(w5, w5, w4, m);
67 if (flags & toom7_w1_neg) {
68 lmmp_shr1add_n_(w1, w1, w4, m);
69 } else {
70 lmmp_shr1sub_n_(w1, w4, w1, m);
71 }
72 lmmp_sub_(w4, w4, m, w0, 2 * n);
73 lmmp_sub_n_(w4, w4, w1, m);
74
75 lmmp_debug_assert(!(w4[0] & 3));
76
77 lmmp_shr_(w4, w4, m, 2); /* w4>=0 */
78
79 tp[w6n] = lmmp_shl_(tp, w6, w6n, 4);
80 lmmp_sub_(w4, w4, m, tp, w6n + 1);
81
82 if (flags & toom7_w3_neg) {
83 lmmp_shr1add_n_(w3, w3, w2, m);
84 } else {
85 lmmp_shr1sub_n_(w3, w2, w3, m);
86 }
87
88 lmmp_sub_n_(w2, w2, w3, m);
89
90 lmmp_submul_1_(w5, w2, m, 65);
91 lmmp_sub_(w2, w2, m, w6, w6n);
92 lmmp_sub_(w2, w2, m, w0, 2 * n);
93
94 lmmp_addmul_1_(w5, w2, m, 45);
95 lmmp_debug_assert(!(w5[0] & 1));
96 lmmp_shr_(w5, w5, m, 1);
97 lmmp_sub_n_(w4, w4, w2, m);
98
99 lmmp_divexact_by3_(w4, w4, m);
100 lmmp_sub_n_(w2, w2, w4, m);
101
102 lmmp_sub_n_(w1, w5, w1, m);
103 lmmp_shl_(tp, w3, m, 3);
104 lmmp_sub_n_(w5, w5, tp, m);
106 lmmp_sub_n_(w3, w3, w5, m);
107
108 lmmp_divexact_by15_(w1, w1, m);
109 lmmp_shr1add_n_(w1, w1, w5, m);
110 w1[m - 1] &= LIMB_MAX >> 1;
111
112 lmmp_sub_n_(w5, w5, w1, m);
113
114 /* These bounds are valid for the 4x4 polynomial product of toom44,
115 * and they are conservative for toom53 and toom62. */
116 lmmp_debug_assert(w1[2 * n] < 2);
117 lmmp_debug_assert(w2[2 * n] < 3);
118 lmmp_debug_assert(w3[2 * n] < 4);
119 lmmp_debug_assert(w4[2 * n] < 3);
120 lmmp_debug_assert(w5[2 * n] < 2);
121
122 cy = lmmp_add_n_(dst + n, dst + n, w1, m);
123 lmmp_inc_1(w2 + n + 1, cy);
124 cy = lmmp_add_n_(dst + 3 * n, dst + 3 * n, w3, n);
125 lmmp_inc_1(w3 + n, w2[2 * n] + cy);
126 cy = lmmp_add_n_(dst + 4 * n, w3 + n, w4, n);
127 lmmp_inc_1(w4 + n, w3[2 * n] + cy);
128 cy = lmmp_add_n_(dst + 5 * n, w4 + n, w5, n);
129 lmmp_inc_1(w5 + n, w4[2 * n] + cy);
130 if (w6n > n + 1) {
131 cy = lmmp_add_n_(dst + 6 * n, dst + 6 * n, w5 + n, n + 1);
132 lmmp_inc_1(dst + 7 * n + 1, cy);
133 } else {
134 lmmp_assert(lmmp_add_n_(dst + 6 * n, dst + 6 * n, w5 + n, w6n));
135 }
136}
static void lmmp_divexact_by15_(mp_ptr dst, mp_srcptr numa, mp_size_t na)
精确除以15([dst,na] = [numa,na] / 15)
Definition divexact.h:85
static void lmmp_divexact_by9_(mp_ptr dst, mp_srcptr numa, mp_size_t na)
精确除以9([dst,na] = [numa,na] / 9)
Definition divexact.h:59
#define LIMB_MAX
Definition lmmp.h:224
#define lmmp_assert(x)
Definition lmmp.h:370
static mp_limb_t lmmp_sub_(mp_ptr dst, mp_srcptr numa, mp_size_t na, mp_srcptr numb, mp_size_t nb)
大数减法静态内联函数 [dst,na]=[numa,na]-[numb,nb]
Definition lmmpn.h:1072
mp_limb_t lmmp_addmul_1_(mp_ptr numa, mp_srcptr numb, mp_size_t n, mp_limb_t b)
大数乘以单limb并累加操作 [numa,n] += [numb,n] * b
mp_limb_t lmmp_submul_1_(mp_ptr numa, mp_srcptr numb, mp_size_t n, mp_limb_t b)
大数乘以单limb并累减操作 [numa,n] -= [numb,n] * b
#define w0
#define w6

引用了 LIMB_MAX, lmmp_add_n_(), lmmp_addmul_1_(), lmmp_assert, lmmp_debug_assert, lmmp_divexact_by15_(), lmmp_divexact_by3_(), lmmp_divexact_by9_(), lmmp_inc_1, lmmp_param_assert, lmmp_shl_(), lmmp_shr1add_n_(), lmmp_shr1sub_n_(), lmmp_shr_(), lmmp_sub_(), lmmp_sub_n_(), lmmp_submul_1_(), toom7_w1_neg, toom7_w3_neg, tp, w0, w2, w3, w5 , 以及 w6.

被这些函数引用 lmmp_mul_toom44_(), lmmp_mul_toom53_(), lmmp_mul_toom62_(), lmmp_mul_toom62_cache_(), lmmp_mul_toom62_cache_init_() , 以及 lmmp_sqr_toom4_().

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