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