Home | History | Annotate | Line # | Download | only in dist
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