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

浏览源代码.

结构体

struct  fft_cache
 
struct  fft_memstack
 

宏定义

#define _FFT_TABLE_ENTRY(n)   {((mp_size_t)3 << (2 * (n) - 5)) + 1, (n)}
 Copyright (C) 2026 HJimmyK(Jericho Knox)
 
#define _FFT_TABLE_ENTRY4(n)    _FFT_TABLE_ENTRY(n), _FFT_TABLE_ENTRY((n) + 1), _FFT_TABLE_ENTRY((n) + 2), _FFT_TABLE_ENTRY((n) + 3)
 

函数

static void lmmp_fft_ (fft_memstack *ms, mp_ptr *coef, mp_size_t k, mp_size_t w)
 
static void lmmp_fft_4_ (fft_memstack *ms, mp_ptr *coef, mp_size_t k, mp_size_t w)
 
static void lmmp_fft_b1_ (fft_memstack *ms, mp_ptr *coef, mp_size_t dis, mp_size_t k, mp_size_t w, mp_size_t w0)
 FFT递归函数
 
static mp_size_t lmmp_fft_best_k_ (mp_size_t n)
 查找对于 m>=n 的模 B^m+1 FFT运算的最优k值
 
static void lmmp_fft_bfy_ (fft_memstack *ms, mp_ptr *coef, mp_size_t wing, mp_size_t w)
 FFT蝶形运算(Butterfly Operation) (a,b) = (a + b, (a-b) << w ) mod 2^n+1 a=[coef[0],ms->lenw+1], b=[coef[wing],ms->lenw+1], n=ms->lenw * LIMB_BITS
 
static void lmmp_fft_extract_coef_ (mp_ptr dst, mp_srcptr numa, mp_size_t bitoffset, mp_size_t bits, mp_size_t lenw)
 [dst,lenw+1] = [(bit*)numa+bitoffset, bits]
 
static voidlmmp_fft_memstack_ (fft_memstack *ms, mp_size_t size)
 FFT内存栈的分配/释放接口
 
mp_size_t lmmp_fft_next_size_ (mp_size_t n)
 计算FFT运算所需的最小规整化长度(向上取整到2^k的倍数)
 
static void lmmp_fft_shl_coef_ (fft_memstack *ms, mp_ptr *coef, mp_size_t shl)
 对模 2^n+1 的系数执行左移操作
 
static void lmmp_fft_shr_coef_ (fft_memstack *ms, mp_ptr *coef, mp_size_t shr)
 对模 2^n+1 的系数执行右移操作 右移shr位 = 左移(2n - shr)位(mod 2^n+1的循环特性)
 
static void lmmp_ifft_ (fft_memstack *ms, mp_ptr *coef, mp_size_t k, mp_size_t w)
 
static void lmmp_ifft_4_ (fft_memstack *ms, mp_ptr *coef, mp_size_t k, mp_size_t w)
 
static void lmmp_ifft_b1_ (fft_memstack *ms, mp_ptr *coef, mp_size_t dis, mp_size_t k, mp_size_t w, mp_size_t w0)
 
static void lmmp_ifft_bfy_ (fft_memstack *ms, mp_ptr *coef, mp_size_t wing, mp_size_t w)
 FFT蝶形运算(Butterfly Operation) (a,b) = (a+(b>>w), a-(b>>w)) mod 2^n+1 a=[coef[0],ms->lenw+1], b=[coef[wing],ms->lenw+1], n=ms->lenw * LIMB_BITS
 
void lmmp_mul_fermat_ (mp_ptr dst, mp_size_t rn, mp_srcptr numa, mp_size_t na, mp_srcptr numb, mp_size_t nb)
 费马数模乘法 [dst,rn+1]=[numa,na]*[numb,nb] mod B^rn+1
 
static void lmmp_mul_fermat_recombine_ (fft_memstack *ms, mp_ptr dst, mp_ptr *pfca, mp_size_t K, mp_size_t k, mp_size_t n, mp_size_t M, mp_size_t rn)
 费马变换 模 B^n+1 乘法的结果合并
 
static void lmmp_mul_fermat_recurse_ (fft_memstack *ms, mp_ptr *pc1, mp_ptr *pc2, mp_size_t K0)
 费马变换乘法递归函数(核心乘法逻辑)
 
static void lmmp_mul_fermat_single_ (mp_ptr dst, mp_size_t rn, mp_srcptr numa, mp_size_t na, mp_srcptr numb, mp_size_t nb, fft_cache *GH)
 
void lmmp_mul_fft_ (mp_ptr dst, mp_srcptr numa, mp_size_t na, mp_srcptr numb, mp_size_t nb)
 FFT乘法运算 [dst,na+nb] = [numa,na] * [numb,nb]
 
static void lmmp_mul_fft_cache_ (mp_ptr dst, mp_size_t hn, mp_srcptr numa, mp_size_t na, mp_srcptr numb, mp_size_t nb, fft_cache *GH)
 
static void lmmp_mul_fft_cache_free_ (fft_cache *GH)
 
void lmmp_mul_fft_unbalance_ (mp_ptr restrict dst, mp_srcptr restrict numa, mp_size_t na, mp_srcptr restrict numb, mp_size_t nb)
 
void lmmp_mul_mersenne_ (mp_ptr dst, mp_size_t rn, mp_srcptr numa, mp_size_t na, mp_srcptr numb, mp_size_t nb)
 梅森数模乘法 [dst,rn] = [numa,na]*[numb,nb] mod B^rn-1
 
static void lmmp_mul_mersenne_single_ (mp_ptr dst, mp_size_t rn, mp_srcptr numa, mp_size_t na, mp_srcptr numb, mp_size_t nb, fft_cache *GH)
 

变量

static const mp_size_t lmmp_fft_table_ [][2]
 

结构体说明

◆ fft_cache

struct fft_cache

在文件 mul_fft.c857 行定义.

+ fft_cache 的协作图:
成员变量
int fermat_flag
int mersenne_flag
fft_memstack msr_fermat
fft_memstack msr_mersenne
mp_ptr temp_coef_fermat
mp_ptr temp_coef_mersenne

◆ fft_memstack

struct fft_memstack

在文件 mul_fft.c70 行定义.

+ fft_memstack 的协作图:
成员变量
mp_size_t lenw
mp_ssize_t maxdepth
void * mem[16]
mp_size_t memsize[16]
mp_ptr temp_coef
mp_ssize_t tempdepth

宏定义说明

◆ _FFT_TABLE_ENTRY

#define _FFT_TABLE_ENTRY (   n)    {((mp_size_t)3 << (2 * (n) - 5)) + 1, (n)}

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/.

在文件 mul_fft.c23 行定义.

◆ _FFT_TABLE_ENTRY4

#define _FFT_TABLE_ENTRY4 (   n)     _FFT_TABLE_ENTRY(n), _FFT_TABLE_ENTRY((n) + 1), _FFT_TABLE_ENTRY((n) + 2), _FFT_TABLE_ENTRY((n) + 3)

在文件 mul_fft.c24 行定义.

函数说明

◆ lmmp_fft_()

static void lmmp_fft_ ( fft_memstack ms,
mp_ptr coef,
mp_size_t  k,
mp_size_t  w 
)
static

在文件 mul_fft.c453 行定义.

453 {
454 mp_size_t k1 = k >> 1;
455 k -= k1;
456 mp_size_t Kp = ((mp_size_t)1) << k;
457 mp_size_t Kq = ((mp_size_t)1) << k1;
458
459 for (mp_size_t i = 0; i < Kp; ++i) lmmp_fft_b1_(ms, coef + i, Kp, k1, w, i * w);
460
461 for (mp_size_t i = 0; i < Kq; ++i) lmmp_fft_4_(ms, coef + Kp * i, k, w * Kq);
462}
#define k
uint64_t mp_size_t
Definition lmmp.h:77
static void lmmp_fft_b1_(fft_memstack *ms, mp_ptr *coef, mp_size_t dis, mp_size_t k, mp_size_t w, mp_size_t w0)
FFT递归函数
Definition mul_fft.c:411
static void lmmp_fft_4_(fft_memstack *ms, mp_ptr *coef, mp_size_t k, mp_size_t w)
Definition mul_fft.c:432
#define n

引用了 k, lmmp_fft_4_(), lmmp_fft_b1_() , 以及 n.

被这些函数引用 lmmp_mul_fermat_(), lmmp_mul_fermat_recurse_(), lmmp_mul_fermat_single_(), lmmp_mul_mersenne_() , 以及 lmmp_mul_mersenne_single_().

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

◆ lmmp_fft_4_()

static void lmmp_fft_4_ ( fft_memstack ms,
mp_ptr coef,
mp_size_t  k,
mp_size_t  w 
)
static

在文件 mul_fft.c432 行定义.

432 {
433 if (k == 1)
434 lmmp_fft_bfy_(ms, coef, 1, 0);
435 else {
436 k -= 2;
437 mp_size_t Kq = ((mp_size_t)1) << k;
438 for (mp_size_t i = 0; i < Kq; ++i) {
439 lmmp_fft_bfy_(ms, coef + i, Kq * 2, i * w);
440 lmmp_fft_bfy_(ms, coef + i + Kq, Kq * 2, (i + Kq) * w);
441 lmmp_fft_bfy_(ms, coef + i, Kq, 2 * i * w);
442 lmmp_fft_bfy_(ms, coef + i + 2 * Kq, Kq, 2 * i * w);
443 }
444 if (k > 0) {
445 lmmp_fft_4_(ms, coef, k, w * 4);
446 lmmp_fft_4_(ms, coef + Kq, k, w * 4);
447 lmmp_fft_4_(ms, coef + 2 * Kq, k, w * 4);
448 lmmp_fft_4_(ms, coef + 3 * Kq, k, w * 4);
449 }
450 }
451}
static void lmmp_fft_bfy_(fft_memstack *ms, mp_ptr *coef, mp_size_t wing, mp_size_t w)
FFT蝶形运算(Butterfly Operation) (a,b) = (a + b, (a-b) << w ) mod 2^n+1 a=[coef[0],ms->lenw+1],...
Definition mul_fft.c:244

