[Gmp-commit] /var/hg/gmp: 3 new changesets

mercurial at gmplib.org mercurial at gmplib.org
Thu Apr 19 11:29:43 CEST 2012


details:   /var/hg/gmp/rev/64ebc7ede850
changeset: 14854:64ebc7ede850
user:      Marco Bodrato <bodrato at mail.dm.unipi.it>
date:      Thu Apr 19 11:16:57 2012 +0200
description:
New function mpz_primorial_ui.

details:   /var/hg/gmp/rev/5b37ef7b9236
changeset: 14855:5b37ef7b9236
user:      Marco Bodrato <bodrato at mail.dm.unipi.it>
date:      Thu Apr 19 11:21:28 2012 +0200
description:
Test for primorial.

details:   /var/hg/gmp/rev/692bc6eee88d
changeset: 14856:692bc6eee88d
user:      Marco Bodrato <bodrato at mail.dm.unipi.it>
date:      Thu Apr 19 11:29:36 2012 +0200
description:
doc/gmp.texi: Short documentation for the new function.

diffstat:

 ChangeLog                  |    8 ++
 Makefile.am                |    3 +-
 doc/gmp.texi               |    6 +
 gmp-h.in                   |    3 +
 mpz/Makefile.am            |    2 +-
 mpz/bin_uiui.c             |    2 +-
 mpz/primorial_ui.c         |  162 +++++++++++++++++++++++++++++++++++++++++++++
 tests/mpz/Makefile.am      |    2 +-
 tests/mpz/t-primorial_ui.c |   97 ++++++++++++++++++++++++++
 9 files changed, 281 insertions(+), 4 deletions(-)

diffs (truncated from 363 to 300 lines):

diff -r 7df54aea7a96 -r 692bc6eee88d ChangeLog
--- a/ChangeLog	Thu Apr 19 09:43:14 2012 +0200
+++ b/ChangeLog	Thu Apr 19 11:29:36 2012 +0200
@@ -9,6 +9,14 @@
 	implementation.
 	* tests/mpz/t-bin.c: Extend tests, to cover _goetgheluck.
 
+	* mpz/primorial_ui.c: New file.
+	* mpz/Makefile.am (libmpz_la_SOURCES): Add mpz/primorial_ui.c
+	* Makefile.am (MPZ_OBJECTS): Add mpz/primorial_ui$U.lo
+	* gmp-h.in (mpz_primorial_ui): Declare.
+	* tests/mpz/t-primorial_ui.c: New test for the new function.
+	* tests/mpz/Makefile.am (check_PROGRAMS): Add t-primorial_ui.
+	* doc/gmp.texi: Short documentation for the new function.
+
 2012-04-17  Torbjorn Granlund  <tege at gmplib.org>
 
 	* mpn/x86_64/coreisbr/aorsmul_1.asm: Fix some DOS64 issues.
diff -r 7df54aea7a96 -r 692bc6eee88d Makefile.am
--- a/Makefile.am	Thu Apr 19 09:43:14 2012 +0200
+++ b/Makefile.am	Thu Apr 19 11:29:36 2012 +0200
@@ -178,7 +178,8 @@
   mpz/n_pow_ui$U.lo mpz/neg$U.lo mpz/nextprime$U.lo			\
   mpz/out_raw$U.lo mpz/out_str$U.lo mpz/perfpow$U.lo mpz/perfsqr$U.lo	\
   mpz/popcount$U.lo mpz/pow_ui$U.lo mpz/powm$U.lo mpz/powm_sec$U.lo	\
-  mpz/powm_ui$U.lo mpz/pprime_p$U.lo mpz/random$U.lo mpz/random2$U.lo	\
+  mpz/powm_ui$U.lo mpz/primorial_ui$U.lo				\
+  mpz/pprime_p$U.lo mpz/random$U.lo mpz/random2$U.lo			\
   mpz/realloc$U.lo mpz/realloc2$U.lo mpz/remove$U.lo			\
   mpz/root$U.lo mpz/rootrem$U.lo mpz/rrandomb$U.lo mpz/scan0$U.lo	\
   mpz/scan1$U.lo mpz/set$U.lo mpz/set_d$U.lo mpz/set_f$U.lo		\
diff -r 7df54aea7a96 -r 692bc6eee88d doc/gmp.texi
--- a/doc/gmp.texi	Thu Apr 19 09:43:14 2012 +0200
+++ b/doc/gmp.texi	Thu Apr 19 11:29:36 2012 +0200
@@ -3641,6 +3641,12 @@
 Set @var{rop} to @var{op}!!, the double-factorial of @var{op}.
 @end deftypefun
 
+ at deftypefun void mpz_primorial_ui (mpz_t @var{rop}, unsigned long int @var{op})
+ at cindex Factorial functions
+Set @var{rop} to the primorial of @var{op}, i.e. the product of all positive
+prime numbers smaller then or equal to @var{op}.
+ at end deftypefun
+
 @deftypefun void mpz_bin_ui (mpz_t @var{rop}, mpz_t @var{n}, unsigned long int @var{k})
 @deftypefunx void mpz_bin_uiui (mpz_t @var{rop}, unsigned long int @var{n}, @w{unsigned long int @var{k}})
 @cindex Binomial coefficient functions
