[Gmp-commit] /home/hgfiles/gmp: New jacobi reference implementation, using fa...

mercurial at gmplib.org mercurial at gmplib.org
Thu Feb 25 21:55:56 CET 2010


details:   /home/hgfiles/gmp/rev/6c0733a4bc88
changeset: 13462:6c0733a4bc88
user:      Niels M?ller <nisse at lysator.liu.se>
date:      Thu Feb 25 21:55:50 2010 +0100
description:
New jacobi reference implementation, using factorization and legendre symbols computed by powm.

diffstat:

 ChangeLog         |   3 +
 tests/mpz/t-jac.c |  96 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 99 insertions(+), 0 deletions(-)

diffs (125 lines):

diff -r 7f50d4ccfd05 -r 6c0733a4bc88 ChangeLog
--- a/ChangeLog	Thu Feb 25 21:26:35 2010 +0100
+++ b/ChangeLog	Thu Feb 25 21:55:50 2010 +0100
@@ -1,5 +1,8 @@
 2010-02-25  Niels Möller  <nisse at lysator.liu.se>
 
+	* tests/mpz/t-jac.c (ref_jacobi): New reference implementation,
+	using factorization and legendre symbols computed by powm.
+
 	* tests/devel/try.c (param_init, call): Don't pass negative values
 	for the second argument to mpz_jacobi and refmpz_jacobi.
 
diff -r 7f50d4ccfd05 -r 6c0733a4bc88 tests/mpz/t-jac.c
--- a/tests/mpz/t-jac.c	Thu Feb 25 21:26:35 2010 +0100
+++ b/tests/mpz/t-jac.c	Thu Feb 25 21:55:50 2010 +0100
@@ -719,6 +719,101 @@
 }
 
 
+/* Assumes that b = prod p_k^e_k */
+int
+ref_jacobi (mpz_srcptr a, mpz_srcptr b, unsigned nprime,
+	    mpz_t prime[], unsigned *exp)
+{
+  unsigned i;
+  int res;
+
+  for (i = 0, res = 1; i < nprime; i++)
+    if (exp[i])
+      {
+	int legendre = refmpz_legendre (a, prime[i]);
+	if (!legendre)
+	  return 0;
+	if (exp[i] & 1)
+	  res *= legendre;
+      }
+  return res;
+}
+
+void
+check_jacobi_factored (void)
+{
+#define PRIME_N 10
+#define PRIME_MAX_SIZE 50
+#define PRIME_MAX_EXP 4
+#define PRIME_A_COUNT 10
+#define PRIME_B_COUNT 5
+#define PRIME_MAX_B_SIZE 2000
+
+  gmp_randstate_ptr rands = RANDS;
+  mpz_t prime[PRIME_N];
+  unsigned exp[PRIME_N];
+  mpz_t a, b, t, bs;
+  unsigned i;
+
+  mpz_init (a);
+  mpz_init (b);
+  mpz_init (t);
+  mpz_init (bs);
+
+  /* Generate primes */
+  for (i = 0; i < PRIME_N; i++)
+    {
+      mp_size_t size;
+      mpz_init (prime[i]);
+      mpz_urandomb (bs, rands, 32);
+      size = mpz_get_ui (bs) % PRIME_MAX_SIZE + 2;
+      mpz_rrandomb (prime[i], rands, size);
+      if (mpz_cmp_ui (prime[i], 3) <= 0)
+	mpz_set_ui (prime[i], 3);
+      else
+	mpz_nextprime (prime[i], prime[i]);
+    }
+
+  for (i = 0; i < PRIME_B_COUNT; i++)
+    {
+      unsigned j, k;
+      mp_bitcnt_t bsize;
+
+      mpz_set_ui (b, 1);
+      bsize = 1;
+
+      for (j = 0; j < PRIME_N && bsize < PRIME_MAX_B_SIZE; j++)
+	{
+	  mpz_urandomb (bs, rands, 32);
+	  exp[j] = mpz_get_ui (bs) % PRIME_MAX_EXP;
+	  mpz_pow_ui (t, prime[j], exp[j]);
+	  mpz_mul (b, b, t);
+	  bsize = mpz_sizeinbase (b, 2);
+	}
+      for (k = 0; k < PRIME_A_COUNT; k++)
+	{
+	  int answer;
+	  mpz_rrandomb (a, rands, bsize + 2);
+	  answer = ref_jacobi (a, b, j, prime, exp);
+	  try_all (a, b, answer);
+	}
+    }
+  for (i = 0; i < PRIME_N; i++)
+    mpz_clear (prime[i]);
+
+  mpz_clear (a);
+  mpz_clear (b);
+  mpz_clear (t);
+  mpz_clear (bs);
+
+#undef PRIME_N
+#undef PRIME_MAX_SIZE
+#undef PRIME_MAX_EXP
+#undef PRIME_A_COUNT
+#undef PRIME_B_COUNT
+#undef PRIME_MAX_B_SIZE
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -741,6 +836,7 @@
   check_data ();
   check_squares_zi ();
   check_a_zero ();
+  check_jacobi_factored ();
 
   tests_end ();
   exit (0);


More information about the gmp-commit mailing list