예제 #1
0
파일: fmpz.c 프로젝트: hperl/flint
// truncated multiplication for fmpz
void fmpz_mul_trunc(fmpz_t res, fmpz_t a, fmpz_t b, unsigned long trunc)
{
    unsigned long sizea = FLINT_MIN(fmpz_size(a), trunc);
    unsigned long sizeb = FLINT_MIN(fmpz_size(b), trunc);
    while ((!a[sizea]) && (sizea)) sizea--;
    while ((!b[sizeb]) && (sizeb)) sizeb--;

    if ((sizea == 0) || (sizeb == 0)) {
        res[0] = 0;
        return;
    }

    if (trunc >= sizea + sizeb) {
        mp_limb_t mslimb;
        if (sizea >= sizeb) mslimb = F_mpn_mul(res+1, a+1, sizea, b+1, sizeb);
        else mslimb = F_mpn_mul(res+1, b+1, sizeb, a+1, sizea);
        res[0] = sizea + sizeb - (mslimb == 0);
    } else {
        mp_limb_t mslimb;
        fmpz_t temp = flint_stack_alloc(sizea + sizeb + 1);
        if (sizea >= sizeb) mslimb = F_mpn_mul_trunc(temp+1, a+1, sizea, b+1, sizeb, trunc);
        else mslimb = F_mpn_mul_trunc(temp+1, b+1, sizeb, a+1, sizea, trunc);
        temp[0] = trunc;
        if (UNLIKELY(!mslimb))
            __fmpz_normalise(temp); // normalise if most significant limb == 0
        fmpz_set(res, temp);
        flint_stack_release();
    }
    if ((long) (a[0] ^ b[0]) < 0L) res[0] = -res[0];
}
예제 #2
0
파일: fmpz.c 프로젝트: hperl/flint
void fmpz_invert(fmpz_t res, fmpz_t x, fmpz_t m)
{
   if (m[0] == 0)
   {
       printf("Error: division by zero!\n");
       abort();
   }

   fmpz_t s0, U, V, temp;
   unsigned long size = fmpz_size(m);
   // U may use fmpz_size(m) + 1 limbs after the sum, and gmp requires +1
   U = fmpz_init(size + 2);
   V = fmpz_init(size + 2);
   s0 = fmpz_init(size + 2);
   temp = fmpz_init(size + 2);

   // U := (x%m) + abs(m)
   // V := abs(m)
   fmpz_abs(V, m);
   fmpz_mod(U, x, V);
   fmpz_add(U, U, V);

   // Compute s0 such that 1 = s0 * x  %  m
   mpn_gcdext(temp+1, s0+1, (long *) s0, U+1, fmpz_size(U), V+1, fmpz_size(V));
   fmpz_mod(res, s0, m);

   fmpz_clear(temp);
   fmpz_clear(s0);
   fmpz_clear(V);
   fmpz_clear(U);
}
예제 #3
0
파일: fmpz.c 프로젝트: hperl/flint
// Compute a*b mod m
void fmpz_mulmod(fmpz_t res, fmpz_t a, fmpz_t b, fmpz_t m)
{
    fmpz_t ab = fmpz_init(fmpz_size(a) + fmpz_size(b));
    fmpz_mul(ab, a, b);
    fmpz_mod(res, ab, m);

    fmpz_clear(ab);
}
예제 #4
0
파일: fmpz.c 프로젝트: hperl/flint
// Compute a/b mod m
void fmpz_divmod(fmpz_t res, fmpz_t a, fmpz_t b, fmpz_t m)
{
    fmpz_t b_inv = fmpz_init(fmpz_size(m));
    fmpz_invert(b_inv, b, m);

    fmpz_t ab = fmpz_init(fmpz_size(a) + fmpz_size(b_inv));
    fmpz_mul(ab, a, b_inv);
    fmpz_mod(res, ab, m);

    fmpz_clear(ab);
    fmpz_clear(b_inv);
}
예제 #5
0
파일: fmpz.c 프로젝트: hperl/flint
void __fmpz_multi_CRT_sign(fmpz_t output, fmpz_t input, fmpz_comb_t comb)
{
   unsigned long n = comb->n;
   if (n == 0L) 
   {
      if (input[0] == 0L) 
	   {
	      fmpz_set_ui(output, 0L);
	      return;
	   }

	   unsigned long p = comb->primes[0];
	   if ((p - input[1]) < input[1]) fmpz_set_si(output, (long) (input[1] - p));
	   else fmpz_set_ui(output, input[1]);
	   return;
   }

   fmpz_t temp = fmpz_init(fmpz_size(comb->comb[n-1][0]) + 1);
   
   fmpz_sub(temp, input, comb->comb[comb->n - 1][0]);

   if (fmpz_cmpabs(temp, input) <= 0L) fmpz_set(output, temp);
   else fmpz_set(output, input);

   fmpz_clear(temp);
   return;
}
예제 #6
0
__inline__ static int
log2_L2_fmpz_3arg(mpfr_t tgt,const fmpz* vec,slong n)
// 2*log2(L2 norm) rounded up
// if row is zero, return 1 and do not initialize tgt
// else return 0 and initialize tgt to a suitable precision
 {
  fmpz_t norm; fmpz_init(norm);
  slong i,i_is_big=0;
  square_L2_fmpz(norm,vec,n);
  i=fmpz_size(norm);
  if( 0==i )
   {
    fmpz_clear(norm);
    return 1;
   }
  if(i>2)
   {
    i=2;
    i_is_big=1;
   }
  mpfr_t normF; mpfr_init2(normF,i*FLINT_BITS);
  fmpz_get_mpfr(normF,norm,MPFR_RNDU);
  fmpz_clear(norm);
  if(i_is_big)
   mpfr_init2(tgt,1+FLINT_BITS);
  else
   mpfr_init(tgt);
  mpfr_log2(tgt, normF, MPFR_RNDU);
  mpfr_clear(normF);
  return 0;
 }
