LAMMP 4.2.0
Lamina High-Precision Arithmetic Library
载入中...
搜索中...
未找到
mul_toom_interp7.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/divexact.h"
17#include "../../../include/lammp/impl/toom_interp.h"
18
19
20/*
21 syms x integer
22 a = 12*x^3 + 22*x^2 + 32*x + 42;
23 b = 56*x^3 + 62*x^2 + 7*x + 82;
24 c_true = a*b;
25
26 w0 = subs(a,0)*subs(b,0);
27 w1 = subs(a,-2)*subs(b,-2);
28 w2 = subs(a,1)*subs(b,1);
29 w3 = subs(a,-1)*subs(b,-1);
30 w4 = subs(a,2)*subs(b,2);
31 w5 = 64*subs(a,1/2)*subs(b,1/2);
32 w6 = 12*56;
33
34 w5 = w5 + w4;
35 w1 = (w4 - w1)/2;
36 w4 = w4 - w0;
37 w4 = (w4 - w1)/4 - w6*16;
38 w3 = (w2 - w3)/2;
39 w2 = w2 - w3;
40 w5 = w5 - 65*w2;
41 w2 = w2 - w6 - w0;
42 w5 = (w5 + 45*w2)/2;
43 w4 = (w4 - w2)/3;
44 w2 = w2 - w4;
45 w1 = w5 - w1;
46 w5 = (w5 - 8*w3)/9;
47 w3 = w3 - w5;
48 w1 = (w1/15 + w5)/2;
49 w5 = w5 - w1;
50
51 c0 = w0; c1 = w1; c2 = w2; c3 = w3; c4 = w4; c5 = w5; c6 = w6;
52 c_calc = c6*x^6 + c5*x^5 + c4*x^4 + c3*x^3 + c2*x^2 + c1*x + c0;
53*/
54
56 mp_ptr dst,
58 enum toom7_flags flags,
59 mp_ptr w1,
60 mp_ptr w3,
61 mp_ptr w4,
62 mp_ptr w5,
65) {
67 lmmp_param_assert(w6n <= 2 * n);
70
71 m = 2 * n + 1;
72#define w0 dst
73#define w2 (dst + 2 * n)
74#define w6 (dst + 6 * n)
75
76 lmmp_add_n_(w5, w5, w4, m);
77 if (flags & toom7_w1_neg) {
79 } else {
81 }
82 lmmp_sub_(w4, w4, m, w0, 2 * n);
83 lmmp_sub_n_(w4, w4, w1, m);
84
85 lmmp_debug_assert(!(w4[0] & 3));
86
87 lmmp_shr_(w4, w4, m, 2); /* w4>=0 */
88
89 tp[w6n] = lmmp_shl_(tp, w6, w6n, 4);
90 lmmp_sub_(w4, w4, m, tp, w6n + 1);
91
92 if (flags & toom7_w3_neg) {
94 } else {
96 }
97
98 lmmp_sub_n_(w2, w2, w3, m);
99
100 lmmp_submul_1_(w5, w2, m, 65);
101 lmmp_sub_(w2, w2, m, w6, w6n);
102 lmmp_sub_(w2, w2, m, w0, 2 * n);
103
104 lmmp_addmul_1_(w5, w2, m, 45);
105 lmmp_debug_assert(!(w5[0] & 1));
106 lmmp_shr_(w5, w5, m, 1);
107 lmmp_sub_n_(w4, w4, w2, m);
108
110 lmmp_sub_n_(w2, w2, w4, m);
111
112 lmmp_sub_n_(w1, w5, w1, m);
113 lmmp_shl_(tp, w3, m, 3);
114 lmmp_sub_n_(w5, w5, tp, m);
116 lmmp_sub_n_(w3, w3, w5, m);
117
120 w1[m - 1] &= LIMB_MAX >> 1;
121
122 lmmp_sub_n_(w5, w5, w1, m);
123
124 /* These bounds are valid for the 4x4 polynomial product of toom44,
125 * and they are conservative for toom53 and toom62. */
126 lmmp_debug_assert(w1[2 * n] < 2);
127 lmmp_debug_assert(w2[2 * n] < 3);
128 lmmp_debug_assert(w3[2 * n] < 4);
129 lmmp_debug_assert(w4[2 * n] < 3);
130 lmmp_debug_assert(w5[2 * n] < 2);
131
132 cy = lmmp_add_n_(dst + n, dst + n, w1, m);
133 lmmp_inc_1(w2 + n + 1, cy);
134 cy = lmmp_add_n_(dst + 3 * n, dst + 3 * n, w3, n);
135 lmmp_inc_1(w3 + n, w2[2 * n] + cy);
136 cy = lmmp_add_n_(dst + 4 * n, w3 + n, w4, n);
137 lmmp_inc_1(w4 + n, w3[2 * n] + cy);
138 cy = lmmp_add_n_(dst + 5 * n, w4 + n, w5, n);
139 lmmp_inc_1(w5 + n, w4[2 * n] + cy);
140 if (w6n > n + 1) {
141 cy = lmmp_add_n_(dst + 6 * n, dst + 6 * n, w5 + n, n + 1);
142 lmmp_inc_1(dst + 7 * n + 1, cy);
143 } else {
144 lmmp_assert(lmmp_add_n_(dst + 6 * n, dst + 6 * n, w5 + n, w6n));
145 }
146}
static void lmmp_divexact_by15_(mp_ptr dst, mp_srcptr numa, mp_size_t na)
精确除以15([dst,na] = [numa,na] / 15)
Definition divexact.h:82
static void lmmp_divexact_by9_(mp_ptr dst, mp_srcptr numa, mp_size_t na)
精确除以9([dst,na] = [numa,na] / 9)
Definition divexact.h:56
static void lmmp_divexact_by3_(mp_ptr dst, mp_srcptr numa, mp_size_t na)
精确除以3([dst,na] = [numa,na] / 3)
Definition divexact.h:30
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
#define LIMB_MAX
Definition lmmp.h:89
uint64_t mp_limb_t
Definition lmmp.h:76
#define lmmp_assert(x)
Definition lmmp.h:373
#define lmmp_param_assert(x)
Definition lmmp.h:401
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:62
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
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
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
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
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
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:116
#define lmmp_inc_1(p, inc)
大数加指定值宏(预期无进位)
Definition lmmpn.h:950
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
#define w3
#define w5
#define w2
#define w0
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)
Copyright (C) 2026 HJimmyK(Jericho Knox)
#define w6
toom7_flags
Definition toom_interp.h:24
@ toom7_w1_neg
Definition toom_interp.h:24
@ toom7_w3_neg
Definition toom_interp.h:24