引用了 k, lmmp_fft_4_(), lmmp_fft_bfy_() , 以及 n.

被这些函数引用 lmmp_fft_() , 以及 lmmp_fft_4_().

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

◆ lmmp_fft_b1_()

static void lmmp_fft_b1_ ( fft_memstack ms,
mp_ptr coef,
mp_size_t  dis,
mp_size_t  k,
mp_size_t  w,
mp_size_t  w0 
)
static

FFT递归函数

参数
ms- 内存栈结构体指针
coef- 系数数组指针数组
dis- 索引步长
k- FFT层数(递归深度)
w- 每次蝶形运算的移位基数
w0- 初始移位偏移

在文件 mul_fft.c411 行定义.

411 {
412 if (k == 1)
414 else {
415 k -= 2;
416 mp_size_t Kq = dis << k;
417 for (mp_size_t i = 0; i < Kq; i += dis) {
418 lmmp_fft_bfy_(ms, coef + i, 2 * Kq, i * w + w0);
419 lmmp_fft_bfy_(ms, coef + i + Kq, 2 * Kq, (i + Kq) * w + w0);
420 lmmp_fft_bfy_(ms, coef + i, Kq, 2 * (i * w + w0));
421 lmmp_fft_bfy_(ms, coef + i + Kq * 2, Kq, 2 * (i * w + w0));
422 }
423 if (k > 0) {
424 lmmp_fft_b1_(ms, coef, dis, k, 4 * w, 4 * w0);
425 lmmp_fft_b1_(ms, coef + Kq, dis, k, 4 * w, 4 * w0);
426 lmmp_fft_b1_(ms, coef + Kq * 2, dis, k, 4 * w, 4 * w0);
427 lmmp_fft_b1_(ms, coef + Kq * 3, dis, k, 4 * w, 4 * w0);
428 }
429 }
430}
#define w0

引用了 k, lmmp_fft_b1_(), lmmp_fft_bfy_(), n , 以及 w0.

被这些函数引用 lmmp_fft_() , 以及 lmmp_fft_b1_().

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

◆ lmmp_fft_best_k_()

static mp_size_t lmmp_fft_best_k_ ( mp_size_t  n)
inlinestatic

查找对于 m>=n 的模 B^m+1 FFT运算的最优k值

参数
n- 输入的机器字长度
返回
最优的k值

在文件 mul_fft.c84 行定义.

84 {
85 mp_size_t k = 0;
86 while (n >= lmmp_fft_table_[k + 1][0]) ++k;
87 return lmmp_fft_table_[k][1];
88}
static const mp_size_t lmmp_fft_table_[][2]
Definition mul_fft.c:30

引用了 k, lmmp_fft_table_ , 以及 n.

被这些函数引用 lmmp_fft_next_size_(), lmmp_mul_fermat_(), lmmp_mul_fermat_recurse_(), lmmp_mul_fermat_single_(), lmmp_mul_mersenne_() , 以及 lmmp_mul_mersenne_single_().

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

◆ lmmp_fft_bfy_()

static void lmmp_fft_bfy_ ( fft_memstack ms,
mp_ptr coef,
mp_size_t  wing,
mp_size_t  w 
)
static

FFT蝶形运算(Butterfly Operation) (a,b) = (a + b, (a-b) << w ) mod 2^n+1 a=[coef[0],ms->lenw+1], b=[coef[wing],ms->lenw+1], n=ms->lenw * LIMB_BITS

参数
ms- 内存栈结构体指针
coef- 系数数组指针数组(coef[0]=a, coef[wing]=b)
wing- b的索引
w- 左移的比特数(0<=w<n)
警告
n = ms->lenw * LIMB_BITS a,b 均已伪归一化(mod 2^n+1) ms->temp_coef 有至少 lenw + 1 个字长

在文件 mul_fft.c244 行定义.

244 {
245 mp_ptr numa = coef[0]; // 系数a
246 mp_ptr numb = coef[wing]; // 系数b
247 mp_ptr numc = ms->temp_coef; // 临时数组(存储a-b<<w)
248 mp_size_t shl = w & (LIMB_BITS - 1); // 比特级左移量
249 w /= LIMB_BITS; // 机器字级左移量
250 mp_size_t l = ms->lenw; // 系数长度(机器字)
251
252 mp_slimb_t acyo = 0, scyo = 0, ch;
253 mp_limb_t shlcyo = 0, chp = 0, chn = 0;
254
255 for (mp_size_t off = 0; off < l - w; off += PART_SIZE) {
259 if (shl)
261 }
262
263 ch = shlcyo + (-scyo << shl);
264 if (ch > 0)
265 chp = ch;
266 else
267 chn = -ch;
268
269 scyo = 0;
270 shlcyo = 0;
271
272 for (mp_size_t off = l - w; off < l; off += PART_SIZE) {
274 scyo = lmmp_sub_nc_(numc + off - (l - w), numb + off, numa + off, cursize, scyo);
276 if (shl)
277 shlcyo = lmmp_shl_c_(numc + off - (l - w), numc + off - (l - w), cursize, shl, shlcyo);
278 }
279
280 numc[w] += shlcyo; // 左移进位加到numc[w]
281 scyo = -scyo + numb[l] - numa[l]; // 调整借位(包含最高位)
282 acyo += numa[l] + numb[l]; // 调整进位(包含最高位)
283
284 numa[l] = numa[0] < (mp_limb_t)(acyo);
286
287 numc[l] = 1;
288 ++chn;
289 if (scyo > 0)
290 lmmp_inc_1(numc + w, scyo << shl);
291 else if (scyo < 0) {
292 if (scyo == -2 && shl == LIMB_BITS - 1)
293 lmmp_dec(numc + w + 1);
294 else
295 lmmp_dec_1(numc + w, -scyo << shl);
296 }
297 chp += numc[l];
298
299 if (chn >= chp) {
300 numc[l] = 0;
302 } else {
303 chp -= chn;
304 numc[l] = numc[0] < chp;
305 lmmp_dec_1(numc, chp - numc[l]);
306 }
307
308 coef[wing] = numc;
309 ms->temp_coef = numb;
310}
#define l
mp_limb_t * mp_ptr
Definition lmmp.h:80
int64_t mp_slimb_t
Definition lmmp.h:78
uint64_t mp_limb_t
Definition lmmp.h:76
#define LMMP_MIN(l, o)
Definition lmmp.h:351
#define LIMB_BITS
Definition lmmp.h:86
#define lmmp_dec(p)
大数减1宏(预期无借位)
Definition lmmpn.h:965
mp_limb_t lmmp_shl_c_(mp_ptr dst, mp_srcptr numa, mp_size_t na, mp_size_t shl, mp_limb_t c)
带进位的大数左移操作 [dst,na] = [numa,na]<<shl,dst的低shl位填充c的低shl位
Definition shl.c:42
mp_limb_t lmmp_add_nc_(mp_ptr dst, mp_srcptr numa, mp_srcptr numb, mp_size_t n, mp_limb_t c)
带进位的n位加法 [dst,n] = [numa,n] + [numb,n] + c
Definition add_n.c:19
#define lmmp_dec_1(p, dec)
大数减指定值宏(预期无借位)
Definition lmmpn.h:977
#define lmmp_inc_1(p, inc)
大数加指定值宏(预期无进位)
Definition lmmpn.h:950
mp_limb_t lmmp_sub_nc_(mp_ptr dst, mp_srcptr numa, mp_srcptr numb, mp_size_t n, mp_limb_t c)
带借位的n位减法 [dst,n] = [numa,n] - [numb,n] - c
Definition sub_n.c:19
#define PART_SIZE
Definition mparam.h:89
#define numb

引用了 l, LIMB_BITS, lmmp_add_nc_(), lmmp_dec, lmmp_dec_1, lmmp_inc_1, LMMP_MIN, lmmp_shl_c_(), lmmp_sub_nc_(), n, numb , 以及 PART_SIZE.

被这些函数引用 lmmp_fft_4_() , 以及 lmmp_fft_b1_().

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

◆ lmmp_fft_extract_coef_()

static void lmmp_fft_extract_coef_ ( mp_ptr  dst,
mp_srcptr  numa,
mp_size_t  bitoffset,
mp_size_t  bits,
mp_size_t  lenw 
)
static

[dst,lenw+1] = [(bit*)numa+bitoffset, bits]

参数
dst- 输出系数数组(长度lenw+1)
numa- 输入大数指针
bitoffset- 起始比特偏移量(>=0)
bits- 提取的比特数(0 < bits <= LIMB_BITS*lenw)
lenw- 输出系数的机器字长度
警告
bitoffset>=0, 0<bits<=LIMB_BITS*lenw, sep(dst,numa)

在文件 mul_fft.c135 行定义.

135 {
136 // shr = 机器字内的比特偏移(0~LIMB_BITS-1)
137 // offset = 起始机器字的索引
139
140 mp_size_t lena = (bitoffset + bits - 1) / LIMB_BITS - offset + 1, endp = (bits - 1) / LIMB_BITS;
141
142 if (shr)
144 else
146
147 dst[endp] &= LIMB_MAX >> (-bits & (LIMB_BITS - 1));
148
149 lmmp_zero(dst + endp + 1, lenw - endp);
150}
#define lmmp_copy(dst, src, n)
Definition lmmp.h:367
#define lmmp_zero(dst, n)
Definition lmmp.h:369
#define LIMB_MAX
Definition lmmp.h:89
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:19