diff -r 7df54aea7a96 -r 692bc6eee88d gmp-h.in
--- a/gmp-h.in	Thu Apr 19 09:43:14 2012 +0200
+++ b/gmp-h.in	Thu Apr 19 11:29:36 2012 +0200
@@ -752,6 +752,9 @@
 #define mpz_2fac_ui __gmpz_2fac_ui
 __GMP_DECLSPEC void mpz_2fac_ui (mpz_ptr, unsigned long int);
 
+#define mpz_primorial_ui __gmpz_primorial_ui
+__GMP_DECLSPEC void mpz_primorial_ui (mpz_ptr, unsigned long int);
+
 #define mpz_fdiv_q __gmpz_fdiv_q
 __GMP_DECLSPEC void mpz_fdiv_q (mpz_ptr, mpz_srcptr, mpz_srcptr);
 
diff -r 7df54aea7a96 -r 692bc6eee88d mpz/Makefile.am
--- a/mpz/Makefile.am	Thu Apr 19 09:43:14 2012 +0200
+++ b/mpz/Makefile.am	Thu Apr 19 11:29:36 2012 +0200
@@ -47,7 +47,7 @@
   mod.c mul.c mul_2exp.c mul_si.c mul_ui.c n_pow_ui.c neg.c nextprime.c \
   oddfac_1.c \
   out_raw.c out_str.c perfpow.c perfsqr.c popcount.c pow_ui.c powm.c \
-  powm_sec.c powm_ui.c pprime_p.c prodlimbs.c random.c random2.c \
+  powm_sec.c powm_ui.c pprime_p.c prodlimbs.c primorial_ui.c random.c random2.c \
   realloc.c realloc2.c remove.c root.c rootrem.c rrandomb.c \
   scan0.c scan1.c set.c set_d.c set_f.c set_q.c set_si.c set_str.c \
   set_ui.c setbit.c size.c sizeinbase.c sqrt.c sqrtrem.c sub.c sub_ui.c \
diff -r 7df54aea7a96 -r 692bc6eee88d mpz/bin_uiui.c
--- a/mpz/bin_uiui.c	Thu Apr 19 09:43:14 2012 +0200
+++ b/mpz/bin_uiui.c	Thu Apr 19 11:29:36 2012 +0200
@@ -524,7 +524,7 @@
 primesieve_size (mp_limb_t n) { return n_to_bit(n) / GMP_LIMB_BITS + 1; }
 
 /*********************************************************/
-/* Section binomial: fast binomial implementations       */
+/* Section binomial: fast binomial implementation        */
 /*********************************************************/
 
 #define COUNT_A_PRIME(P, N, K, PR, MAX_PR, VEC, I)	\
