1 /*
2    mpn_mulmid-test.c:  test code for functions in mpn_mulmid.c
3 
4    Copyright (C) 2007, 2008, David Harvey
5 
6    This file is part of the zn_poly library (version 0.9).
7 
8    This program is free software: you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation, either version 2 of the License, or
11    (at your option) version 3 of the License.
12 
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #include "support.h"
24 #include "zn_poly_internal.h"
25 #include <string.h>
26 
27 
28 /*
29    Tests mpn_smp for given n1 >= n2 >= 1.
30 */
31 int
testcase_mpn_smp_basecase(size_t n1,size_t n2)32 testcase_mpn_smp_basecase (size_t n1, size_t n2)
33 {
34    size_t n3 = n1 - n2 + 3;
35    mp_limb_t* buf1 = (mp_limb_t*) malloc (sizeof (mp_limb_t) * n1);
36    mp_limb_t* buf2 = (mp_limb_t*) malloc (sizeof (mp_limb_t) * n2);
37    mp_limb_t* ref = (mp_limb_t*) malloc (sizeof (mp_limb_t) * n3);
38    mp_limb_t* res = (mp_limb_t*) malloc (sizeof (mp_limb_t) * n3);
39 
40    // generate random inputs
41    ZNP_mpn_random2 (buf1, n1);
42    ZNP_mpn_random2 (buf2, n2);
43 
44    // compare target against reference implementation
45    ZNP_mpn_smp_basecase (res, buf1, n1, buf2, n2);
46    ref_mpn_smp (ref, buf1, n1, buf2, n2);
47    int success = !mpn_cmp (ref, res, n3);
48 
49    free (res);
50    free (ref);
51    free (buf2);
52    free (buf1);
53 
54    return success;
55 }
56 
57 
58 /*
59    Tests mpn_smp for a range of n1, n2.
60 */
61 int
test_mpn_smp_basecase(int quick)62 test_mpn_smp_basecase (int quick)
63 {
64    int success = 1;
65    size_t n1, n2;
66    ulong trial;
67 
68    for (n2 = 1; n2 <= 30 && success; n2++)
69    for (n1 = n2; n1 <= 30 && success; n1++)
70    for (trial = 0; trial < (quick ? 30 : 3000) && success; trial++)
71       success = success && testcase_mpn_smp_basecase (n1, n2);
72 
73    return success;
74 }
75 
76 
77 /*
78    Tests mpn_smp_kara for given n.
79 */
80 #if GMP_NAIL_BITS == 0 && ULONG_BITS == GMP_NUMB_BITS
81 int
testcase_mpn_smp_kara(size_t n)82 testcase_mpn_smp_kara (size_t n)
83 {
84    mp_limb_t* buf1 = malloc (sizeof (mp_limb_t) * (2 * n - 1));
85    mp_limb_t* buf2 = malloc (sizeof (mp_limb_t) * n);
86    mp_limb_t* ref = malloc (sizeof (mp_limb_t) * (n + 2));
87    mp_limb_t* res = malloc (sizeof (mp_limb_t) * (n + 2));
88 
89    // generate random inputs
90    ZNP_mpn_random2 (buf1, 2 * n - 1);
91    ZNP_mpn_random2 (buf2, n);
92 
93    // compare target against reference implementation
94    ZNP_mpn_smp_kara (res, buf1, buf2, n);
95    ref_mpn_smp (ref, buf1, 2 * n - 1, buf2, n);
96    int success = !zn_array_cmp ((ulong*) ref, (ulong*)res, n + 2);
97 
98    free (res);
99    free (ref);
100    free (buf2);
101    free (buf1);
102 
103    return success;
104 }
105 #else
106 #error Not nails-safe yet
107 #endif
108 
109 
110 /*
111    Tests mpn_smp_kara for a range of n.
112 */
113 int
test_mpn_smp_kara(int quick)114 test_mpn_smp_kara (int quick)
115 {
116    int success = 1;
117    size_t n;
118    ulong trial;
119 
120    // first a dense range of small problems
121    for (n = 2; n <= 30 && success; n++)
122    for (trial = 0; trial < (quick ? 300 : 30000) && success; trial++)
123       success = success && testcase_mpn_smp_kara (n);
124 
125    // now a few larger problems too
126    for (trial = 0; trial < (quick ? 100 : 3000) && success; trial++)
127    {
128       if (ZNP_mpn_smp_kara_thresh == SIZE_MAX)
129          n = random_ulong (100) + 2;
130       else
131          n = random_ulong (3 * ZNP_mpn_smp_kara_thresh) + 2;
132       success = success && testcase_mpn_smp_kara (n);
133    }
134 
135    return success;
136 }
137 
138 
139 #if GMP_NAIL_BITS == 0 && ULONG_BITS == GMP_NUMB_BITS
140 int
testcase_mpn_smp(size_t n1,size_t n2)141 testcase_mpn_smp (size_t n1, size_t n2)
142 {
143    size_t n3 = n1 - n2 + 3;
144    mp_limb_t* buf1 = malloc (sizeof (mp_limb_t) * n1);
145    mp_limb_t* buf2 = malloc (sizeof (mp_limb_t) * n2);
146    mp_limb_t* ref = malloc (sizeof (mp_limb_t) * n3);
147    mp_limb_t* res = malloc (sizeof (mp_limb_t) * n3);
148 
149    // generate random inputs
150    ZNP_mpn_random2 (buf1, n1);
151    ZNP_mpn_random2 (buf2, n2);
152 
153    // temporarily lower the karatsuba threshold for more stringent testing
154    unsigned long temp_thresh = ZNP_mpn_smp_kara_thresh;
155    ZNP_mpn_smp_kara_thresh = 5;
156 
157    // compare target against reference implementation
158    ZNP_mpn_smp (res, buf1, n1, buf2, n2);
159    ref_mpn_smp (ref, buf1, n1, buf2, n2);
160    int success = !zn_array_cmp ((ulong*) ref, (ulong*) res, n3);
161 
162    ZNP_mpn_smp_kara_thresh = temp_thresh;
163 
164    free (res);
165    free (ref);
166    free (buf2);
167    free (buf1);
168 
169    return success;
170 }
171 #else
172 #error Not nails-safe yet
173 #endif
174 
175 
176 /*
177    Tests mpn_smp for a range of n1, n2.
178 */
179 int
test_mpn_smp(int quick)180 test_mpn_smp (int quick)
181 {
182    int success = 1;
183    size_t n1, n2;
184    ulong trial;
185 
186    for (n2 = 1; n2 <= 30 && success; n2++)
187    for (n1 = n2; n1 <= 30 && success; n1++)
188    for (trial = 0; trial < (quick ? 30 : 3000) && success; trial++)
189       success = success && testcase_mpn_smp (n1, n2);
190 
191    return success;
192 }
193 
194 
195 
196 int
testcase_mpn_mulmid(size_t n1,size_t n2)197 testcase_mpn_mulmid (size_t n1, size_t n2)
198 {
199    size_t n3 = n1 - n2 + 3;
200    mp_limb_t* buf1 = (mp_limb_t*) malloc (sizeof (mp_limb_t) * n1);
201    mp_limb_t* buf2 = (mp_limb_t*) malloc (sizeof (mp_limb_t) * n2);
202    mp_limb_t* ref = (mp_limb_t*) malloc (sizeof (mp_limb_t) * n3);
203    mp_limb_t* res = (mp_limb_t*) malloc (sizeof (mp_limb_t) * n3);
204 
205    // generate random inputs
206    ZNP_mpn_random2 (buf1, n1);
207    ZNP_mpn_random2 (buf2, n2);
208 
209    // compare target against reference implementation
210    ZNP_mpn_mulmid (res, buf1, n1, buf2, n2);
211    ref_mpn_mulmid (ref, buf1, n1, buf2, n2);
212    int success = (n3 <= 4) || !mpn_cmp (ref + 2, res + 2, n3 - 4);
213 
214    free (res);
215    free (ref);
216    free (buf2);
217    free (buf1);
218 
219    return success;
220 }
221 
222 
223 
224 /*
225    Tests mpn_mulmid for a range of n1, n2.
226 */
227 int
test_mpn_mulmid(int quick)228 test_mpn_mulmid (int quick)
229 {
230    int success = 1;
231    size_t n1, n2;
232    ulong trial;
233 
234    for (n2 = 1; n2 <= 30 && success; n2++)
235    for (n1 = n2; n1 <= 30 && success; n1++)
236    for (trial = 0; trial < (quick ? 30 : 3000) && success; trial++)
237       success = success && testcase_mpn_mulmid (n1, n2);
238 
239    return success;
240 }
241 
242 
243 // end of file ****************************************************************
244