引用了 LIMB_BITS, LIMB_MAX, lmmp_copy, lmmp_shr_(), lmmp_zero , 以及 n.

被这些函数引用 lmmp_mul_fermat_(), lmmp_mul_fermat_recurse_(), lmmp_mul_fermat_single_(), lmmp_mul_mersenne_() , 以及 lmmp_mul_mersenne_single_().

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

◆ lmmp_fft_memstack_()

static void * lmmp_fft_memstack_ ( fft_memstack ms,
mp_size_t  size 
)
static

FFT内存栈的分配/释放接口

参数
ms- 内存栈结构体栈帧
size- 分配大小(字节),size=0表示释放当前层内存
返回
分配成功:返回mp_ptr*;释放:返回0

在文件 mul_fft.c109 行定义.

109 {
110 if (size) {
111 if (++ms->tempdepth > ms->maxdepth) {
112 ms->mem[++ms->maxdepth] = lmmp_alloc(size);
113 ms->memsize[ms->maxdepth] = size;
114 }
115 lmmp_debug_assert(ms->memsize[ms->tempdepth] == size);
116 return ms->mem[ms->tempdepth];
117 } else {
118 if (--ms->tempdepth < 0) {
119 for (mp_size_t i = 0; i <= (mp_size_t)(ms->maxdepth); ++i) lmmp_free(ms->mem[i]);
120 ms->maxdepth = -1;
121 }
122 return 0;
123 }
124}
#define lmmp_debug_assert(x)
Definition lmmp.h:390
void * lmmp_alloc(size_t size)
内存分配函数(调用lmmp_heap_alloc_fn)
Definition memory.c:164
void lmmp_free(void *ptr)
内存释放函数(调用lmmp_heap_free_fn)
Definition memory.c:202

引用了 lmmp_alloc(), lmmp_debug_assert, lmmp_free() , 以及 n.

被这些函数引用 lmmp_mul_fermat_(), lmmp_mul_fermat_recurse_(), lmmp_mul_fermat_single_(), lmmp_mul_fft_cache_free_(), lmmp_mul_mersenne_() , 以及 lmmp_mul_mersenne_single_().

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

◆ lmmp_fft_next_size_()

mp_size_t lmmp_fft_next_size_ ( mp_size_t  n)

计算FFT运算所需的最小规整化长度(向上取整到2^k的倍数)

计算满足 >=n 的最小费马/梅森乘法可行尺寸

参数
n- 原始长度
返回
规整后的长度(为2^k的倍数)

在文件 mul_fft.c95 行定义.

95 {
99 n = (((n - 1) >> k) + 1) << k;
100 return n;
101}
#define LOG2_LIMB_BITS
Definition lmmp.h:88
static mp_size_t lmmp_fft_best_k_(mp_size_t n)
查找对于 m>=n 的模 B^m+1 FFT运算的最优k值
Definition mul_fft.c:84

引用了 k, lmmp_debug_assert, lmmp_fft_best_k_(), LOG2_LIMB_BITS , 以及 n.

被这些函数引用 binvert_mulhi_(), lmmp_div_mulinv_(), lmmp_invappr_newton_(), lmmp_invsqrt_newton_(), lmmp_mul_fft_(), lmmp_mul_fft_unbalance_(), lmmp_mulhi_n_() , 以及 lmmp_mullo_fft_().

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

◆ lmmp_fft_shl_coef_()

static void lmmp_fft_shl_coef_ ( fft_memstack ms,
mp_ptr coef,
mp_size_t  shl 
)
static

对模 2^n+1 的系数执行左移操作

参数
ms- 内存栈结构体指针
coef- 输入输出系数数组指针(指针的指针,用于交换内存)
shl- 左移的比特数(0<shl<2*n)
警告
n = ms->lenw * LIMB_BITS *coef 已伪归一化(mod 2^n+1) ms->temp_coef 至少有 lenw+1 个机器字

在文件 mul_fft.c161 行定义.

161 {
162 mp_size_t l = ms->lenw; // 系数的机器字长度
163 mp_size_t w = shl / LIMB_BITS; // 左移的机器字数量
164 shl &= LIMB_BITS - 1; // 剩余的比特偏移(0~LIMB_BITS-1)
165 mp_ptr src = *coef; // 源系数数组
166 mp_ptr dst = ms->temp_coef; // 目标临时数组
167 mp_limb_t cc, rd; // 进位变量(cc=carry, rd=read)
168
169 if (w >= l) {
170 w -= l;
171 if (shl) {
172 lmmp_shl_(dst, src + l - w, w + 1, shl);
173 rd = dst[w];
174 cc = lmmp_shlnot_(dst + w, src, l - w, shl);
175 } else {
176 if (w)
177 lmmp_copy(dst, src + l - w, w);
178 rd = src[l];
179 lmmp_not_(dst + w, src, l - w);
180 cc = 0;
181 }
182 dst[l] = 0;
183 ++cc;
184 lmmp_inc_1(dst, cc);
185
186 if (++rd == 0)
187 lmmp_inc(dst + w + 1);
188 else
189 lmmp_inc_1(dst + w, rd);
190 } else {
191 if (shl) {
192 lmmp_shlnot_(dst, src + l - w, w + 1, shl);
193 rd = ~dst[w];
194 cc = lmmp_shl_(dst + w, src, l - w, shl);
195 } else {
196 if (w)
197 lmmp_not_(dst, src + l - w, w);
198 rd = src[l];
199
200 lmmp_copy(dst + w, src, l - w);
201 cc = 0;
202 }
203 dst[l] = 2;
204 lmmp_inc_1(dst, 3);
205 lmmp_dec_1(dst, cc);
206
207 if (++rd == 0)
208 lmmp_dec(dst + w + 1);
209 else
210 lmmp_dec_1(dst + w, rd);
211
212 cc = dst[l];
213 dst[l] = dst[0] < cc;
214 lmmp_dec_1(dst, cc - dst[l]);
215 }
216
217 ms->temp_coef = src;
218 *coef = dst;
219}
mp_limb_t lmmp_shlnot_(mp_ptr dst, mp_srcptr numa, mp_size_t na, mp_size_t shl)
左移后按位取反操作 [dst,na] = ~([numa,na] << shl),dst的低shl位填充1
#define lmmp_inc(p)
大数加1宏(预期无进位)
Definition lmmpn.h:938
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:19
void lmmp_not_(mp_ptr dst, mp_srcptr numa, mp_size_t na)
大数按位取反操作 [dst,na] = ~[numa,na] (对每个limb执行按位非操作)

引用了 l, LIMB_BITS, lmmp_copy, lmmp_dec, lmmp_dec_1, lmmp_inc, lmmp_inc_1, lmmp_not_(), lmmp_shl_(), lmmp_shlnot_() , 以及 n.

被这些函数引用 lmmp_fft_shr_coef_(), lmmp_mul_fermat_(), lmmp_mul_fermat_recurse_() , 以及 lmmp_mul_fermat_single_().

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

◆ lmmp_fft_shr_coef_()

static void lmmp_fft_shr_coef_ ( fft_memstack ms,
mp_ptr coef,
mp_size_t  shr 
)
static

对模 2^n+1 的系数执行右移操作 右移shr位 = 左移(2n - shr)位(mod 2^n+1的循环特性)

参数
ms- 内存栈结构体指针
coef- 输入输出系数数组指针
shr- 右移的比特数(0 < shr < 2*n)

在文件 mul_fft.c228 行定义.

228 {
229 lmmp_fft_shl_coef_(ms, coef, 2 * ms->lenw * LIMB_BITS - shr);
230}
static void lmmp_fft_shl_coef_(fft_memstack *ms, mp_ptr *coef, mp_size_t shl)
对模 2^n+1 的系数执行左移操作
Definition mul_fft.c:161

引用了 LIMB_BITS, lmmp_fft_shl_coef_() , 以及 n.

被这些函数引用 lmmp_mul_fermat_recombine_(), lmmp_mul_mersenne_() , 以及 lmmp_mul_mersenne_single_().

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

◆ lmmp_ifft_()

static void lmmp_ifft_ ( fft_memstack ms,
mp_ptr coef,
mp_size_t  k,
mp_size_t  w 
)
static

在文件 mul_fft.c506 行定义.

506 {
507 mp_size_t k1 = k >> 1;
508 k -= k1;
509 mp_size_t Kp = ((mp_size_t)1) << k;
510 mp_size_t Kq = ((mp_size_t)1) << k1;
511
512 for (mp_size_t i = 0; i < Kq; ++i) lmmp_ifft_4_(ms, coef + Kp * i, k, w * Kq);
513
514 for (mp_size_t i = 0; i < Kp; ++i) lmmp_ifft_b1_(ms, coef + i, Kp, k1, w, i * w);
515}
static void lmmp_ifft_b1_(fft_memstack *ms, mp_ptr *coef, mp_size_t dis, mp_size_t k, mp_size_t w, mp_size_t w0)
Definition mul_fft.c:464
static void lmmp_ifft_4_(fft_memstack *ms, mp_ptr *coef, mp_size_t k, mp_size_t w)
Definition mul_fft.c:485

引用了 k, lmmp_ifft_4_(), lmmp_ifft_b1_() , 以及 n.

被这些函数引用 lmmp_mul_fermat_(), lmmp_mul_fermat_recurse_(), lmmp_mul_fermat_single_(), lmmp_mul_mersenne_() , 以及 lmmp_mul_mersenne_single_().

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

