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