ยปCore Development>Code coverage>Modules/_decimal/libmpdec/convolute.c

Python code coverage for Modules/_decimal/libmpdec/convolute.c

#countcontent
1n/a/*
2n/a * Copyright (c) 2008-2016 Stefan Krah. All rights reserved.
3n/a *
4n/a * Redistribution and use in source and binary forms, with or without
5n/a * modification, are permitted provided that the following conditions
6n/a * are met:
7n/a *
8n/a * 1. Redistributions of source code must retain the above copyright
9n/a * notice, this list of conditions and the following disclaimer.
10n/a *
11n/a * 2. Redistributions in binary form must reproduce the above copyright
12n/a * notice, this list of conditions and the following disclaimer in the
13n/a * documentation and/or other materials provided with the distribution.
14n/a *
15n/a * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
16n/a * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17n/a * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18n/a * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19n/a * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20n/a * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21n/a * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22n/a * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23n/a * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24n/a * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25n/a * SUCH DAMAGE.
26n/a */
27n/a
28n/a
29n/a#include "mpdecimal.h"
30n/a#include <stdio.h>
31n/a#include "bits.h"
32n/a#include "constants.h"
33n/a#include "fnt.h"
34n/a#include "fourstep.h"
35n/a#include "numbertheory.h"
36n/a#include "sixstep.h"
37n/a#include "umodarith.h"
38n/a#include "convolute.h"
39n/a
40n/a
41n/a/* Bignum: Fast convolution using the Number Theoretic Transform. Used for
42n/a the multiplication of very large coefficients. */
43n/a
44n/a
45n/a/* Convolute the data in c1 and c2. Result is in c1. */
46n/aint
47n/afnt_convolute(mpd_uint_t *c1, mpd_uint_t *c2, mpd_size_t n, int modnum)
48n/a{
49n/a int (*fnt)(mpd_uint_t *, mpd_size_t, int);
50n/a int (*inv_fnt)(mpd_uint_t *, mpd_size_t, int);
51n/a#ifdef PPRO
52n/a double dmod;
53n/a uint32_t dinvmod[3];
54n/a#endif
55n/a mpd_uint_t n_inv, umod;
56n/a mpd_size_t i;
57n/a
58n/a
59n/a SETMODULUS(modnum);
60n/a n_inv = POWMOD(n, (umod-2));
61n/a
62n/a if (ispower2(n)) {
63n/a if (n > SIX_STEP_THRESHOLD) {
64n/a fnt = six_step_fnt;
65n/a inv_fnt = inv_six_step_fnt;
66n/a }
67n/a else {
68n/a fnt = std_fnt;
69n/a inv_fnt = std_inv_fnt;
70n/a }
71n/a }
72n/a else {
73n/a fnt = four_step_fnt;
74n/a inv_fnt = inv_four_step_fnt;
75n/a }
76n/a
77n/a if (!fnt(c1, n, modnum)) {
78n/a return 0;
79n/a }
80n/a if (!fnt(c2, n, modnum)) {
81n/a return 0;
82n/a }
83n/a for (i = 0; i < n-1; i += 2) {
84n/a mpd_uint_t x0 = c1[i];
85n/a mpd_uint_t y0 = c2[i];
86n/a mpd_uint_t x1 = c1[i+1];
87n/a mpd_uint_t y1 = c2[i+1];
88n/a MULMOD2(&x0, y0, &x1, y1);
89n/a c1[i] = x0;
90n/a c1[i+1] = x1;
91n/a }
92n/a
93n/a if (!inv_fnt(c1, n, modnum)) {
94n/a return 0;
95n/a }
96n/a for (i = 0; i < n-3; i += 4) {
97n/a mpd_uint_t x0 = c1[i];
98n/a mpd_uint_t x1 = c1[i+1];
99n/a mpd_uint_t x2 = c1[i+2];
100n/a mpd_uint_t x3 = c1[i+3];
101n/a MULMOD2C(&x0, &x1, n_inv);
102n/a MULMOD2C(&x2, &x3, n_inv);
103n/a c1[i] = x0;
104n/a c1[i+1] = x1;
105n/a c1[i+2] = x2;
106n/a c1[i+3] = x3;
107n/a }
108n/a
109n/a return 1;
110n/a}
111n/a
112n/a/* Autoconvolute the data in c1. Result is in c1. */
113n/aint
114n/afnt_autoconvolute(mpd_uint_t *c1, mpd_size_t n, int modnum)
115n/a{
116n/a int (*fnt)(mpd_uint_t *, mpd_size_t, int);
117n/a int (*inv_fnt)(mpd_uint_t *, mpd_size_t, int);
118n/a#ifdef PPRO
119n/a double dmod;
120n/a uint32_t dinvmod[3];
121n/a#endif
122n/a mpd_uint_t n_inv, umod;
123n/a mpd_size_t i;
124n/a
125n/a
126n/a SETMODULUS(modnum);
127n/a n_inv = POWMOD(n, (umod-2));
128n/a
129n/a if (ispower2(n)) {
130n/a if (n > SIX_STEP_THRESHOLD) {
131n/a fnt = six_step_fnt;
132n/a inv_fnt = inv_six_step_fnt;
133n/a }
134n/a else {
135n/a fnt = std_fnt;
136n/a inv_fnt = std_inv_fnt;
137n/a }
138n/a }
139n/a else {
140n/a fnt = four_step_fnt;
141n/a inv_fnt = inv_four_step_fnt;
142n/a }
143n/a
144n/a if (!fnt(c1, n, modnum)) {
145n/a return 0;
146n/a }
147n/a for (i = 0; i < n-1; i += 2) {
148n/a mpd_uint_t x0 = c1[i];
149n/a mpd_uint_t x1 = c1[i+1];
150n/a MULMOD2(&x0, x0, &x1, x1);
151n/a c1[i] = x0;
152n/a c1[i+1] = x1;
153n/a }
154n/a
155n/a if (!inv_fnt(c1, n, modnum)) {
156n/a return 0;
157n/a }
158n/a for (i = 0; i < n-3; i += 4) {
159n/a mpd_uint_t x0 = c1[i];
160n/a mpd_uint_t x1 = c1[i+1];
161n/a mpd_uint_t x2 = c1[i+2];
162n/a mpd_uint_t x3 = c1[i+3];
163n/a MULMOD2C(&x0, &x1, n_inv);
164n/a MULMOD2C(&x2, &x3, n_inv);
165n/a c1[i] = x0;
166n/a c1[i+1] = x1;
167n/a c1[i+2] = x2;
168n/a c1[i+3] = x3;
169n/a }
170n/a
171n/a return 1;
172n/a}
173n/a
174n/a