◆ lmmp_ifft_4_()

static void lmmp_ifft_4_ ( fft_memstack ms,
mp_ptr coef,
mp_size_t  k,
mp_size_t  w 
)
static

在文件 mul_fft.c485 行定义.

485 {
486 if (k == 1)
487 lmmp_ifft_bfy_(ms, coef, 1, 0);
488 else {
489 k -= 2;
490 mp_size_t Kq = ((mp_size_t)1) << k;
491 if (k > 0) {
492 lmmp_ifft_4_(ms, coef, k, w * 4);
493 lmmp_ifft_4_(ms, coef + Kq, k, w * 4);
494 lmmp_ifft_4_(ms, coef + 2 * Kq, k, w * 4);
495 lmmp_ifft_4_(ms, coef + 3 * Kq, k, w * 4);
496 }
497 for (mp_size_t i = 0; i < Kq; ++i) {
498 lmmp_ifft_bfy_(ms, coef + i, Kq, 2 * i * w);
499 lmmp_ifft_bfy_(ms, coef + i + 2 * Kq, Kq, 2 * i * w);
500 lmmp_ifft_bfy_(ms, coef + i, Kq * 2, i * w);
501 lmmp_ifft_bfy_(ms, coef + i + Kq, Kq * 2, (i + Kq) * w);
502 }
503 }
504}
static void lmmp_ifft_bfy_(fft_memstack *ms, mp_ptr *coef, mp_size_t wing, mp_size_t w)
FFT蝶形运算(Butterfly Operation) (a,b) = (a+(b>>w), a-(b>>w)) mod 2^n+1 a=[coef[0],ms->lenw+1],...
Definition mul_fft.c:324

引用了 k, lmmp_ifft_4_(), lmmp_ifft_bfy_() , 以及 n.

被这些函数引用 lmmp_ifft_() , 以及 lmmp_ifft_4_().

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

◆ lmmp_ifft_b1_()

static void lmmp_ifft_b1_ ( fft_memstack ms,
mp_ptr coef,
mp_size_t  dis,
mp_size_t  k,
mp_size_t  w,
mp_size_t  w0 
)
static

在文件 mul_fft.c464 行定义.

464 {
465 if (k == 1)
467 else {
468 k -= 2;
469 mp_size_t Kq = dis << k;
470 if (k > 0) {
471 lmmp_ifft_b1_(ms, coef, dis, k, 4 * w, 4 * w0);
472 lmmp_ifft_b1_(ms, coef + Kq, dis, k, 4 * w, 4 * w0);
473 lmmp_ifft_b1_(ms, coef + Kq * 2, dis, k, 4 * w, 4 * w0);
474 lmmp_ifft_b1_(ms, coef + Kq * 3, dis, k, 4 * w, 4 * w0);
475 }
476 for (mp_size_t i = 0; i < Kq; i += dis) {
477 lmmp_ifft_bfy_(ms, coef + i, Kq, 2 * (i * w + w0));
478 lmmp_ifft_bfy_(ms, coef + i + Kq * 2, Kq, 2 * (i * w + w0));
479 lmmp_ifft_bfy_(ms, coef + i, 2 * Kq, i * w + w0);
480 lmmp_ifft_bfy_(ms, coef + i + Kq, 2 * Kq, (i + Kq) * w + w0);
481 }
482 }
483}

引用了 k, lmmp_ifft_b1_(), lmmp_ifft_bfy_(), n , 以及 w0.

被这些函数引用 lmmp_ifft_() , 以及 lmmp_ifft_b1_().

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

◆ lmmp_ifft_bfy_()

static void lmmp_ifft_bfy_ ( fft_memstack ms,
mp_ptr coef,
mp_size_t  wing,
mp_size_t  w 
)
static

FFT蝶形运算(Butterfly Operation) (a,b) = (a+(b>>w), a-(b>>w)) mod 2^n+1 a=[coef[0],ms->lenw+1], b=[coef[wing],ms->lenw+1], n=ms->lenw * LIMB_BITS

参数
ms- 内存栈结构体指针
coef- 系数数组指针数组(coef[0]=a, coef[wing]=b)
wing- b的索引
w- 左移的比特数(0<=w<n)
警告
n = ms->lenw * LIMB_BITS a,b 均已伪归一化(mod 2^n+1) ms->temp_coef 有至少 lenw + 1 个字长

在文件 mul_fft.c324 行定义.

324 {
325 mp_ptr numa = coef[0];
326 mp_ptr numb = coef[wing];
327 mp_ptr numc = ms->temp_coef;
328 mp_size_t shr = w & (LIMB_BITS - 1);
329 w /= LIMB_BITS;
330 mp_size_t l = ms->lenw;
331
332 mp_slimb_t bcyo = 0, acyo = 0, ah;
333 mp_limb_t shrcyo = shr ? numb[0] << (LIMB_BITS - shr) : 0;
334
335 for (mp_size_t off = l - w; off < l; off += PART_SIZE) {
337 if (shr)
338 lmmp_shr_c_(numb + off - (l - w), numb + off - (l - w), cursize, shr,
339 numb[off - (l - w) + cursize] << (LIMB_BITS - shr));
340 bcyo = lmmp_add_nc_(numc + off, numa + off, numb + off - (l - w), cursize, bcyo);
341 acyo = lmmp_sub_nc_(numa + off, numa + off, numb + off - (l - w), cursize, acyo);
342 }
343
344 for (mp_size_t off = 0; off < l - w; off += PART_SIZE) {
346 if (shr)
347 lmmp_shr_c_(numb + w + off, numb + w + off, cursize, shr, numb[off + w + cursize] << (LIMB_BITS - shr));
350 }
351
352 acyo += numb[l] >> shr;
353 bcyo = -bcyo - (numb[l] >> shr);
354
355 acyo -= numa[l - w - 1] < shrcyo;
356 numa[l - w - 1] -= shrcyo;
357 numc[l - w - 1] += shrcyo;
358 bcyo += numc[l - w - 1] < shrcyo;
359
360 ah = numa[l];
361
362 numa[l] += 1;
363 if (w == 0)
364 numa[l] += acyo;
365 else {
366 if (acyo < 0)
367 lmmp_dec(numa + l - w);
368 else
369 lmmp_inc_1(numa + l - w, acyo);
370 }
371 acyo = numa[l] - 1;
372 if (acyo < 0) {
373 numa[l] = 0;
374 lmmp_inc(numa);
375 } else {
376 numa[l] = numa[0] < (mp_limb_t)acyo;
378 }
379
380 numc[l] = ah + 2;
381 if (w == 0)
382 numc[l] += bcyo;
383 else {
384 if (bcyo > 0)
385 lmmp_inc(numc + l - w);
386 else
387 lmmp_dec_1(numc + l - w, -bcyo);
388 }
389 bcyo = numc[l] - 2;
390 if (bcyo <= 0) {
391 numc[l] = 0;
393 } else {
394 numc[l] = numc[0] < (mp_limb_t)bcyo;
396 }
397
398 coef[wing] = numc;
399 ms->temp_coef = numb;
400}
mp_limb_t lmmp_shr_c_(mp_ptr dst, mp_srcptr numa, mp_size_t na, mp_size_t shr, mp_limb_t c)
带进位的大数右移操作 [dst,na] = [numa,na]>>shr,dst的高shr位填充c的高shr位
Definition shr.c:40

引用了 l, LIMB_BITS, lmmp_add_nc_(), lmmp_dec, lmmp_dec_1, lmmp_inc, lmmp_inc_1, LMMP_MIN, lmmp_shr_c_(), lmmp_sub_nc_(), n, numb , 以及 PART_SIZE.

被这些函数引用 lmmp_ifft_4_() , 以及 lmmp_ifft_b1_().

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

◆ lmmp_mul_fermat_()

void lmmp_mul_fermat_ ( mp_ptr  dst,
mp_size_t  rn,
mp_srcptr  numa,
mp_size_t  na,
mp_srcptr  numb,
mp_size_t  nb 
)

费马数模乘法 [dst,rn+1]=[numa,na]*[numb,nb] mod B^rn+1

参数
dst输出结果缓冲区,长度至少为 rn+1
rn模运算的阶数参数,rn = lmmp_fft_next_size_((na + nb + 1) >> 1)
numa第一个输入操作数,长度为 na
na第一个操作数的 limb 长度
numb第二个输入操作数,长度为 nb
nb第二个操作数的 limb 长度
警告
eqsep(dst,[numa|numb]), 0<=[numa,na]<2*B^rn, 0<=[numb,nb]<2*B^rn, rn = lmmp_fft_next_size_((na+nb+1)>>1)
返回
无返回值,结果存储在dst中

在文件 mul_fft.c687 行定义.