예제 #7
0
파일: t-size.c 프로젝트: clear731/lattice
int
main(void)
{
    int i, result;
    FLINT_TEST_INIT(state);

    flint_printf("size....");
    fflush(stdout);

    

    for (i = 0; i < 10000 * flint_test_multiplier(); i++)
    {
        fmpz_t a;
        mpz_t b;
        mp_size_t r1, r2;

        fmpz_init(a);

        mpz_init(b);

        fmpz_randtest(a, state, 200);

        fmpz_get_mpz(b, a);

        r1 = fmpz_size(a);
        r2 = mpz_size(b);
        result = (r1 == r2);

        if (!result)
        {
            flint_printf("FAIL:\n");
            gmp_printf("b = %Zd\n", b);
            abort();
        }

        fmpz_clear(a);

        mpz_clear(b);
    }

    FLINT_TEST_CLEANUP(state);
    
    flint_printf("PASS\n");
    return 0;
}
예제 #8
0
/* 
   Divide (arrayg, limbsg) by the positive value gc inplace and
   return the number of limbs written
*/
mp_size_t mpn_tdiv_q_fmpz_inplace(mp_ptr arrayg, mp_size_t limbsg, fmpz_t gc)
{
   if (fmpz_size(gc) == 1) 
   {
      mpn_divmod_1(arrayg, arrayg, limbsg, fmpz_get_ui(gc));
      return limbsg - (arrayg[limbsg - 1] == 0);
   }
	else 
   {
      mp_size_t tlimbs;
      __mpz_struct * mpz_ptr = COEFF_TO_PTR(*gc);
      
      mp_ptr temp = flint_malloc(limbsg*sizeof(mp_limb_t));
      mpn_copyi(temp, arrayg, limbsg);
      
      mpn_tdiv_q(arrayg, temp, limbsg, mpz_ptr->_mp_d, mpz_ptr->_mp_size);
      tlimbs = limbsg - mpz_ptr->_mp_size + 1;
      tlimbs -= (arrayg[tlimbs - 1] == 0);
      
      flint_free(temp);
      return tlimbs;
   } 
}