1 /* Test for various Toom functions.
3 Copyright 2009 Free Software Foundation, Inc.
5 This file is part of the GNU MP Library test suite.
7 The GNU MP Library test suite is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 3 of the License,
10 or (at your option) any later version.
12 The GNU MP Library test suite is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15 Public License for more details.
17 You should have received a copy of the GNU General Public License along with
18 the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */
28 /* Main file is expected to define mpn_toomMN_mul,
29 * mpn_toomMN_mul_itch, MIN_AN, MIN_BN(an), MAX_BN(an) and then
30 * include this file. */
32 /* Sizes are up to 2^SIZE_LOG limbs */
41 #define MAX_AN (1L << SIZE_LOG)
44 #define MAX_BN(an) (an)
47 /* For general toomMN_mul, we need
49 * MIN_BN(an) = N + floor(((N-1)*an + M - N)/M)
51 * MAX_BN(an) = floor(N*(an-1)/(M-1)) - N + 1
55 main (int argc, char **argv)
57 mp_ptr ap, bp, refp, pp, scratch;
60 gmp_randstate_ptr rands;
67 count = strtol (argv[1], &end, 0);
68 if (*end || count <= 0)
70 fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
78 ap = TMP_ALLOC_LIMBS (MAX_AN);
79 bp = TMP_ALLOC_LIMBS (MAX_BN(MAX_AN));
80 refp = TMP_ALLOC_LIMBS (MAX_AN + MAX_BN(MAX_AN));
81 pp = 1+TMP_ALLOC_LIMBS (MAX_AN + MAX_BN(MAX_AN)+2);
83 = 1+TMP_ALLOC_LIMBS (mpn_toomMN_mul_itch (MAX_AN, MAX_BN(MAX_AN))
86 for (test = 0; test < count; test++)
92 mp_limb_t p_before, p_after, s_before, s_after;
94 for (size_min = 1; (1L << size_min) < MIN_AN; size_min++)
97 /* We generate an in the MIN_AN <= an <= (1 << size_range). */
99 + gmp_urandomm_ui (rands, SIZE_LOG + 1 - size_min);
102 + gmp_urandomm_ui (rands, (1L << size_range) + 1 - MIN_AN);
104 + gmp_urandomm_ui (rands, MAX_BN(an) + 1 - MIN_BN(an));
106 mpn_random2 (ap, an);
107 mpn_random2 (bp, bn);
108 mpn_random2 (pp-1, an + bn + 2);
110 p_after = pp[an + bn];
112 itch = mpn_toomMN_mul_itch (an, bn);
113 ASSERT_ALWAYS (itch <= mpn_toomMN_mul_itch (MAX_AN, MAX_BN(MAX_AN)));
114 mpn_random2 (scratch-1, itch+2);
115 s_before = scratch[-1];
116 s_after = scratch[itch];
118 mpn_toomMN_mul (pp, ap, an, bp, bn, scratch);
119 refmpn_mul (refp, ap, an, bp, bn);
120 if (pp[-1] != p_before || pp[an + bn] != p_after
121 || scratch[-1] != s_before || scratch[itch] != s_after
122 || mpn_cmp (refp, pp, an + bn) != 0)
124 printf ("ERROR in test %d, an = %d, bn = %d\n",
125 test, (int) an, (int) bn);
126 if (pp[-1] != p_before)
128 printf ("before pp:"); mpn_dump (pp -1, 1);
129 printf ("keep: "); mpn_dump (&p_before, 1);
131 if (pp[an + bn] != p_after)
133 printf ("after pp:"); mpn_dump (pp + an + bn, 1);
134 printf ("keep: "); mpn_dump (&p_after, 1);
136 if (scratch[-1] != s_before)
138 printf ("before scratch:"); mpn_dump (scratch-1, 1);
139 printf ("keep: "); mpn_dump (&s_before, 1);
141 if (scratch[itch] != s_after)
143 printf ("after scratch:"); mpn_dump (scratch + itch, 1);
144 printf ("keep: "); mpn_dump (&s_after, 1);
148 mpn_dump (pp, an + bn);
149 mpn_dump (refp, an + bn);