687 {
688 int nsqr = numa != numb || na != nb; // 判断是否为平方运算
689 mp_size_t N = rn * LIMB_BITS; // 结果总比特数
691 mp_size_t K = ((mp_size_t)1) << k; // FFT块数(2^k)
692 lmmp_debug_assert(!(N & (K - 1)));
693 mp_size_t M = N >> k; // 每个块的比特数
694 mp_size_t n = 2 * M + k + 2; // 扩展系数长度
695
696 n = (n + LIMB_BITS - 1) & (-LIMB_BITS);
697 n = (((n - 1) >> k) + 1) << k;
698
699 // 初始化内存栈
701 msr.maxdepth = -1;
702 msr.tempdepth = -1;
703 msr.lenw = n / LIMB_BITS;
704 mp_size_t nlen = msr.lenw + 1;
705
706 msr.temp_coef = (mp_ptr)lmmp_fft_memstack_(&msr, (((nlen + 1) << (k + nsqr)) + nlen) * LIMB_BYTES);
707
708 mp_ptr *pfca = (mp_ptr*)(msr.temp_coef + nlen), *pfcb = pfca;
710
711 for (mp_size_t i = 0; i < K; ++i) {
713 pfca[i] = (mp_ptr)(pfca + K) + i * nlen;
714 if (narest > 0) {
715 coeflen = M + (i == K - 1);
717 narest -= coeflen;
719 if (i > 0)
720 lmmp_fft_shl_coef_(&msr, pfca + i, i * n >> k);
721 } else {
722 lmmp_zero(pfca[i], nlen);
723 }
724 }
725 lmmp_fft_(&msr, pfca, k, n >> (k - 1));
726
727 if (nsqr) {
728 pfcb += (nlen + 1) << k;
729 for (mp_size_t i = 0; i < K; ++i) {
731 pfcb[i] = (mp_ptr)(pfcb + K) + i * nlen;
732 if (nbrest > 0) {
733 coeflen = M + (i == K - 1);
735 nbrest -= coeflen;
737 if (i > 0)
738 lmmp_fft_shl_coef_(&msr, pfcb + i, i * n >> k);
739 } else {
740 lmmp_zero(pfcb[i], nlen);
741 }
742 }
743 lmmp_fft_(&msr, pfcb, k, n >> (k - 1));
744 }
745
747
748 lmmp_ifft_(&msr, pfca, k, n >> (k - 1));
749
751
752 // 处理模 B^rn+1 的溢出
753 if (dst[rn] && !lmmp_zero_q_(dst, rn)) {
754 dst[rn] = 0;
755 lmmp_dec(dst);
756 }
757
759}
static int lmmp_zero_q_(mp_srcptr p, mp_size_t n)
大数判零函数(内联)
Definition lmmpn.h:1019
#define LIMB_BYTES
Definition mparam.h:85
mp_ssize_t maxdepth
Definition mul_fft.c:73
static void lmmp_mul_fermat_recurse_(fft_memstack *ms, mp_ptr *pc1, mp_ptr *pc2, mp_size_t K0)
费马变换乘法递归函数(核心乘法逻辑)
Definition mul_fft.c:611
static void lmmp_fft_(fft_memstack *ms, mp_ptr *coef, mp_size_t k, mp_size_t w)
Definition mul_fft.c:453
static void * lmmp_fft_memstack_(fft_memstack *ms, mp_size_t size)
FFT内存栈的分配/释放接口
Definition mul_fft.c:109
static void lmmp_mul_fermat_recombine_(fft_memstack *ms, mp_ptr dst, mp_ptr *pfca, mp_size_t K, mp_size_t k, mp_size_t n, mp_size_t M, mp_size_t rn)
费马变换 模 B^n+1 乘法的结果合并
Definition mul_fft.c:528
static void lmmp_ifft_(fft_memstack *ms, mp_ptr *coef, mp_size_t k, mp_size_t w)
Definition mul_fft.c:506
static void lmmp_fft_extract_coef_(mp_ptr dst, mp_srcptr numa, mp_size_t bitoffset, mp_size_t bits, mp_size_t lenw)
[dst,lenw+1] = [(bit*)numa+bitoffset, bits]
Definition mul_fft.c:135

引用了 k, LIMB_BITS, LIMB_BYTES, lmmp_debug_assert, lmmp_dec, lmmp_fft_(), lmmp_fft_best_k_(), lmmp_fft_extract_coef_(), lmmp_fft_memstack_(), lmmp_fft_shl_coef_(), lmmp_ifft_(), LMMP_MIN, lmmp_mul_fermat_recombine_(), lmmp_mul_fermat_recurse_(), lmmp_zero, lmmp_zero_q_(), fft_memstack::maxdepth, n , 以及 numb.

被这些函数引用 lmmp_mul_fft_() , 以及 lmmp_mullo_fft_().

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

◆ lmmp_mul_fermat_recombine_()

static void lmmp_mul_fermat_recombine_ ( fft_memstack ms,
mp_ptr  dst,
mp_ptr pfca,
mp_size_t  K,
mp_size_t  k,
mp_size_t  n,
mp_size_t  M,
mp_size_t  rn 
)
static

费马变换 模 B^n+1 乘法的结果合并

参数
ms- 内存栈结构体指针
dst- 输出结果数组
pfca- FFT系数数组指针数组
K- FFT块数(2^k)
k- FFT层数
n- 系数总比特数
M- 每个块的比特数
rn- 结果长度(机器字)

在文件 mul_fft.c528 行定义.

537 {
538 mp_size_t rhead = 0, nlen = ms->lenw + 1;
539 mp_slimb_t borrow = 0, maxc = 0;
540
541 for (mp_size_t i = 0; i < K; ++i) {
542 lmmp_fft_shr_coef_(ms, pfca + i, (i * n >> k) + k);
543 mp_ptr nums = pfca[i];
544
545 if (nums[nlen - 1]) {
546 lmmp_dec(nums);
547 --nums[nlen - 1];
548 }
549 if (nums[nlen - 1] == 0 && nums[nlen - 2] >> (LIMB_BITS - 1)) {
550 lmmp_dec(nums);
551 --nums[nlen - 1];
552 }
553
554 if (borrow) {
555 mp_size_t brshift = borrow - 1 + n - M;
558 --nums[nlen - 1];
560 ++nums[nlen - 1];
561 }
562 borrow = -nums[nlen - 1];
563 nums[nlen - 1] = 0;
564
565 mp_size_t roffset = i * M;
566 mp_size_t shl = roffset & (LIMB_BITS - 1);
568
569 if (shl)
571
572 if (i == 0) {
574 rhead = nlen;
575 } else if (roffset + nlen <= rn) {
577 rhead = roffset + nlen;
578 } else {
580 maxc -= lmmp_sub_(dst, dst, rn, nums + rn - roffset, nlen + roffset - rn);
581 rhead = rn;
582 }
583 }
584
585 if (borrow) {
586 mp_size_t cyshift = borrow - 1 + n - M;
590 }
591
592 if (maxc > 0) {
593 dst[rn] = dst[0] < (mp_limb_t)maxc;
594 lmmp_dec_1(dst, maxc - dst[rn]);
595 } else {
596 dst[rn] = 0;
598 }
599}
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:1050
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:1103
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:1064
static void lmmp_fft_shr_coef_(fft_memstack *ms, mp_ptr *coef, mp_size_t shr)
对模 2^n+1 的系数执行右移操作 右移shr位 = 左移(2n - shr)位(mod 2^n+1的循环特性)
Definition mul_fft.c:228

引用了 k, LIMB_BITS, lmmp_add_(), lmmp_add_1_(), lmmp_copy, lmmp_dec, lmmp_dec_1, lmmp_fft_shr_coef_(), lmmp_inc_1, lmmp_shl_(), lmmp_sub_() , 以及 n.

被这些函数引用 lmmp_mul_fermat_(), lmmp_mul_fermat_recurse_() , 以及 lmmp_mul_fermat_single_().

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

◆ lmmp_mul_fermat_recurse_()

static void lmmp_mul_fermat_recurse_ ( fft_memstack ms,
mp_ptr pc1,
mp_ptr pc2,
mp_size_t  K0 
)
static

费马变换乘法递归函数(核心乘法逻辑)

参数
ms- 内存栈结构体指针
pc1- 第一个数的FFT系数数组指针数组
pc2- 第二个数的FFT系数数组指针数组
K0- FFT块数
警告
K0>0 所有系数均已伪归一化(mod B^lenw+1) nsqr=1表示乘法,nsqr=0表示平方

在文件 mul_fft.c611 行定义.

611 {
612 int nsqr = pc1 != pc2;
613 mp_ptr push_temp_coef = ms->temp_coef;
614 mp_size_t rn = ms->lenw;
615
618 for (mp_size_t i = 0; i < K0; ++i) {
619 if (nsqr)
620 lmmp_mul_n_(temp_mul, pc1[i], pc2[i], rn + 1);
621 else
622 lmmp_sqr_(temp_mul, pc1[i], rn + 1);
623
624 // 模 B^rn+1 归一化:temp_mul - temp_mul[rn ...]
626 pc1[i][rn] = 0;
627 lmmp_inc_1(pc1[i], maxc);
628 }
630 } else {
631 mp_size_t N = rn * LIMB_BITS; // 总比特数
633 mp_size_t K = ((mp_size_t)1) << k; // FFT块数(2^k)
634 lmmp_debug_assert(!(N & (K - 1)));
635 mp_size_t M = N >> k; // 每个块的比特数(N/K)
636 mp_size_t n = 2 * M + k + 2; // 扩展系数长度(保证归一化)
637
638 // 规整n:必须是LIMB_BITS和K的整数倍
639 n = (n + LIMB_BITS - 1) & (-LIMB_BITS);
640 n = (((n - 1) >> k) + 1) << k;
641
642 ms->lenw = n / LIMB_BITS;
643 mp_size_t nlen = ms->lenw + 1;
644
645 ms->temp_coef = (mp_ptr)lmmp_fft_memstack_(ms, (((nlen + 1) << (k + nsqr)) + nlen) * LIMB_BYTES);
646 mp_ptr *pfca = (mp_ptr*)(ms->temp_coef + nlen), *pfcb = pfca;
647 for (mp_size_t i = 0; i < K; ++i) pfca[i] = (mp_ptr)(pfca + K) + i * nlen;
648 if (nsqr) {
649 pfcb += (nlen + 1) << k;
650 for (mp_size_t i = 0; i < K; ++i) pfcb[i] = (mp_ptr)(pfcb + K) + i * nlen;
651 }
652
653 for (mp_size_t j = 0; j < K0; ++j) {
654 mp_ptr numa = pc1[j];
655 mp_ptr numb = pc2[j];
656
657 for (mp_size_t i = 0; i < K; ++i) {
658 lmmp_fft_extract_coef_(pfca[i], numa, M * i, M + (i == K - 1), ms->lenw);
659 if (i > 0)
660 lmmp_fft_shl_coef_(ms, pfca + i, i * n >> k);
661 }
662 lmmp_fft_(ms, pfca, k, n >> (k - 1));
663
664 if (nsqr) {
665 for (mp_size_t i = 0; i < K; ++i) {
666 lmmp_fft_extract_coef_(pfcb[i], numb, M * i, M + (i == K - 1), ms->lenw);
667 if (i > 0)
668 lmmp_fft_shl_coef_(ms, pfcb + i, i * n >> k);
669 }
670 lmmp_fft_(ms, pfcb, k, n >> (k - 1));
671 }
672
673 // dot product
675
676 lmmp_ifft_(ms, pfca, k, n >> (k - 1));
677
679 }
681 }
682
683 ms->temp_coef = push_temp_coef;
684 ms->lenw = rn;
685}
#define lmmp_mul_n_
Definition inlines.h:167
#define lmmp_sqr_
Definition inlines.h:166
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:80
#define MUL_FFT_MODF_THRESHOLD
Definition mparam.h:65

