blob: 8188b00c496c9425329c4ad9bf9081463d1b6617 [file] [log] [blame]
Austin Schuhbb1338c2024-06-15 19:31:16 -07001/* Test for various Toom functions.
2
3Copyright 2009 Free Software Foundation, Inc.
4
5This file is part of the GNU MP Library test suite.
6
7The GNU MP Library test suite is free software; you can redistribute it
8and/or modify it under the terms of the GNU General Public License as
9published by the Free Software Foundation; either version 3 of the License,
10or (at your option) any later version.
11
12The GNU MP Library test suite is distributed in the hope that it will be
13useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15Public License for more details.
16
17You should have received a copy of the GNU General Public License along with
18the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */
19
20
21#include <stdlib.h>
22#include <stdio.h>
23
24#include "gmp-impl.h"
25#include "tests.h"
26
27/* Main file is expected to define mpn_toomMN_mul,
28 * mpn_toomMN_mul_itch, MIN_AN, MIN_BN(an), MAX_BN(an) and then
29 * include this file. */
30
31/* Sizes are up to 2^SIZE_LOG limbs */
32#ifndef SIZE_LOG
33#define SIZE_LOG 10
34#endif
35
36#ifndef COUNT
37#define COUNT 2000
38#endif
39
40#define MAX_AN (1L << SIZE_LOG)
41
42#ifndef MAX_BN
43#define MAX_BN(an) (an)
44#endif
45
46/* For general toomMN_mul, we need
47 *
48 * MIN_BN(an) = N + floor(((N-1)*an + M - N)/M)
49 *
50 * MAX_BN(an) = floor(N*(an-1)/(M-1)) - N + 1
51 */
52
53int
54main (int argc, char **argv)
55{
56 mp_ptr ap, bp, refp, pp, scratch;
57 int count = COUNT;
58 int test;
59 gmp_randstate_ptr rands;
60 TMP_DECL;
61 TMP_MARK;
62
63 TESTS_REPS (count, argv, argc);
64
65 tests_start ();
66 rands = RANDS;
67
68 ap = TMP_ALLOC_LIMBS (MAX_AN);
69 bp = TMP_ALLOC_LIMBS (MAX_BN(MAX_AN));
70 refp = TMP_ALLOC_LIMBS (MAX_AN + MAX_BN(MAX_AN));
71 pp = 1+TMP_ALLOC_LIMBS (MAX_AN + MAX_BN(MAX_AN)+2);
72 scratch
73 = 1+TMP_ALLOC_LIMBS (mpn_toomMN_mul_itch (MAX_AN, MAX_BN(MAX_AN))
74 + 2);
75
76 for (test = 0; test < count; test++)
77 {
78 unsigned size_min;
79 unsigned size_range;
80 mp_size_t an, bn;
81 mp_size_t itch;
82 mp_limb_t p_before, p_after, s_before, s_after;
83
84 for (size_min = 1; (1L << size_min) < MIN_AN; size_min++)
85 ;
86
87 /* We generate an in the MIN_AN <= an <= (1 << size_range). */
88 size_range = size_min
89 + gmp_urandomm_ui (rands, SIZE_LOG + 1 - size_min);
90
91 an = MIN_AN
92 + gmp_urandomm_ui (rands, (1L << size_range) + 1 - MIN_AN);
93 bn = MIN_BN(an)
94 + gmp_urandomm_ui (rands, MAX_BN(an) + 1 - MIN_BN(an));
95
96 mpn_random2 (ap, an);
97 mpn_random2 (bp, bn);
98 mpn_random2 (pp-1, an + bn + 2);
99 p_before = pp[-1];
100 p_after = pp[an + bn];
101
102 itch = mpn_toomMN_mul_itch (an, bn);
103 ASSERT_ALWAYS (itch <= mpn_toomMN_mul_itch (MAX_AN, MAX_BN(MAX_AN)));
104 mpn_random2 (scratch-1, itch+2);
105 s_before = scratch[-1];
106 s_after = scratch[itch];
107
108 mpn_toomMN_mul (pp, ap, an, bp, bn, scratch);
109 refmpn_mul (refp, ap, an, bp, bn);
110 if (pp[-1] != p_before || pp[an + bn] != p_after
111 || scratch[-1] != s_before || scratch[itch] != s_after
112 || mpn_cmp (refp, pp, an + bn) != 0)
113 {
114 printf ("ERROR in test %d, an = %d, bn = %d\n",
115 test, (int) an, (int) bn);
116 if (pp[-1] != p_before)
117 {
118 printf ("before pp:"); mpn_dump (pp -1, 1);
119 printf ("keep: "); mpn_dump (&p_before, 1);
120 }
121 if (pp[an + bn] != p_after)
122 {
123 printf ("after pp:"); mpn_dump (pp + an + bn, 1);
124 printf ("keep: "); mpn_dump (&p_after, 1);
125 }
126 if (scratch[-1] != s_before)
127 {
128 printf ("before scratch:"); mpn_dump (scratch-1, 1);
129 printf ("keep: "); mpn_dump (&s_before, 1);
130 }
131 if (scratch[itch] != s_after)
132 {
133 printf ("after scratch:"); mpn_dump (scratch + itch, 1);
134 printf ("keep: "); mpn_dump (&s_after, 1);
135 }
136 mpn_dump (ap, an);
137 mpn_dump (bp, bn);
138 mpn_dump (pp, an + bn);
139 mpn_dump (refp, an + bn);
140
141 abort();
142 }
143 }
144 TMP_FREE;
145
146 tests_end ();
147 return 0;
148}