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