引用了 k, LIMB_BITS, LIMB_BYTES, lmmp_debug_assert, lmmp_fft_(), lmmp_fft_best_k_(), lmmp_fft_extract_coef_(), lmmp_fft_memstack_(), lmmp_fft_shl_coef_(), lmmp_ifft_(), lmmp_inc_1, lmmp_mul_fermat_recombine_(), lmmp_mul_fermat_recurse_(), lmmp_mul_n_, lmmp_sqr_, lmmp_sub_n_(), MUL_FFT_MODF_THRESHOLD, n , 以及 numb.

被这些函数引用 lmmp_mul_fermat_(), lmmp_mul_fermat_recurse_(), lmmp_mul_fermat_single_(), lmmp_mul_mersenne_() , 以及 lmmp_mul_mersenne_single_().

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

◆ lmmp_mul_fermat_single_()

static void lmmp_mul_fermat_single_ ( mp_ptr  dst,
mp_size_t  rn,
mp_srcptr  numa,
mp_size_t  na,
mp_srcptr  numb,
mp_size_t  nb,
fft_cache GH 
)
static

在文件 mul_fft.c878 行定义.

886 {
887 mp_size_t N = rn * LIMB_BITS; // 结果总比特数
889 mp_size_t K = ((mp_size_t)1) << k; // FFT块数(2^k)
890 lmmp_debug_assert(!(N & (K - 1)));
891 mp_size_t M = N >> k; // 每个块的比特数
892 mp_size_t n = 2 * M + k + 2; // 扩展系数长度
893
894 n = (n + LIMB_BITS - 1) & (-LIMB_BITS);
895 n = (((n - 1) >> k) + 1) << k;
896
899 amsr.maxdepth = -1;
900 amsr.tempdepth = -1;
901 amsr.lenw = n / LIMB_BITS;
902 mp_size_t nlen = amsr.lenw + 1;
903 mp_size_t a_size = (((nlen + 1) << (k)) + nlen) * LIMB_BYTES;
904 mp_size_t b_size = (((nlen + 1) << (k)) + nlen) * LIMB_BYTES;
905 amsr.temp_coef = (mp_ptr)lmmp_fft_memstack_(&amsr, a_size);
906
907 mp_ptr* pfca = (mp_ptr*)(amsr.temp_coef + nlen);
908 mp_ptr* pfcb = NULL;
909
910 if (GH->fermat_flag) {
911 bmsr = &GH->msr_fermat;
912 bmsr->lenw = n / LIMB_BITS;
913 pfcb = (mp_ptr*)(GH->temp_coef_fermat + nlen);
914 } else {
915 bmsr = &GH->msr_fermat;
916 bmsr->maxdepth = -1;
917 bmsr->tempdepth = -1;
918 bmsr->lenw = n / LIMB_BITS;
919 bmsr->temp_coef = (mp_ptr)lmmp_fft_memstack_(bmsr, b_size);
920 GH->temp_coef_fermat = bmsr->temp_coef;
921 pfcb = (mp_ptr*)(bmsr->temp_coef + nlen);
922 }
923
925 for (mp_size_t i = 0; i < K; ++i) {
927 pfca[i] = (mp_ptr)(pfca + K) + i * nlen;
928 if (narest > 0) {
929 coeflen = M + (i == K - 1);
931 narest -= coeflen;
933 if (i > 0)
934 lmmp_fft_shl_coef_(&amsr, pfca + i, i * n >> k);
935 } else {
936 lmmp_zero(pfca[i], nlen);
937 }
938 }
939 lmmp_fft_(&amsr, pfca, k, n >> (k - 1));
940
941 if (!GH->fermat_flag) {
942 GH->fermat_flag = 1;
943 for (mp_size_t i = 0; i < K; ++i) {
945 pfcb[i] = (mp_ptr)(pfcb + K) + i * nlen;
946 if (nbrest > 0) {
947 coeflen = M + (i == K - 1);
949 nbrest -= coeflen;
951 if (i > 0)
952 lmmp_fft_shl_coef_(bmsr, pfcb + i, i * n >> k);
953 } else {
954 lmmp_zero(pfcb[i], nlen);
955 }
956 }
957 lmmp_fft_(bmsr, pfcb, k, n >> (k - 1));
958 }
959
961
962 lmmp_ifft_(&amsr, pfca, k, n >> (k - 1));
963
965
966 if (dst[rn] && !lmmp_zero_q_(dst, rn)) {
967 dst[rn] = 0;
968 lmmp_dec(dst);
969 }
970
972}

引用了 k, LIMB_BITS, LIMB_BYTES, lmmp_debug_assert, lmmp_dec, lmmp_fft_(), lmmp_fft_best_k_(), lmmp_fft_extract_coef_(), lmmp_fft_memstack_(), lmmp_fft_shl_coef_(), lmmp_ifft_(), LMMP_MIN, lmmp_mul_fermat_recombine_(), lmmp_mul_fermat_recurse_(), lmmp_zero, lmmp_zero_q_(), fft_memstack::maxdepth, n , 以及 numb.

被这些函数引用 lmmp_mul_fft_cache_().

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

◆ lmmp_mul_fft_()

void lmmp_mul_fft_ ( mp_ptr  dst,
mp_srcptr  numa,
mp_size_t  na,
mp_srcptr  numb,
mp_size_t  nb 
)

FFT乘法运算 [dst,na+nb] = [numa,na] * [numb,nb]

参数
dst输出结果缓冲区,长度至少为 na+nb
numa第一个输入操作数,长度为 na
na第一个操作数的 limb 长度
numb第二个输入操作数,长度为 nb
nb第二个操作数的 limb 长度
警告
???<=nb<=na, sep(dst,[numa|numb])
返回
无返回值,结果存储在dst中

在文件 mul_fft.c1095 行定义.

1095 {
1096 lmmp_param_assert(na > 0 && nb > 0);
1098 mp_size_t hn = lmmp_fft_next_size_((na + nb + 1) >> 1);
1099 lmmp_assert(na + nb > hn);
1101
1103 mp_size_t nam = na;
1104 if (na > hn) {
1105 /*
1106 Z = B^hb - 1
1107 amodm = a mod Z
1108 */
1109 if (lmmp_add_(dst, numa, hn, numa + hn, na - hn))
1110 lmmp_inc(dst);
1111 amodm = dst;
1112 nam = hn;
1113 }
1115
1117 mp_size_t nap = na;
1118 if (na > hn) {
1119 /*
1120 Z = B^hp - 1
1121 amodp = a mod Z
1122 */
1123 tp[hn] = 0;
1124 if (lmmp_sub_(tp, numa, hn, numa + hn, na - hn))
1125 lmmp_inc(tp);
1126 amodp = tp;
1127 nap = hn + 1;
1128 }
1130
1132 cy <<= LIMB_BITS - 1;
1133 dst[hn - 1] += cy;
1134 if (dst[hn - 1] < cy)
1135 lmmp_inc(dst);
1136
1137 if (na + nb == 2 * hn) {
1138 cy = tp[hn] + lmmp_sub_n_(dst + hn, dst, tp, hn);
1139 // cy==1 means [tp,hn+1]!=0, then [dst,hn]!=0
1140 // cy==2 is impossible since [tp,hn+1] is normalized.
1141 // so the following dec won't overflow.
1142 lmmp_dec_1(dst, cy);
1143 } else {
1144 cy = lmmp_sub_n_(dst + hn, dst, tp, na + nb - hn);
1145 cy = tp[hn] + lmmp_sub_nc_(tp + na + nb - hn, dst + na + nb - hn, tp + na + nb - hn, 2 * hn - (na + nb), cy);
1146 cy = lmmp_sub_1_(dst, dst, na + nb, cy);
1147 }
1148 lmmp_free(tp);
1149}
const mp_limb_t * mp_srcptr
Definition lmmp.h:81
#define lmmp_assert(x)
Definition lmmp.h:373
#define lmmp_param_assert(x)
Definition lmmp.h:401
mp_limb_t lmmp_shr1add_nc_(mp_ptr dst, mp_srcptr numa, mp_srcptr numb, mp_size_t n, mp_limb_t c)
带进位加法后右移1位 [dst,n] = ([numa,n] + [numb,n] + c) >> 1
Definition shr.c:89
static mp_limb_t lmmp_sub_1_(mp_ptr dst, mp_srcptr numa, mp_size_t na, mp_limb_t x)
大数减单精度数静态内联函数 [dst,na]=[numa,na]-x
Definition lmmpn.h:1114
void lmmp_mul_mersenne_(mp_ptr dst, mp_size_t rn, mp_srcptr numa, mp_size_t na, mp_srcptr numb, mp_size_t nb)
梅森数模乘法 [dst,rn] = [numa,na]*[numb,nb] mod B^rn-1
Definition mul_fft.c:761
void lmmp_mul_fermat_(mp_ptr dst, mp_size_t rn, mp_srcptr numa, mp_size_t na, mp_srcptr numb, mp_size_t nb)
费马数模乘法 [dst,rn+1]=[numa,na]*[numb,nb] mod B^rn+1
Definition mul_fft.c:687
mp_size_t lmmp_fft_next_size_(mp_size_t n)
计算FFT运算所需的最小规整化长度(向上取整到2^k的倍数)
Definition mul_fft.c:95
#define tp
#define ALLOC_TYPE(n, type)
Definition tmp_alloc.h:173

