Annotation of OpenXM_contrib/gmp/tests/refmpz.c, Revision 1.1
1.1 ! ohara 1: /* Reference mpz functions.
! 2:
! 3: Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
! 4:
! 5: This file is part of the GNU MP Library.
! 6:
! 7: The GNU MP Library is free software; you can redistribute it and/or modify
! 8: it under the terms of the GNU Lesser General Public License as published by
! 9: the Free Software Foundation; either version 2.1 of the License, or (at your
! 10: option) any later version.
! 11:
! 12: The GNU MP Library is distributed in the hope that it will be useful, but
! 13: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 14: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
! 15: License for more details.
! 16:
! 17: You should have received a copy of the GNU Lesser General Public License
! 18: along with the GNU MP Library; see the file COPYING.LIB. If not, write to
! 19: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
! 20: MA 02111-1307, USA. */
! 21:
! 22: /* always do assertion checking */
! 23: #define WANT_ASSERT 1
! 24:
! 25: #include <stdio.h>
! 26: #include <stdlib.h> /* for free */
! 27: #include "gmp.h"
! 28: #include "gmp-impl.h"
! 29: #include "longlong.h"
! 30: #include "tests.h"
! 31:
! 32:
! 33: /* Change this to "#define TRACE(x) x" for some traces. */
! 34: #define TRACE(x)
! 35:
! 36:
! 37: unsigned long
! 38: refmpz_hamdist (mpz_srcptr x, mpz_srcptr y)
! 39: {
! 40: mp_size_t tsize;
! 41: mp_ptr xp, yp;
! 42: unsigned long ret;
! 43:
! 44: if ((SIZ(x) < 0 && SIZ(y) >= 0)
! 45: || (SIZ(y) < 0 && SIZ(x) >= 0))
! 46: return ULONG_MAX;
! 47:
! 48: tsize = MAX (ABSIZ(x), ABSIZ(y));
! 49:
! 50: xp = refmpn_malloc_limbs (tsize);
! 51: refmpn_zero (xp, tsize);
! 52: refmpn_copy (xp, PTR(x), ABSIZ(x));
! 53:
! 54: yp = refmpn_malloc_limbs (tsize);
! 55: refmpn_zero (yp, tsize);
! 56: refmpn_copy (yp, PTR(y), ABSIZ(y));
! 57:
! 58: if (SIZ(x) < 0)
! 59: refmpn_neg_n (xp, xp, tsize);
! 60:
! 61: if (SIZ(x) < 0)
! 62: refmpn_neg_n (yp, yp, tsize);
! 63:
! 64: ret = refmpn_hamdist (xp, yp, tsize);
! 65:
! 66: free (xp);
! 67: free (yp);
! 68: return ret;
! 69: }
! 70:
! 71:
! 72: /* (0/b), with mpz b; is 1 if b=+/-1, 0 otherwise */
! 73: #define JACOBI_0Z(b) JACOBI_0LS (PTR(b)[0], SIZ(b))
! 74:
! 75: /* (a/b) effect due to sign of b: mpz/mpz */
! 76: #define JACOBI_BSGN_ZZ_BIT1(a, b) JACOBI_BSGN_SS_BIT1 (SIZ(a), SIZ(b))
! 77:
! 78: /* (a/b) effect due to sign of a: mpz/unsigned-mpz, b odd;
! 79: is (-1/b) if a<0, or +1 if a>=0 */
! 80: #define JACOBI_ASGN_ZZU_BIT1(a, b) JACOBI_ASGN_SU_BIT1 (SIZ(a), PTR(b)[0])
! 81:
! 82: int
! 83: refmpz_kronecker (mpz_srcptr a_orig, mpz_srcptr b_orig)
! 84: {
! 85: unsigned long twos;
! 86: mpz_t a, b;
! 87: int result_bit1 = 0;
! 88:
! 89: if (mpz_sgn (b_orig) == 0)
! 90: return JACOBI_Z0 (a_orig); /* (a/0) */
! 91:
! 92: if (mpz_sgn (a_orig) == 0)
! 93: return JACOBI_0Z (b_orig); /* (0/b) */
! 94:
! 95: if (mpz_even_p (a_orig) && mpz_even_p (b_orig))
! 96: return 0;
! 97:
! 98: if (mpz_cmp_ui (b_orig, 1) == 0)
! 99: return 1;
! 100:
! 101: mpz_init_set (a, a_orig);
! 102: mpz_init_set (b, b_orig);
! 103:
! 104: if (mpz_sgn (b) < 0)
! 105: {
! 106: result_bit1 ^= JACOBI_BSGN_ZZ_BIT1 (a, b);
! 107: mpz_neg (b, b);
! 108: }
! 109: if (mpz_even_p (b))
! 110: {
! 111: twos = mpz_scan1 (b, 0L);
! 112: mpz_tdiv_q_2exp (b, b, twos);
! 113: result_bit1 ^= JACOBI_TWOS_U_BIT1 (twos, PTR(a)[0]);
! 114: }
! 115:
! 116: if (mpz_sgn (a) < 0)
! 117: {
! 118: result_bit1 ^= JACOBI_N1B_BIT1 (PTR(b)[0]);
! 119: mpz_neg (a, a);
! 120: }
! 121: if (mpz_even_p (a))
! 122: {
! 123: twos = mpz_scan1 (a, 0L);
! 124: mpz_tdiv_q_2exp (a, a, twos);
! 125: result_bit1 ^= JACOBI_TWOS_U_BIT1 (twos, PTR(b)[0]);
! 126: }
! 127:
! 128: for (;;)
! 129: {
! 130: ASSERT (mpz_odd_p (a));
! 131: ASSERT (mpz_odd_p (b));
! 132: ASSERT (mpz_sgn (a) > 0);
! 133: ASSERT (mpz_sgn (b) > 0);
! 134:
! 135: TRACE (printf ("top\n");
! 136: mpz_trace (" a", a);
! 137: mpz_trace (" b", b));
! 138:
! 139: if (mpz_cmp (a, b) < 0)
! 140: {
! 141: TRACE (printf ("swap\n"));
! 142: mpz_swap (a, b);
! 143: result_bit1 ^= JACOBI_RECIP_UU_BIT1 (PTR(a)[0], PTR(b)[0]);
! 144: }
! 145:
! 146: if (mpz_cmp_ui (b, 1) == 0)
! 147: break;
! 148:
! 149: mpz_sub (a, a, b);
! 150: TRACE (printf ("sub\n");
! 151: mpz_trace (" a", a));
! 152: if (mpz_sgn (a) == 0)
! 153: goto zero;
! 154:
! 155: twos = mpz_scan1 (a, 0L);
! 156: mpz_fdiv_q_2exp (a, a, twos);
! 157: TRACE (printf ("twos %lu\n", twos);
! 158: mpz_trace (" a", a));
! 159: result_bit1 ^= JACOBI_TWOS_U_BIT1 (twos, PTR(b)[0]);
! 160: }
! 161:
! 162: mpz_clear (a);
! 163: mpz_clear (b);
! 164: return JACOBI_BIT1_TO_PN (result_bit1);
! 165:
! 166: zero:
! 167: mpz_clear (a);
! 168: mpz_clear (b);
! 169: return 0;
! 170: }
! 171:
! 172: /* Same as mpz_kronecker, but ignoring factors of 2 on b */
! 173: int
! 174: refmpz_jacobi (mpz_srcptr a, mpz_srcptr b)
! 175: {
! 176: mpz_t b_odd;
! 177: mpz_init_set (b_odd, b);
! 178: if (mpz_sgn (b_odd) != 0)
! 179: mpz_fdiv_q_2exp (b_odd, b_odd, mpz_scan1 (b_odd, 0L));
! 180: return refmpz_kronecker (a, b_odd);
! 181: }
! 182:
! 183: int
! 184: refmpz_legendre (mpz_srcptr a, mpz_srcptr b)
! 185: {
! 186: return refmpz_jacobi (a, b);
! 187: }
! 188:
! 189:
! 190: int
! 191: refmpz_kronecker_ui (mpz_srcptr a, unsigned long b)
! 192: {
! 193: mpz_t bz;
! 194: int ret;
! 195: mpz_init_set_ui (bz, b);
! 196: ret = refmpz_kronecker (a, bz);
! 197: mpz_clear (bz);
! 198: return ret;
! 199: }
! 200:
! 201: int
! 202: refmpz_kronecker_si (mpz_srcptr a, long b)
! 203: {
! 204: mpz_t bz;
! 205: int ret;
! 206: mpz_init_set_si (bz, b);
! 207: ret = refmpz_kronecker (a, bz);
! 208: mpz_clear (bz);
! 209: return ret;
! 210: }
! 211:
! 212: int
! 213: refmpz_ui_kronecker (unsigned long a, mpz_srcptr b)
! 214: {
! 215: mpz_t az;
! 216: int ret;
! 217: mpz_init_set_ui (az, a);
! 218: ret = refmpz_kronecker (az, b);
! 219: mpz_clear (az);
! 220: return ret;
! 221: }
! 222:
! 223: int
! 224: refmpz_si_kronecker (long a, mpz_srcptr b)
! 225: {
! 226: mpz_t az;
! 227: int ret;
! 228: mpz_init_set_si (az, a);
! 229: ret = refmpz_kronecker (az, b);
! 230: mpz_clear (az);
! 231: return ret;
! 232: }
! 233:
! 234:
! 235: void
! 236: refmpz_pow_ui (mpz_ptr w, mpz_srcptr b, unsigned long e)
! 237: {
! 238: mpz_t s, t;
! 239: unsigned long i;
! 240:
! 241: mpz_init_set_ui (t, 1L);
! 242: mpz_init_set (s, b);
! 243:
! 244: if ((e & 1) != 0)
! 245: mpz_mul (t, t, s);
! 246:
! 247: for (i = 2; i <= e; i <<= 1)
! 248: {
! 249: mpz_mul (s, s, s);
! 250: if ((i & e) != 0)
! 251: mpz_mul (t, t, s);
! 252: }
! 253:
! 254: mpz_set (w, t);
! 255:
! 256: mpz_clear (s);
! 257: mpz_clear (t);
! 258: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>