gen-fac.c revision 1.1.1.3 1 1.1 mrg /* Generate data for combinatorics: fac_ui, bin_uiui, ...
2 1.1 mrg
3 1.1.1.3 mrg Copyright 2002, 2011-2016 Free Software Foundation, Inc.
4 1.1 mrg
5 1.1 mrg This file is part of the GNU MP Library.
6 1.1 mrg
7 1.1 mrg The GNU MP Library is free software; you can redistribute it and/or modify
8 1.1.1.2 mrg it under the terms of either:
9 1.1.1.2 mrg
10 1.1.1.2 mrg * the GNU Lesser General Public License as published by the Free
11 1.1.1.2 mrg Software Foundation; either version 3 of the License, or (at your
12 1.1.1.2 mrg option) any later version.
13 1.1.1.2 mrg
14 1.1.1.2 mrg or
15 1.1.1.2 mrg
16 1.1.1.2 mrg * the GNU General Public License as published by the Free Software
17 1.1.1.2 mrg Foundation; either version 2 of the License, or (at your option) any
18 1.1.1.2 mrg later version.
19 1.1.1.2 mrg
20 1.1.1.2 mrg or both in parallel, as here.
21 1.1 mrg
22 1.1 mrg The GNU MP Library is distributed in the hope that it will be useful, but
23 1.1 mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
24 1.1.1.2 mrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25 1.1.1.2 mrg for more details.
26 1.1 mrg
27 1.1.1.2 mrg You should have received copies of the GNU General Public License and the
28 1.1.1.2 mrg GNU Lesser General Public License along with the GNU MP Library. If not,
29 1.1.1.2 mrg see https://www.gnu.org/licenses/. */
30 1.1 mrg
31 1.1 mrg #include <stdio.h>
32 1.1 mrg #include <stdlib.h>
33 1.1 mrg
34 1.1 mrg #include "bootstrap.c"
35 1.1 mrg
36 1.1 mrg int
37 1.1 mrg mpz_remove_twos (mpz_t x)
38 1.1 mrg {
39 1.1.1.2 mrg mp_bitcnt_t r = mpz_scan1(x, 0);
40 1.1.1.2 mrg mpz_tdiv_q_2exp (x, x, r);
41 1.1 mrg return r;
42 1.1 mrg }
43 1.1 mrg
44 1.1 mrg /* returns 0 on success */
45 1.1 mrg int
46 1.1.1.3 mrg gen_consts (unsigned numb, unsigned limb)
47 1.1 mrg {
48 1.1 mrg mpz_t x, mask, y, last;
49 1.1 mrg unsigned long a, b;
50 1.1 mrg unsigned long ofl, ofe;
51 1.1 mrg
52 1.1 mrg printf ("/* This file is automatically generated by gen-fac.c */\n\n");
53 1.1.1.3 mrg printf ("#if GMP_NUMB_BITS != %u\n", numb);
54 1.1.1.3 mrg printf ("Error , error this data is for %u GMP_NUMB_BITS only\n", numb);
55 1.1 mrg printf ("#endif\n");
56 1.1 mrg #if 0
57 1.1.1.3 mrg printf ("#if GMP_LIMB_BITS != %u\n", limb);
58 1.1.1.3 mrg printf ("Error , error this data is for %u GMP_LIMB_BITS only\n", limb);
59 1.1 mrg printf ("#endif\n");
60 1.1 mrg #endif
61 1.1 mrg
62 1.1 mrg printf
63 1.1 mrg ("/* This table is 0!,1!,2!,3!,...,n! where n! has <= GMP_NUMB_BITS bits */\n");
64 1.1 mrg printf
65 1.1 mrg ("#define ONE_LIMB_FACTORIAL_TABLE CNST_LIMB(0x1),CNST_LIMB(0x1");
66 1.1 mrg mpz_init_set_ui (x, 1);
67 1.1 mrg mpz_init (last);
68 1.1 mrg for (b = 2;; b++)
69 1.1 mrg {
70 1.1 mrg mpz_mul_ui (x, x, b); /* so b!=a */
71 1.1 mrg if (mpz_sizeinbase (x, 2) > numb)
72 1.1 mrg break;
73 1.1 mrg printf ("),CNST_LIMB(0x");
74 1.1 mrg mpz_out_str (stdout, 16, x);
75 1.1 mrg }
76 1.1 mrg printf (")\n");
77 1.1 mrg
78 1.1 mrg printf
79 1.1 mrg ("\n/* This table is 0!,1!,2!/2,3!/2,...,n!/2^sn where n!/2^sn is an */\n");
80 1.1 mrg printf
81 1.1 mrg ("/* odd integer for each n, and n!/2^sn has <= GMP_NUMB_BITS bits */\n");
82 1.1 mrg printf
83 1.1 mrg ("#define ONE_LIMB_ODD_FACTORIAL_TABLE CNST_LIMB(0x1),CNST_LIMB(0x1),CNST_LIMB(0x1");
84 1.1 mrg mpz_set_ui (x, 1);
85 1.1 mrg for (b = 3;; b++)
86 1.1 mrg {
87 1.1 mrg for (a = b; (a & 1) == 0; a >>= 1);
88 1.1.1.2 mrg mpz_swap (last, x);
89 1.1.1.2 mrg mpz_mul_ui (x, last, a);
90 1.1 mrg if (mpz_sizeinbase (x, 2) > numb)
91 1.1 mrg break;
92 1.1 mrg printf ("),CNST_LIMB(0x");
93 1.1 mrg mpz_out_str (stdout, 16, x);
94 1.1 mrg }
95 1.1 mrg printf (")\n");
96 1.1 mrg printf
97 1.1 mrg ("#define ODD_FACTORIAL_TABLE_MAX CNST_LIMB(0x");
98 1.1 mrg mpz_out_str (stdout, 16, last);
99 1.1 mrg printf (")\n");
100 1.1 mrg
101 1.1 mrg ofl = b - 1;
102 1.1 mrg printf
103 1.1 mrg ("#define ODD_FACTORIAL_TABLE_LIMIT (%lu)\n", ofl);
104 1.1.1.3 mrg mpz_init (mask);
105 1.1 mrg mpz_setbit (mask, numb);
106 1.1 mrg mpz_sub_ui (mask, mask, 1);
107 1.1 mrg printf
108 1.1 mrg ("\n/* Previous table, continued, values modulo 2^GMP_NUMB_BITS */\n");
109 1.1 mrg printf
110 1.1 mrg ("#define ONE_LIMB_ODD_FACTORIAL_EXTTABLE CNST_LIMB(0x");
111 1.1 mrg mpz_and (x, x, mask);
112 1.1 mrg mpz_out_str (stdout, 16, x);
113 1.1 mrg mpz_init (y);
114 1.1 mrg mpz_bin_uiui (y, b, b/2);
115 1.1 mrg b++;
116 1.1 mrg for (;; b++)
117 1.1 mrg {
118 1.1 mrg for (a = b; (a & 1) == 0; a >>= 1);
119 1.1 mrg if (a == b) {
120 1.1 mrg mpz_divexact_ui (y, y, a/2+1);
121 1.1 mrg mpz_mul_ui (y, y, a);
122 1.1 mrg } else
123 1.1 mrg mpz_mul_2exp (y, y, 1);
124 1.1 mrg if (mpz_sizeinbase (y, 2) > numb)
125 1.1 mrg break;
126 1.1 mrg mpz_mul_ui (x, x, a);
127 1.1 mrg mpz_and (x, x, mask);
128 1.1 mrg printf ("),CNST_LIMB(0x");
129 1.1 mrg mpz_out_str (stdout, 16, x);
130 1.1 mrg }
131 1.1 mrg printf (")\n");
132 1.1 mrg ofe = b - 1;
133 1.1 mrg printf
134 1.1 mrg ("#define ODD_FACTORIAL_EXTTABLE_LIMIT (%lu)\n", ofe);
135 1.1 mrg
136 1.1 mrg printf
137 1.1 mrg ("\n/* This table is 1!!,3!!,...,(2n+1)!! where (2n+1)!! has <= GMP_NUMB_BITS bits */\n");
138 1.1 mrg printf
139 1.1 mrg ("#define ONE_LIMB_ODD_DOUBLEFACTORIAL_TABLE CNST_LIMB(0x1");
140 1.1 mrg mpz_set_ui (x, 1);
141 1.1 mrg for (b = 3;; b+=2)
142 1.1 mrg {
143 1.1.1.2 mrg mpz_swap (last, x);
144 1.1.1.2 mrg mpz_mul_ui (x, last, b);
145 1.1 mrg if (mpz_sizeinbase (x, 2) > numb)
146 1.1 mrg break;
147 1.1 mrg printf ("),CNST_LIMB(0x");
148 1.1 mrg mpz_out_str (stdout, 16, x);
149 1.1 mrg }
150 1.1 mrg printf (")\n");
151 1.1 mrg printf
152 1.1 mrg ("#define ODD_DOUBLEFACTORIAL_TABLE_MAX CNST_LIMB(0x");
153 1.1 mrg mpz_out_str (stdout, 16, last);
154 1.1 mrg printf (")\n");
155 1.1 mrg
156 1.1 mrg printf
157 1.1 mrg ("#define ODD_DOUBLEFACTORIAL_TABLE_LIMIT (%lu)\n", b - 2);
158 1.1 mrg
159 1.1 mrg printf
160 1.1 mrg ("\n/* This table x_1, x_2,... contains values s.t. x_n^n has <= GMP_NUMB_BITS bits */\n");
161 1.1 mrg printf
162 1.1 mrg ("#define NTH_ROOT_NUMB_MASK_TABLE (GMP_NUMB_MASK");
163 1.1 mrg for (b = 2;b <= 8; b++)
164 1.1 mrg {
165 1.1 mrg mpz_root (x, mask, b);
166 1.1 mrg printf ("),CNST_LIMB(0x");
167 1.1 mrg mpz_out_str (stdout, 16, x);
168 1.1 mrg }
169 1.1 mrg printf (")\n");
170 1.1 mrg
171 1.1 mrg mpz_add_ui (mask, mask, 1);
172 1.1 mrg printf
173 1.1 mrg ("\n/* This table contains inverses of odd factorials, modulo 2^GMP_NUMB_BITS */\n");
174 1.1 mrg printf
175 1.1 mrg ("\n/* It begins with (2!/2)^-1=1 */\n");
176 1.1 mrg printf
177 1.1 mrg ("#define ONE_LIMB_ODD_FACTORIAL_INVERSES_TABLE CNST_LIMB(0x1");
178 1.1 mrg mpz_set_ui (x, 1);
179 1.1 mrg for (b = 3;b <= ofe - 2; b++)
180 1.1 mrg {
181 1.1 mrg for (a = b; (a & 1) == 0; a >>= 1);
182 1.1 mrg mpz_mul_ui (x, x, a);
183 1.1 mrg mpz_invert (y, x, mask);
184 1.1 mrg printf ("),CNST_LIMB(0x");
185 1.1 mrg mpz_out_str (stdout, 16, y);
186 1.1 mrg }
187 1.1 mrg printf (")\n");
188 1.1 mrg
189 1.1 mrg ofe = (ofe / 16 + 1) * 16;
190 1.1 mrg
191 1.1 mrg printf
192 1.1 mrg ("\n/* This table contains 2n-popc(2n) for small n */\n");
193 1.1 mrg printf
194 1.1 mrg ("\n/* It begins with 2-1=1 (n=1) */\n");
195 1.1 mrg printf
196 1.1 mrg ("#define TABLE_2N_MINUS_POPC_2N 1");
197 1.1 mrg for (b = 4; b <= ofe; b += 2)
198 1.1 mrg {
199 1.1 mrg mpz_set_ui (x, b);
200 1.1 mrg printf (",%lu",b - mpz_popcount (x));
201 1.1 mrg }
202 1.1 mrg printf ("\n");
203 1.1 mrg printf
204 1.1 mrg ("#define TABLE_LIMIT_2N_MINUS_POPC_2N %lu\n", ofe + 1);
205 1.1 mrg
206 1.1 mrg
207 1.1 mrg ofl = (ofl + 1) / 2;
208 1.1 mrg printf
209 1.1 mrg ("#define ODD_CENTRAL_BINOMIAL_OFFSET (%lu)\n", ofl);
210 1.1 mrg printf
211 1.1 mrg ("\n/* This table contains binomial(2k,k)/2^t */\n");
212 1.1 mrg printf
213 1.1 mrg ("\n/* It begins with ODD_CENTRAL_BINOMIAL_TABLE_MIN */\n");
214 1.1 mrg printf
215 1.1 mrg ("#define ONE_LIMB_ODD_CENTRAL_BINOMIAL_TABLE ");
216 1.1 mrg for (b = ofl;; b++)
217 1.1 mrg {
218 1.1 mrg mpz_bin_uiui (x, 2 * b, b);
219 1.1 mrg mpz_remove_twos (x);
220 1.1 mrg if (mpz_sizeinbase (x, 2) > numb)
221 1.1 mrg break;
222 1.1 mrg if (b != ofl)
223 1.1 mrg printf ("),");
224 1.1 mrg printf("CNST_LIMB(0x");
225 1.1 mrg mpz_out_str (stdout, 16, x);
226 1.1 mrg }
227 1.1 mrg printf (")\n");
228 1.1 mrg
229 1.1 mrg ofe = b - 1;
230 1.1 mrg printf
231 1.1 mrg ("#define ODD_CENTRAL_BINOMIAL_TABLE_LIMIT (%lu)\n", ofe);
232 1.1 mrg
233 1.1 mrg printf
234 1.1 mrg ("\n/* This table contains the inverses of elements in the previous table. */\n");
235 1.1 mrg printf
236 1.1 mrg ("#define ONE_LIMB_ODD_CENTRAL_BINOMIAL_INVERSE_TABLE CNST_LIMB(0x");
237 1.1 mrg for (b = ofl; b <= ofe; b++)
238 1.1 mrg {
239 1.1 mrg mpz_bin_uiui (x, 2 * b, b);
240 1.1 mrg mpz_remove_twos (x);
241 1.1 mrg mpz_invert (x, x, mask);
242 1.1 mrg mpz_out_str (stdout, 16, x);
243 1.1 mrg if (b != ofe)
244 1.1 mrg printf ("),CNST_LIMB(0x");
245 1.1 mrg }
246 1.1 mrg printf (")\n");
247 1.1 mrg
248 1.1 mrg printf
249 1.1 mrg ("\n/* This table contains the values t in the formula binomial(2k,k)/2^t */\n");
250 1.1 mrg printf
251 1.1 mrg ("#define CENTRAL_BINOMIAL_2FAC_TABLE ");
252 1.1 mrg for (b = ofl; b <= ofe; b++)
253 1.1 mrg {
254 1.1 mrg mpz_bin_uiui (x, 2 * b, b);
255 1.1 mrg printf ("%d", mpz_remove_twos (x));
256 1.1 mrg if (b != ofe)
257 1.1 mrg printf (",");
258 1.1 mrg }
259 1.1 mrg printf ("\n");
260 1.1 mrg
261 1.1 mrg return 0;
262 1.1 mrg }
263 1.1 mrg
264 1.1 mrg int
265 1.1 mrg main (int argc, char *argv[])
266 1.1 mrg {
267 1.1 mrg int nail_bits, limb_bits, numb_bits;
268 1.1 mrg
269 1.1 mrg if (argc != 3)
270 1.1 mrg {
271 1.1.1.2 mrg fprintf (stderr, "Usage: gen-fac limbbits nailbits\n");
272 1.1 mrg exit (1);
273 1.1 mrg }
274 1.1 mrg limb_bits = atoi (argv[1]);
275 1.1 mrg nail_bits = atoi (argv[2]);
276 1.1 mrg numb_bits = limb_bits - nail_bits;
277 1.1 mrg if (limb_bits < 2 || nail_bits < 0 || numb_bits < 1)
278 1.1 mrg {
279 1.1 mrg fprintf (stderr, "Invalid limb/nail bits %d,%d\n", limb_bits,
280 1.1 mrg nail_bits);
281 1.1 mrg exit (1);
282 1.1 mrg }
283 1.1.1.3 mrg gen_consts (numb_bits, limb_bits);
284 1.1 mrg return 0;
285 1.1 mrg }
286