引用了 ALLOC_TYPE, LIMB_BITS, lmmp_add_(), lmmp_assert, lmmp_dec_1, lmmp_fft_next_size_(), lmmp_free(), lmmp_inc, lmmp_mul_fermat_(), lmmp_mul_mersenne_(), lmmp_param_assert, lmmp_shr1add_nc_(), lmmp_sub_(), lmmp_sub_1_(), lmmp_sub_n_(), lmmp_sub_nc_(), n, numb , 以及 tp.

被这些函数引用 __lmmp_mul_n_(), __lmmp_sqr_(), lmmp_mul_(), lmmp_mul_n_() , 以及 lmmp_sqr_().

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

◆ lmmp_mul_fft_cache_()

static void lmmp_mul_fft_cache_ ( mp_ptr  dst,
mp_size_t  hn,
mp_srcptr  numa,
mp_size_t  na,
mp_srcptr  numb,
mp_size_t  nb,
fft_cache GH 
)
static

在文件 mul_fft.c1151 行定义.

1159 {
1160 lmmp_param_assert(na > 0 && nb > 0);
1162 lmmp_assert(na + nb > hn);
1164
1166 mp_size_t nam = na;
1167 if (na > hn) {
1168 /*
1169 Z = B^hb - 1
1170 amodm = a mod Z
1171 */
1172 if (lmmp_add_(dst, numa, hn, numa + hn, na - hn))
1173 lmmp_inc(dst);
1174 amodm = dst;
1175 nam = hn;
1176 }
1178
1180 mp_size_t nap = na;
1181 if (na > hn) {
1182 /*
1183 Z = B^hp - 1
1184 amodp = a mod Z
1185 */
1186 tp[hn] = 0;
1187 if (lmmp_sub_(tp, numa, hn, numa + hn, na - hn))
1188 lmmp_inc(tp);
1189 amodp = tp;
1190 nap = hn + 1;
1191 }
1193
1195 cy <<= LIMB_BITS - 1;
1196 dst[hn - 1] += cy;
1197 if (dst[hn - 1] < cy)
1198 lmmp_inc(dst);
1199
1200 if (na + nb == 2 * hn) {
1201 cy = tp[hn] + lmmp_sub_n_(dst + hn, dst, tp, hn);
1202 // cy==1 means [tp,hn+1]!=0, then [dst,hn]!=0
1203 // cy==2 is impossible since [tp,hn+1] is normalized.
1204 // so the following dec won't overflow.
1205 lmmp_dec_1(dst, cy);
1206 } else {
1207 cy = lmmp_sub_n_(dst + hn, dst, tp, na + nb - hn);
1208 cy = tp[hn] + lmmp_sub_nc_(tp + na + nb - hn, dst + na + nb - hn, tp + na + nb - hn, 2 * hn - (na + nb), cy);
1209 cy = lmmp_sub_1_(dst, dst, na + nb, cy);
1210 }
1211 lmmp_free(tp);
1212}
static void lmmp_mul_mersenne_single_(mp_ptr dst, mp_size_t rn, mp_srcptr numa, mp_size_t na, mp_srcptr numb, mp_size_t nb, fft_cache *GH)
Definition mul_fft.c:974
static void lmmp_mul_fermat_single_(mp_ptr dst, mp_size_t rn, mp_srcptr numa, mp_size_t na, mp_srcptr numb, mp_size_t nb, fft_cache *GH)
Definition mul_fft.c:878

引用了 ALLOC_TYPE, LIMB_BITS, lmmp_add_(), lmmp_assert, lmmp_dec_1, lmmp_free(), lmmp_inc, lmmp_mul_fermat_single_(), lmmp_mul_mersenne_single_(), lmmp_param_assert, lmmp_shr1add_nc_(), lmmp_sub_(), lmmp_sub_1_(), lmmp_sub_n_(), lmmp_sub_nc_(), n, numb , 以及 tp.

被这些函数引用 lmmp_mul_fft_unbalance_().

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

◆ lmmp_mul_fft_cache_free_()

static void lmmp_mul_fft_cache_free_ ( fft_cache GH)
inlinestatic

在文件 mul_fft.c866 行定义.

866 {
867 if (GH->fermat_flag)
868 lmmp_fft_memstack_(&GH->msr_fermat, 0);
869 if (GH->mersenne_flag)
870 lmmp_fft_memstack_(&GH->msr_mersenne, 0);
871}

引用了 lmmp_fft_memstack_() , 以及 n.

被这些函数引用 lmmp_mul_fft_unbalance_().

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

◆ lmmp_mul_fft_unbalance_()

void lmmp_mul_fft_unbalance_ ( mp_ptr restrict  dst,
mp_srcptr restrict  numa,
mp_size_t  na,
mp_srcptr restrict  numb,
mp_size_t  nb 
)

在文件 mul_fft.c1214 行定义.

1220 {
1221 lmmp_param_assert(na >= 3 * nb);
1223 mp_size_t sna = 3 * nb;
1224 mp_size_t hn = lmmp_fft_next_size_((sna + nb + 1) >> 1);
1225 sna = (hn << 1) - 1 - nb;
1226 fft_cache GH = {.mersenne_flag = 0, .fermat_flag = 0};
1228 dst += sna;
1229 numa += sna;
1230 na -= sna;
1231 lmmp_copy(ws, dst, nb);
1232 while (na >= sna) {
1234 if (lmmp_add_n_(dst, dst, ws, nb))
1235 lmmp_inc(dst + nb);
1236 dst += sna;
1237 numa += sna;
1238 na -= sna;
1239 lmmp_copy(ws, dst, nb);
1240 }
1242 // remaining na < sna
1243 if (na >= nb)
1244 lmmp_mul_(dst, numa, na, numb, nb);
1245 else if (na > 0)
1246 lmmp_mul_(dst, numb, nb, numa, na);
1247 else // na == 0
1248 lmmp_zero(dst, nb);
1249 if (lmmp_add_n_(dst, dst, ws, nb))
1250 lmmp_inc(dst + nb);
1251 lmmp_free(ws);
1252}
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]
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:81
static void lmmp_mul_fft_cache_(mp_ptr dst, mp_size_t hn, mp_srcptr numa, mp_size_t na, mp_srcptr numb, mp_size_t nb, fft_cache *GH)
Definition mul_fft.c:1151
static void lmmp_mul_fft_cache_free_(fft_cache *GH)
Definition mul_fft.c:866
int mersenne_flag
Definition mul_fft.c:863

引用了 ALLOC_TYPE, lmmp_add_n_(), lmmp_copy, lmmp_fft_next_size_(), lmmp_free(), lmmp_inc, lmmp_mul_(), lmmp_mul_fft_cache_(), lmmp_mul_fft_cache_free_(), lmmp_param_assert, lmmp_zero, fft_cache::mersenne_flag, n , 以及 numb.

+ 函数调用图:

◆ lmmp_mul_mersenne_()

void lmmp_mul_mersenne_ ( mp_ptr  dst,
mp_size_t  rn,
mp_srcptr  numa,
mp_size_t  na,
mp_srcptr  numb,
mp_size_t  nb 
)

梅森数模乘法 [dst,rn] = [numa,na]*[numb,nb] mod B^rn-1

参数
dst输出结果缓冲区,长度至少为 rn
rn模运算的阶数参数,rn = lmmp_fft_next_size_((na + nb + 1) >> 1)
numa第一个输入操作数,长度为 na
na第一个操作数的 limb 长度
numb第二个输入操作数,长度为 nb
nb第二个操作数的 limb 长度
警告
eqsep(dst,[numa|numb]), 0<=[numa,na]<B^rn, 0<=[numb,nb]<B^rn, rn = lmmp_fft_next_size_((na+nb+1)>>1)
返回
无返回值,结果存储在dst中,

在文件 mul_fft.c761 行定义.

