LAMMP 4.2.0
Lamina High-Precision Arithmetic Library
载入中...
搜索中...
未找到
mul_toom_interp6.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 = 2*x^3 + 32*x^2 + 4*x + 5;
23 b = 6*x^2 + 712*x + 18;
24 c_true = a*b;
25
26 w0 = 2*6;
27 w1 = subs(a,2)*subs(b,2);
28 w2 = subs(a,-2)*subs(b,-2);
29 w3 = subs(a,1)*subs(b,1);
30 w4 = subs(a,-1)*subs(b,-1);
31 w5 = subs(a,0)*subs(b,0);
32
33 w2 = (w1 - w2)/4;
34 w1 = (w1 - w5)/2;
35 w1 = (w1 - w2)/2;
36 w4 = (w3 - w4)/2;
37 w2 = (w2 - w4)/3;
38 w3 = w3 - w4 - w5;
39 w1 = (w1 - w3)/3;
40 w2 = w2 - w0*4;
41 w4 = w4 - w2;
42 w3 = w3 - w1;
43 w2 = w2 - w0;
44
45 c0=w5; c1=w4; c2=w3; c3=w2; c4=w1; c5=w0;
46 c_calc = c5*x^5 + c4*x^4 + c3*x^3 + c2*x^2 + c1*x + c0;
47*/
48
50 mp_ptr dst,
52 enum toom6_flags flags,
53 mp_ptr w4,
54 mp_ptr w2,
55 mp_ptr w1,
57) {
58
60 lmmp_param_assert(2 * n >= w0n && w0n > 0);
62 /* cy6 can be stored in w1[2*n], cy4 in w4[0], embankment in w2[0] */
64
65#define w5 dst /* 2n */
66#define w3 (dst + 2 * n) /* 2n+1 */
67#define w0 (dst + 5 * n) /* w0n */
68
69 /* W2 =(W1 - W2)>>2 */
70 if (flags & toom6_vm2_neg)
71 lmmp_add_n_(w2, w1, w2, 2 * n + 1);
72 else
73 lmmp_sub_n_(w2, w1, w2, 2 * n + 1);
74 lmmp_shr_(w2, w2, 2 * n + 1, 2);
75
76 /* W1 =(W1 - W5)>>1 */
77 w1[2 * n] -= lmmp_sub_n_(w1, w1, w5, 2 * n);
78 lmmp_shr_(w1, w1, 2 * n + 1, 1);
79
80 /* W1 =(W1 - W2)>>1 */
81 lmmp_shr1sub_n_(w1, w1, w2, 2 * n + 1);
82
83 /* W4 =(W3 - W4)>>1 */
84 if (flags & toom6_vm1_neg) {
85 lmmp_shr1add_n_(w4, w3, w4, 2 * n + 1);
86 } else {
87 lmmp_shr1sub_n_(w4, w3, w4, 2 * n + 1);
88 }
89
90 /* W2 =(W2 - W4)/3 */
91 lmmp_sub_n_(w2, w2, w4, 2 * n + 1);
92 lmmp_divexact_by3_(w2, w2, 2 * n + 1);
93
94 /* W3 = W3 - W4 - W5 */
95 lmmp_sub_n_(w3, w3, w4, 2 * n + 1);
96 w3[2 * n] -= lmmp_sub_n_(w3, w3, w5, 2 * n);
97
98 /* W1 =(W1 - W3)/3 */
99 lmmp_sub_n_(w1, w1, w3, 2 * n + 1);
100 lmmp_divexact_by3_(w1, w1, 2 * n + 1);
101
102 cy = lmmp_add_n_(dst + n, dst + n, w4, 2 * n + 1);
103 lmmp_inc_1(dst + 3 * n + 1, cy);
104
105 /* W2 -= W0<<2 */
106 /* {W4,2*n+1} is now free and can be overwritten. */
107 cy = lmmp_shl_(w4, w0, w0n, 2);
108 cy += lmmp_sub_n_(w2, w2, w4, w0n);
109
110 lmmp_dec_1(w2 + w0n, cy);
111
112 /* W4L = W4L - W2L */
113 cy = lmmp_sub_n_(dst + n, dst + n, w2, n);
114 lmmp_dec_1(w3, cy);
115
116 /* W3H = W3H + W2L */
117 cy4 = w3[2 * n] + lmmp_add_n_(dst + 3 * n, dst + 3 * n, w2, n);
118 /* W1L + W2H */
119 cy = w2[2 * n] + lmmp_add_n_(dst + 4 * n, w1, w2 + n, n);
120 lmmp_inc_1(w1 + n, cy);
121
122 /* W0 = W0 + W1H */
123 if (w0n > n)
124 cy6 = w1[2 * n] + lmmp_add_n_(w0, w0, w1 + n, n);
125 else
126 cy6 = lmmp_add_n_(w0, w0, w1 + n, w0n);
127
128 cy = lmmp_sub_n_(dst + 2 * n, dst + 2 * n, dst + 4 * n, n + w0n);
129
130 /* embankment is a "dirty trick" to avoid carry/borrow propagation
131 beyond allocated memory */
132 embankment = w0[w0n - 1] - 1;
133 w0[w0n - 1] = 1;
134 if (w0n > n) {
135 if (cy4 > cy6)
136 lmmp_inc_1(dst + 4 * n, cy4 - cy6);
137 else
138 lmmp_dec_1(dst + 4 * n, cy6 - cy4);
139 lmmp_dec_1(dst + 3 * n + w0n, cy);
140 lmmp_inc_1(w0 + n, cy6);
141 } else {
142 lmmp_inc_1(dst + 4 * n, cy4);
143 lmmp_dec_1(dst + 3 * n + w0n, cy + cy6);
144 }
145 w0[w0n - 1] += embankment;
146
147#undef w5
148#undef w3
149#undef w0
150}
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
uint64_t mp_limb_t
Definition lmmp.h:76
#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
#define lmmp_dec_1(p, dec)
大数减指定值宏(预期无借位)
Definition lmmpn.h:977
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 n
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)
Copyright (C) 2026 HJimmyK(Jericho Knox)
#define w3
#define w0
#define w5
#define w2
toom6_flags
Copyright (C) 2026 HJimmyK(Jericho Knox)
Definition toom_interp.h:22
@ toom6_vm2_neg
Definition toom_interp.h:22
@ toom6_vm1_neg
Definition toom_interp.h:22