diff -r 7df54aea7a96 -r 692bc6eee88d mpz/primorial_ui.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mpz/primorial_ui.c	Thu Apr 19 11:29:36 2012 +0200
@@ -0,0 +1,162 @@
+/* mpz_primorial_ui(RESULT, N) -- Set RESULT to N# the product of primes <= N.
+
+Contributed to the GNU project by Marco Bodrato.
+
+Copyright 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* TODO: Remove duplicated constants / macros / static functions...
+ */
+#include "fac_ui.h"
+
+/*************************************************************/
+/* Section macros: common macros, for swing/fac/bin (&sieve) */
+/*************************************************************/
+
+#define FACTOR_LIST_STORE(P, PR, MAX_PR, VEC, I)		\
+  do {								\
+    if ((PR) > (MAX_PR)) {					\
+      (VEC)[(I)++] = (PR);					\
+      (PR) = (P);						\
+    } else							\
+      (PR) *= (P);						\
+  } while (0)
+
+#define LOOP_ON_SIEVE_CONTINUE(prime,end,sieve)			\
+    __max_i = (end);						\
+								\
+    do {							\
+      ++__i;							\
+      if (((sieve)[__index] & __mask) == 0)			\
+	{							\
+	  (prime) = id_to_n(__i)
+
+#define LOOP_ON_SIEVE_BEGIN(prime,start,end,off,sieve)		\
+  do {								\
+    mp_limb_t __mask, __index, __max_i, __i;			\
+								\
+    __i = (start)-(off);					\
+    __index = __i / GMP_LIMB_BITS;				\
+    __mask = CNST_LIMB(1) << (__i % GMP_LIMB_BITS);		\
+    __i += (off);						\
+								\
+    LOOP_ON_SIEVE_CONTINUE(prime,end,sieve)
+
+#define LOOP_ON_SIEVE_STOP					\
+	}							\
+      __mask = __mask << 1 | __mask >> (GMP_LIMB_BITS-1);	\
+      __index += __mask & 1;					\
+    }  while (__i <= __max_i)					\
+
+#define LOOP_ON_SIEVE_END					\
+    LOOP_ON_SIEVE_STOP;						\
+  } while (0)
+
+/*********************************************************/
+/* Section sieve: sieving functions and tools for primes */
+/*********************************************************/
+
+static mp_limb_t
+bit_to_n (mp_limb_t bit) { return (bit*3+4)|1; }
+
+/* id_to_n (x) = bit_to_n (x-1) = (id*3+1)|1*/
+static mp_limb_t
+id_to_n  (mp_limb_t id)  { return id*3+1+(id&1); }
+
+/* n_to_bit (n) = ((n-1)&(-CNST_LIMB(2)))/3U-1 */
+static mp_limb_t
+n_to_bit (mp_limb_t n) { return ((n-5)|1)/3U; }
+
+static mp_size_t
+primesieve_size (mp_limb_t n) { return n_to_bit(n) / GMP_LIMB_BITS + 1; }
+
+/*********************************************************/
+/* Section primorial: implementation                     */
+/*********************************************************/
+
+/* n^log <= GMP_NUMB_MAX, a limb can store log factors less than n */
+static unsigned
+log_n_max (mp_limb_t n)
+{
+  static const mp_limb_t table[] = { NTH_ROOT_NUMB_MASK_TABLE };
+  unsigned log;
+
+  for (log = numberof (table); n > table[log - 1]; log--);
+
+  return log;
+}
+
+void
+mpz_primorial_ui (mpz_ptr x, unsigned long n)
+{
+  static const mp_limb_t table[] = { 1, 1, 2, 6, 6 };
+
+  ASSERT (n <= GMP_NUMB_MAX);
+
+  if (n < numberof (table))
+    {
+      PTR (x)[0] = table[n];
+      SIZ (x) = 1;
+    }
+  else
+    {
+      mp_limb_t *sieve, *factors;
+      mp_size_t size;
+      mp_limb_t prod;
+      mp_limb_t j;
+      TMP_DECL;
+
+      size = 1 + n / GMP_NUMB_BITS + n / (2*GMP_NUMB_BITS);
+      ASSERT (size >= primesieve_size (n));
+      sieve = MPZ_REALLOC (x, size);
+      size = (gmp_primesieve (sieve, n) + 1) / log_n_max (n) + 1;
+
+      TMP_MARK;
+      factors = TMP_ALLOC_LIMBS (size);
+
+      j = 0;
+
+      prod = table[numberof (table)-1];
+
+      /* Store primes from 5 to n */
+      {
+	mp_limb_t prime, max_prod;
+
+	max_prod = GMP_NUMB_MAX / n;
+
+	LOOP_ON_SIEVE_BEGIN (prime, n_to_bit(numberof (table)), n_to_bit (n), 0, sieve);
+	FACTOR_LIST_STORE (prime, prod, max_prod, factors, j);
+	LOOP_ON_SIEVE_END;
+      }
+
+      if (j != 0)
+	{
+	  factors[j++] = prod;
+	  mpz_prodlimbs (x, factors, j);
+	}
+      else
+	{
+	  PTR (x)[0] = prod;
+	  SIZ (x) = 1;
+	}
+
+      TMP_FREE;
+    }
+}
diff -r 7df54aea7a96 -r 692bc6eee88d tests/mpz/Makefile.am
--- a/tests/mpz/Makefile.am	Thu Apr 19 09:43:14 2012 +0200
+++ b/tests/mpz/Makefile.am	Thu Apr 19 11:29:36 2012 +0200
@@ -27,7 +27,7 @@
   convert io t-inp_str logic bit t-powm t-powm_ui t-pow t-div_2exp reuse   \
   t-root t-perfsqr t-perfpow t-jac t-bin t-get_d t-get_d_2exp t-get_si	\
   t-set_d t-set_si							\
-  t-fac_ui t-fib_ui t-lucnum_ui t-scan t-fits                           \
+  t-fac_ui t-primorial_ui t-fib_ui t-lucnum_ui t-scan t-fits                           \
   t-divis t-divis_2exp t-cong t-cong_2exp t-sizeinbase t-set_str        \
   t-aorsmul t-cmp_d t-cmp_si t-hamdist t-oddeven t-popcount t-set_f     \
   t-io_raw t-import t-export t-pprime_p t-nextprime
diff -r 7df54aea7a96 -r 692bc6eee88d tests/mpz/t-primorial_ui.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/mpz/t-primorial_ui.c	Thu Apr 19 11:29:36 2012 +0200
@@ -0,0 +1,97 @@
+/* Exercise mpz_primorial_ui.
+
+Copyright 2000, 2001, 2002, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+/* Usage: t-primorial_ui [x|num]
+
+   With no arguments testing goes up to the initial value of "limit" below.
+   With a number argument tests are carried that far, or with a literal "x"
+   tests are continued without limit (this being meant only for development
+   purposes).  */
+
+static int isprime (unsigned long int t);


More information about the gmp-commit mailing list