761 {
762 int nsqr = numa != numb || na != nb; // 判断是否为平方运算
763 mp_size_t N = rn * LIMB_BITS; // 结果总比特数
764 mp_size_t k = lmmp_fft_best_k_(rn); // 最优FFT层数
765 mp_size_t K = ((mp_size_t)1) << k; // FFT块数(2^k)
766 // 断言:N必须是K的整数倍
767 lmmp_debug_assert(!(N & (K - 1)));
768 mp_size_t M = N >> k; // 每个块的比特数
769 mp_size_t n = 2 * M + k; // 扩展系数长度(梅森数比费马数少2)
770
771 // 规整n:必须是LIMB_BITS和K/2的整数倍
772 n = (n + LIMB_BITS - 1) & (-LIMB_BITS);
773 n = (((n - 1) >> (k - 1)) + 1) << (k - 1);
774
775 // 初始化内存栈
777 msr.maxdepth = -1;
778 msr.tempdepth = -1;
779 msr.lenw = n / LIMB_BITS;
780 mp_size_t nlen = msr.lenw + 1;
781
782 msr.temp_coef = (mp_ptr)lmmp_fft_memstack_(&msr, (((nlen + 1) << (k + nsqr)) + nlen) * LIMB_BYTES);
783
784 mp_ptr *pfca = (mp_ptr*)(msr.temp_coef + nlen), *pfcb = pfca;
786
787 for (mp_size_t i = 0; i < K; ++i) {
789 pfca[i] = (mp_ptr)(pfca + K) + i * nlen;
790 if (narest > 0) {
792 narest -= coeflen;
794 } else {
795 lmmp_zero(pfca[i], nlen);
796 }
797 }
798 lmmp_fft_(&msr, pfca, k, n >> (k - 1));
799
800 if (nsqr) {
801 pfcb += (nlen + 1) << k;
802 for (mp_size_t i = 0; i < K; ++i) {
804 pfcb[i] = (mp_ptr)(pfcb + K) + i * nlen;
805 if (nbrest > 0) {
807 nbrest -= coeflen;
809 } else {
810 lmmp_zero(pfcb[i], nlen);
811 }
812 }
813 lmmp_fft_(&msr, pfcb, k, n >> (k - 1));
814 }
815
817
818 lmmp_ifft_(&msr, pfca, k, n >> (k - 1));
819
820 mp_size_t rhead = 0, maxc = 0;
821 for (mp_size_t i = 0; i < K; ++i) {
823 mp_ptr nums = pfca[i];
824
825 if (nums[nlen - 1]) {
826 lmmp_dec(nums);
827 lmmp_debug_assert(nums[nlen - 1] == 1);
828 nums[nlen - 1] = 0;
829 }
830
831 mp_size_t roffset = i * M;
832 mp_size_t shl = roffset & (LIMB_BITS - 1);
834
835 if (shl)
837
838 if (i == 0) {
840 rhead = nlen;
841 } else if (roffset + nlen <= rn) {
843 rhead = roffset + nlen;
844 } else {
846 maxc += lmmp_add_(dst, dst, rn, nums + rn - roffset, nlen + roffset - rn);
847 rhead = rn;
848 }
849 }
850
851 if (!lmmp_add_1_(dst, dst, rn, 1 + maxc))
852 lmmp_dec(dst);
853
855}

引用了 k, LIMB_BITS, LIMB_BYTES, lmmp_add_(), lmmp_add_1_(), lmmp_copy, lmmp_debug_assert, lmmp_dec, lmmp_fft_(), lmmp_fft_best_k_(), lmmp_fft_extract_coef_(), lmmp_fft_memstack_(), lmmp_fft_shr_coef_(), lmmp_ifft_(), LMMP_MIN, lmmp_mul_fermat_recurse_(), lmmp_shl_(), lmmp_zero, fft_memstack::maxdepth, n , 以及 numb.

被这些函数引用 binvert_mulhi_(), lmmp_div_mulinv_(), lmmp_invappr_newton_(), lmmp_invsqrt_newton_(), lmmp_mul_fft_(), lmmp_mulhi_n_() , 以及 lmmp_mullo_fft_().

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

◆ lmmp_mul_mersenne_single_()

static void lmmp_mul_mersenne_single_ ( mp_ptr  dst,
mp_size_t  rn,
mp_srcptr  numa,
mp_size_t  na,
mp_srcptr  numb,
mp_size_t  nb,
fft_cache GH 
)
static

在文件 mul_fft.c974 行定义.

982 {
983 mp_size_t N = rn * LIMB_BITS; // 结果总比特数
984 mp_size_t k = lmmp_fft_best_k_(rn); // 最优FFT层数
985 mp_size_t K = ((mp_size_t)1) << k; // FFT块数(2^k)
986 // 断言:N必须是K的整数倍
987 lmmp_debug_assert(!(N & (K - 1)));
988 mp_size_t M = N >> k; // 每个块的比特数
989 mp_size_t n = 2 * M + k; // 扩展系数长度(梅森数比费马数少2)
990
991 // 规整n:必须是LIMB_BITS和K/2的整数倍
992 n = (n + LIMB_BITS - 1) & (-LIMB_BITS);
993 n = (((n - 1) >> (k - 1)) + 1) << (k - 1);
994
995 // 初始化内存栈
998 amsr.maxdepth = -1;
999 amsr.tempdepth = -1;
1000 amsr.lenw = n / LIMB_BITS;
1001 mp_size_t nlen = amsr.lenw + 1;
1002 mp_size_t a_size = (((nlen + 1) << (k)) + nlen) * LIMB_BYTES;
1003 mp_size_t b_size = (((nlen + 1) << (k)) + nlen) * LIMB_BYTES;
1004 amsr.temp_coef = (mp_ptr)lmmp_fft_memstack_(&amsr, a_size);
1005
1006 mp_ptr* pfca = (mp_ptr*)(amsr.temp_coef + nlen);
1007 mp_ptr* pfcb = NULL;
1008
1009 if (GH->mersenne_flag) {
1010 bmsr = &GH->msr_mersenne;
1011 bmsr->lenw = n / LIMB_BITS;
1012 pfcb = (mp_ptr*)(GH->temp_coef_mersenne + nlen);
1013 } else {
1014 bmsr = &GH->msr_mersenne;
1015 bmsr->maxdepth = -1;
1016 bmsr->tempdepth = -1;
1017 bmsr->lenw = n / LIMB_BITS;
1018 bmsr->temp_coef = (mp_ptr)lmmp_fft_memstack_(bmsr, b_size);
1019 GH->temp_coef_mersenne = bmsr->temp_coef;
1020 pfcb = (mp_ptr*)(bmsr->temp_coef + nlen);
1021 }
1022
1024
1025 for (mp_size_t i = 0; i < K; ++i) {
1027 pfca[i] = (mp_ptr)(pfca + K) + i * nlen;
1028 if (narest > 0) {
1030 narest -= coeflen;
1032 } else {
1033 lmmp_zero(pfca[i], nlen);
1034 }
1035 }
1036 lmmp_fft_(&amsr, pfca, k, n >> (k - 1));
1037
1038 if (!GH->mersenne_flag) {
1039 GH->mersenne_flag = 1;
1040 for (mp_size_t i = 0; i < K; ++i) {
1042 pfcb[i] = (mp_ptr)(pfcb + K) + i * nlen;
1043 if (nbrest > 0) {
1045 nbrest -= coeflen;
1047 } else {
1048 lmmp_zero(pfcb[i], nlen);
1049 }
1050 }
1051 lmmp_fft_(bmsr, pfcb, k, n >> (k - 1));
1052 }
1053
1055
1056 lmmp_ifft_(&amsr, pfca, k, n >> (k - 1));
1057
1058 mp_size_t rhead = 0, maxc = 0;
1059 for (mp_size_t i = 0; i < K; ++i) {
1061 mp_ptr nums = pfca[i];
1062
1063 if (nums[nlen - 1]) {
1064 lmmp_dec(nums);
1065 lmmp_debug_assert(nums[nlen - 1] == 1);
1066 nums[nlen - 1] = 0;
1067 }
1068
1069 mp_size_t roffset = i * M;
1070 mp_size_t shl = roffset & (LIMB_BITS - 1);
1071 roffset /= LIMB_BITS;
1072
1073 if (shl)
1075
1076 if (i == 0) {
1078 rhead = nlen;
1079 } else if (roffset + nlen <= rn) {
1081 rhead = roffset + nlen;
1082 } else {
1084 maxc += lmmp_add_(dst, dst, rn, nums + rn - roffset, nlen + roffset - rn);
1085 rhead = rn;
1086 }
1087 }
1088
1089 if (!lmmp_add_1_(dst, dst, rn, 1 + maxc))
1090 lmmp_dec(dst);
1091
1093}

引用了 k, LIMB_BITS, LIMB_BYTES, lmmp_add_(), lmmp_add_1_(), lmmp_copy, lmmp_debug_assert, lmmp_dec, lmmp_fft_(), lmmp_fft_best_k_(), lmmp_fft_extract_coef_(), lmmp_fft_memstack_(), lmmp_fft_shr_coef_(), lmmp_ifft_(), LMMP_MIN, lmmp_mul_fermat_recurse_(), lmmp_shl_(), lmmp_zero, fft_memstack::maxdepth, n , 以及 numb.

被这些函数引用 lmmp_mul_fft_cache_().

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

变量说明

◆ lmmp_fft_table_

const mp_size_t lmmp_fft_table_[][2]
static

在文件 mul_fft.c30 行定义.

30 {
31 {0, 6},
32 {1597, 7},
33 {1655, 6},
34 {1917, 7},
35 {3447, 8},
36 {3565, 7},
37 {3831, 8},
38 {7661, 9},
39 {8145, 8},
40 {8685, 9},
41 {14289, 10},
42 {16289, 9},
43 {20433, 10},
44 {24481, 9},
45 {26577, 10},
46 {28593, 11},
47 {32545, 10},
48 {57249, 11},
49 {65313, 10},
50 {73633, 11},
51 {98081, 12},
52 {130625, 11},
53 {196385, 12},
54 {261697, 11},
55 {294689, 12},
56 {392769, 13},
57 {523265, 12},
58 {654913, 11},
59 {917281, 13},
60 {1047553, 11},
61 {1600001, 12},
62 {1834561, 14},
63 {2095105, 12},
68 {(mp_size_t)-1, 127}};
#define _FFT_TABLE_ENTRY4(n)
Definition mul_fft.c:24

被这些函数引用 lmmp_fft_best_k_().