LAMMP 4.2.0
Lamina High-Precision Arithmetic Library
载入中...
搜索中...
未找到
mul_toom_eval.c
浏览该文件的文档.
1/**
2 * Copyright (C) 2026 HJimmyK(Jericho Knox)
3 *
4 * This file is part of LAMMP.
5 *
6 * LAMMP is free software: you can redistribute it and/or modify it under
7 * the terms of the GNU Lesser General Public License (LGPL) as published
8 * by the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed WITHOUT ANY WARRANTY.
12 *
13 * See <https://www.gnu.org/licenses/>.
14 */
15
16#include "../../../include/lammp/impl/toom_interp.h"
17
18
20 int neg;
23
24 xp1[n] = lmmp_add_n_(xp1, xp, xp + 2 * n, n);
25 tp[n] = lmmp_add_(tp, xp + n, n, xp + 3 * n, x3n);
26
27 neg = (lmmp_cmp_(xp1, tp, n + 1) < 0) ? ~0 : 0;
28 if (neg)
30 else
32
33 lmmp_debug_assert(xp1[n] <= 3);
34 lmmp_debug_assert(xm1[n] <= 1);
35
36 return neg;
37}
38
41 int neg;
44 /* (x0 + 4 * x2) +/- (2 x1 + 8 x_3) */
45
46 cy = lmmp_shl_(tp, xp + 2 * n, n, 2);
47 xp2[n] = cy + lmmp_add_n_(xp2, tp, xp, n);
48
49 tp[x3n] = lmmp_shl_(tp, xp + 3 * n, x3n, 2);
50 if (x3n < n)
51 tp[n] = lmmp_add_(tp, xp + n, n, tp, x3n + 1);
52 else
53 tp[n] += lmmp_add_n_(tp, xp + n, tp, n);
54
55 lmmp_shl_(tp, tp, n + 1, 1);
56
57 neg = (lmmp_cmp_(xp2, tp, n + 1) < 0) ? ~0 : 0;
58
59 if (neg)
61 else
63
64 lmmp_debug_assert(xp2[n] < 15);
65 lmmp_debug_assert(xm2[n] < 10);
66
67 return neg;
68}
69
71 unsigned i;
72 int neg;
73 lmmp_param_assert(k >= 4);
74
77
78 /* The degree k is also the number of full-size coefficients, so
79 * that last coefficient, of size hn, starts at xp + k*n. */
80
81 xp1[n] = lmmp_add_n_(xp1, xp, xp + 2 * n, n);
82 for (i = 4; i < k; i += 2) lmmp_add_(xp1, xp1, n + 1, xp + i * n, n);
83
84 tp[n] = lmmp_add_n_(tp, xp + n, xp + 3 * n, n);
85 for (i = 5; i < k; i += 2) lmmp_add_(tp, tp, n + 1, xp + i * n, n);
86
87 if (k & 1)
88 lmmp_add_(tp, tp, n + 1, xp + k * n, hn);
89 else
90 lmmp_add_(xp1, xp1, n + 1, xp + k * n, hn);
91
92 neg = (lmmp_cmp_(xp1, tp, n + 1) < 0) ? ~0 : 0;
93
94 if (neg)
96 else
98
100 lmmp_debug_assert(xm1[n] <= k / 2 + 1);
101
102 return neg;
103}
104
105/* DO_addlsh2(d,a,b,n,cy) computes cy,[d,n] <= [a,n] + 4*(cy,[b,n]), it
106 can be used as DO_addlsh2(d,a,d,n,d[n]), for accumulation on [d,n+1]. */
107
108/* The following is not a general substitute for addlsh2.
109 It is correct if d == b, but it is not if d == a. */
110#define DO_addlsh2(d, a, b, n, cy) \
111 do { \
112 (cy) <<= 2; \
113 (cy) += lmmp_shl_(d, b, n, 2); \
114 (cy) += lmmp_add_n_(d, d, a, n); \
115 } while (0)
116
118 int i;
119 int neg;
121 lmmp_param_assert(k >= 3);
123
126
127 /* The degree k is also the number of full-size coefficients, so
128 * that last coefficient, of size hn, starts at xp + k*n. */
129
130 cy = 0;
131 DO_addlsh2(xp2, xp + (k - 2) * n, xp + k * n, hn, cy);
132 if (hn != n)
133 cy = lmmp_add_1_(xp2 + hn, xp + (k - 2) * n + hn, n - hn, cy);
134 for (i = k - 4; i >= 0; i -= 2) DO_addlsh2(xp2, xp + i * n, xp2, n, cy);
135 xp2[n] = cy;
136
137 k--;
138
139 cy = 0;
140 DO_addlsh2(tp, xp + (k - 2) * n, xp + k * n, n, cy);
141 for (i = k - 4; i >= 0; i -= 2) DO_addlsh2(tp, xp + i * n, tp, n, cy);
142 tp[n] = cy;
143
144 if (k & 1)
145 lmmp_shl_(tp, tp, n + 1, 1);
146 else
147 lmmp_shl_(xp2, xp2, n + 1, 1);
148
149 neg = (lmmp_cmp_(xp2, tp, n + 1) < 0) ? ~0 : 0;
150
151 if (neg)
152 lmmp_add_n_sub_n_(xp2, xm2, tp, xp2, n + 1);
153 else
154 lmmp_add_n_sub_n_(xp2, xm2, xp2, tp, n + 1);
155
156 lmmp_debug_assert(xp2[n] < (1ull << (k + 2)) - 1);
157 lmmp_debug_assert(xm2[n] < ((1 << (k + 3)) - 1 - (1 ^ (k & 1))) / 3);
158
159 neg ^= ((k & 1) - 1);
160
161 return neg;
162}
163
164#undef DO_addlsh2
#define k
mp_limb_t * mp_ptr
Definition lmmp.h:80
uint64_t mp_size_t
Definition lmmp.h:77
#define lmmp_debug_assert(x)
Definition lmmp.h:390
const mp_limb_t * mp_srcptr
Definition lmmp.h:81
uint64_t mp_limb_t
Definition lmmp.h:76
#define LIMB_BITS
Definition lmmp.h:86
#define lmmp_param_assert(x)
Definition lmmp.h:401
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 int lmmp_cmp_(mp_srcptr numa, mp_srcptr numb, mp_size_t n)
大数比较函数(内联)
Definition lmmpn.h:996
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
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
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:20
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
#define tp
#define n
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 处求值
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_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段系数)。
#define DO_addlsh2(d, a, b, n, cy)
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)
Copyright (C) 2026 HJimmyK(Jericho Knox)