示例#1
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;
}
示例#2
0
void _fmpz_mod_poly_evaluate_fmpz(fmpz_t res, const fmpz *poly, slong len, 
                                  const fmpz_t a, const fmpz_t p)
{
    if (len == 0)
    {
        fmpz_zero(res);
    }
    else if (len == 1 || fmpz_is_zero(a))
    {
        fmpz_set(res, poly);
    }
    else
    {
        slong i = len - 1;
        fmpz_t t;

        fmpz_init(t);
        fmpz_set(res, poly + i);
        for (i = len - 2; i >= 0; i--)
        {
            fmpz_mul(t, res, a);
            fmpz_mod(t, t, p);
            fmpz_add(res, poly + i, t);
        }
        fmpz_clear(t);

        if (fmpz_cmpabs(res, p) >= 0)
            fmpz_sub(res, res, p);
    }
}
示例#3
0
文件: fmpz.c 项目: hperl/flint
void fmpz_multi_mod_ui(unsigned long * out, fmpz_t in, fmpz_comb_t comb, fmpz_t ** temp)
{
   ulong i, j, k;
   ulong n = comb->n;
   long log_comb;
	ulong size;
	mp_limb_t * ptr;
	ulong num;
	unsigned long num_primes = comb->num_primes;

   if (num_primes == 1) // we are reducing modulo a single prime which is assumed to be big enough
   {
	  if ((long)in[0] > 0L) out[0] = in[1];
	  else if ((long)in[0] < 0L) out[0] = comb->primes[0] - in[1];
	  else out[0] = 0L;
	  return;
   }

   log_comb = n - 1;
   

   // find level in comb with entries bigger than the input integer
	log_comb = 0;
	if ((long) in[0] < 0L)
	  while ((fmpz_bits(in) >= fmpz_bits(comb->comb[log_comb][0]) - 1) && (log_comb < comb->n - 1)) log_comb++;
   else
		while (fmpz_cmpabs(in, comb->comb[log_comb][0]) >= 0) log_comb++;
   num = (1L<<(n - log_comb - 1));

	// set each entry of this level of temp to the input integer
	for (i = 0; i < num; i++)
   {
      fmpz_set(temp[log_comb][i], in);
   }
   log_comb--;
   num *= 2;
   
   // fill in other entries of temp by taking entries of temp at higher level mod pairs from comb
	while (log_comb > FLINT_LOG_MULTI_MOD_CUTOFF) // keep going until we reach the basecase
   {
      for (i = 0, j = 0; i < num; i += 2, j++)
      {
         fmpz_mod(temp[log_comb][i], temp[log_comb + 1][j], comb->comb[log_comb][i]);
         fmpz_mod(temp[log_comb][i+1], temp[log_comb + 1][j], comb->comb[log_comb][i+1]);
      }
      num *= 2;
      log_comb--;
   }
   
   // do basecase
	num /= 2;
   log_comb++;
   ulong stride = (1L << (log_comb + 1));
   for (i = 0, j = 0; j < num_primes; i++, j += stride)
   {
	   fmpz_multi_mod_ui_basecase(out + j, temp[log_comb][i], comb->primes + j, FLINT_MIN(stride, num_primes - j));
   }
}
示例#4
0
void
elem_add(elem_ptr res, elem_srcptr op1, elem_srcptr op2, const ring_t ring)
{
    switch (ring->type)
    {
        case TYPE_FMPZ:
            fmpz_add(res, op1, op2);
            break;

        case TYPE_LIMB:
            *((mp_ptr) res) = *((mp_srcptr) op1) + *((mp_srcptr) op2);
            break;

        case TYPE_POLY:
            elem_poly_add(res, op1, op2, ring);
            break;

        case TYPE_MOD:
            {
                switch (RING_PARENT(ring)->type)
                {
                    case TYPE_LIMB:
                        *((mp_ptr) res) = n_addmod(*((mp_srcptr) op1), *((mp_srcptr) op2), ring->nmod.n);
                        break;

                    case TYPE_FMPZ:
                        fmpz_add(res, op1, op2);
                        if (fmpz_cmpabs(res, RING_MODULUS(ring)) >= 0)
                            fmpz_sub(res, res, RING_MODULUS(ring));
                        break;

                    default:
                        NOT_IMPLEMENTED("add (mod)", ring);
                }
            }
            break;

        case TYPE_FRAC:
            elem_frac_add(res, op1, op2, ring);
            break;

        case TYPE_COMPLEX:
            elem_add(REALPART(res, ring), REALPART(op1, ring), REALPART(op2, ring), ring->parent);
            elem_add(IMAGPART(res, ring), IMAGPART(op1, ring), IMAGPART(op2, ring), ring->parent);
            break;

        default:
            NOT_IMPLEMENTED("add", ring);
    }
}
示例#5
0
void test1(mp_limb_t log2,const fmpz_t b,const fmpz_t z)
 {
  if( (fmpz_cmp_ui(z,0)<=0) || (log2==0) )
   return;
  int r0=fmpz_cmpabs(z,b);
  int r1=cmp_positive_log2(z,log2);
  #if LOUD
   fmpz_hex_print("2**y=",b,0);
   fmpz_hex_print("    z=",z,0);
   flint_printf("    r0/1: %d/%d\n",r0,r1);
  #endif
  if( r0>0 )
   assert( r1>0 );
  if( r0<0 )
   assert( r1<0 );
  if( r0==0 )
   assert( 0 == r1 );
 }
示例#6
0
文件: cmpabs.c 项目: bluescarni/arb
int
fmpr_cmpabs(const fmpr_t x, const fmpr_t y)
{
    int res, xsign, ysign;
    fmpr_t t;

    if (fmpr_equal(x, y))
        return 0;

    if (fmpr_is_special(x) || fmpr_is_special(y))
    {
        if (fmpr_is_nan(x) || fmpr_is_nan(y))
            return 0;
        if (fmpr_is_zero(x)) return -1;
        if (fmpr_is_zero(y)) return 1;
        if (fmpr_is_inf(x)) return fmpr_is_inf(y) ? 0 : 1;
        if (fmpr_is_inf(y)) return -1;
        return -1;
    }

    /* Reduces to integer comparison if bottom exponents are the same */
    if (fmpz_equal(fmpr_expref(x), fmpr_expref(y)))
    {
        res = fmpz_cmpabs(fmpr_manref(x), fmpr_manref(y));
        if (res != 0)
            res = (res < 0) ? -1 : 1;
    }
    else
    {
        /* TODO: compare position of top exponents to avoid subtraction */
        xsign = fmpr_sgn(x);
        ysign = fmpr_sgn(y);

        fmpr_init(t);
        if (xsign == ysign)
            fmpr_sub(t, x, y, 2, FMPR_RND_DOWN);
        else
            fmpr_add(t, x, y, 2, FMPR_RND_DOWN);
        res = fmpr_sgn(t) * xsign;
        fmpr_clear(t);
    }

    return res;
}
示例#7
0
void _fmpz_mod_poly_compose_horner(fmpz *res, const fmpz *poly1, long len1, 
                                              const fmpz *poly2, long len2, 
                                              const fmpz_t p)
{
    if (len1 == 1 || len2 == 0)
    {
        fmpz_set(res, poly1);
    }
    else
    {
        const long alloc = (len1 - 1) * (len2 - 1) + 1;
        long i = len1 - 1, lenr = len2;
        fmpz * t = _fmpz_vec_init(alloc);
        
        /*
           Perform the first two steps as one, 
             "res = a(m) * poly2 + a(m-1)".
         */
        {
            _fmpz_mod_poly_scalar_mul_fmpz(res, poly2, len2, poly1 + i, p);
            i--;
            fmpz_add(res, res, poly1 + i);
            if (fmpz_cmpabs(res, p) >= 0)
                fmpz_sub(res, res, p);
        }
        while (i > 0)
        {
            i--;
            _fmpz_mod_poly_mul(t, res, lenr, poly2, len2, p);
            lenr += len2 - 1;
            _fmpz_mod_poly_add(res, t, lenr, poly1 + i, 1, p);
        }

        _fmpz_vec_clear(t, alloc);
    }
}
示例#8
0
文件: t-cmpabs.c 项目: argriffing/arb
int main()
{
    slong iter;
    flint_rand_t state;

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

    flint_randinit(state);

    /* compare with fmpz */
    {
        arf_t x, y;
        fmpz_t X, Y;

        arf_init(x);
        arf_init(y);
        fmpz_init(X);
        fmpz_init(Y);

        for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++)
        {
            int cmp1, cmp2;

            fmpz_randtest(X, state, 1 + n_randint(state, 1000));

            switch (n_randint(state, 8))
            {
                case 0:
                    fmpz_neg(Y, X);
                    break;
                case 1:
                    fmpz_set(Y, X);
                    break;
                default:
                    fmpz_randtest(Y, state, 1 + n_randint(state, 1000));
            }

            arf_set_fmpz(x, X);
            arf_set_fmpz(y, Y);

            cmp1 = arf_cmpabs(x, y);

            cmp2 = fmpz_cmpabs(X, Y);
            cmp2 = (cmp2 > 0) - (cmp2 < 0);

            if (cmp1 != cmp2)
            {
                flint_printf("FAIL\n\n");
                flint_printf("x = "); arf_debug(x); flint_printf("\n\n");
                flint_printf("y = "); arf_debug(y); flint_printf("\n\n");
                flint_printf("X = "); fmpz_print(X); flint_printf("\n\n");
                flint_printf("Y = "); fmpz_print(Y); flint_printf("\n\n");
                flint_printf("cmp1 = %d, cmp2 = %d\n\n", cmp1, cmp2);
                abort();
            }
        }

        arf_clear(x);
        arf_clear(y);
        fmpz_clear(X);
        fmpz_clear(Y);
    }

    /* compare with mpfr */
    for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++)
    {
        slong bits;
        arf_t x, y;
        mpfr_t X, Y;
        int cmp1, cmp2;

        bits = 2 + n_randint(state, 200);

        arf_init(x);
        arf_init(y);

        mpfr_init2(X, bits);
        mpfr_init2(Y, bits);

        arf_randtest_special(x, state, bits, 10);
        arf_randtest_special(y, state, bits, 10);

        arf_get_mpfr(X, x, MPFR_RNDN);
        arf_get_mpfr(Y, y, MPFR_RNDN);

        mpfr_abs(X, X, MPFR_RNDN);
        mpfr_abs(Y, Y, MPFR_RNDN);

        cmp1 = arf_cmpabs(x, y);
        cmp2 = mpfr_cmp(X, Y);

        if (cmp1 != cmp2)
        {
            flint_printf("FAIL\n\n");
            flint_printf("x = "); arf_print(x); flint_printf("\n\n");
            flint_printf("y = "); arf_print(y); flint_printf("\n\n");
            flint_printf("cmp1 = %d, cmp2 = %d\n\n", cmp1, cmp2);
            abort();
        }

        arf_clear(x);
        arf_clear(y);

        mpfr_clear(X);
        mpfr_clear(Y);
    }

    flint_randclear(state);
    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}
示例#9
0
文件: fmpz.c 项目: hperl/flint
int fmpz_divides(fmpz_t q, const fmpz_t a, const fmpz_t b) 
{
   long a0 = a[0];
   long b0 = b[0];
   unsigned long sizea = FLINT_ABS(a0);
   unsigned long sizeb = FLINT_ABS(b0);   

   mp_limb_t mslimb;
   fmpz_t temp;
      
   if (sizeb == 0)
   {
      printf("Error: division by zero!\n");
      abort();          
   } else if (sizea == 0)
	{
		q[0] = 0;
		return 1;
	} else if (sizea < sizeb) 
   {
      return 0;
   } else if (sizea == sizeb) 
	{
		int cmp = fmpz_cmpabs(a, b);
		if (cmp < 0) return 0;
      if (cmp == 0)
		{
			if ((long) (a0 ^ b0) < 0L) q[0] = -1L;
			else q[0] = 1L;
			q[1] = 1;
		   return 1;
		}
   } 

   if (fmpz_is_one(b)) 
	{
	   fmpz_set(q, a); 
		return 1;
	}

	if (fmpz_is_m1(b))
	{
		fmpz_neg(q, a);
		return 1;
	}
	  
	temp = (fmpz_t) flint_stack_alloc(sizeb + 2);
   mpn_tdiv_qr(q+1, temp+1, 0, a+1, sizea, b+1, sizeb);
      
	temp[0] = sizeb;
   NORM(temp);
      
	if (temp[0] != 0) 
	{
		flint_stack_release();
		return 0;
	}

	q[0] = sizea - sizeb + 1;
	NORM(q);

	if ((long) (a0 ^ b0) < 0L) q[0] = -q[0];
   
	flint_stack_release();
	return 1;
}     
示例#10
0
文件: fmpz.c 项目: hperl/flint
void fmpz_mod(fmpz_t res, const fmpz_t a, const fmpz_t b) 
{
   long a0 = a[0];
   long b0 = b[0];
   unsigned long sizea = FLINT_ABS(a0);
   unsigned long sizeb = b0;
   while ((!a[sizea]) && (sizea)) sizea--;
   while ((!b[sizeb]) && (sizeb)) sizeb--;
      

   mp_limb_t mslimb;
   fmpz_t temp, temp2;
      
   if (sizeb == 0)
   {
      printf("Error: division by zero!\n");
      abort();          
   } else if (sizea < sizeb) 
   {
      if ((long) a0 < 0L) 
      {
         temp = (fmpz_t) flint_stack_alloc(sizeb + 2);
         fmpz_add(temp, a, b);
         fmpz_set(res, temp);
         flint_stack_release();  
      } else fmpz_set(res, a);
      return;
   } else if ((sizea == sizeb) && (fmpz_cmpabs(a, b) < 0L))
   {
      if (fmpz_sgn(a) < 0) fmpz_add(res, a, b);
      else fmpz_set(res, a);
	  return;
   } else
   {
      if (fmpz_is_one(b)) 
	  {
	     fmpz_set_ui(res, 0L); 
		 return;
	  }
	  temp = (fmpz_t) flint_stack_alloc(sizea - sizeb + 1);
      temp2 = (fmpz_t) flint_stack_alloc(sizeb + 2);
      mpn_tdiv_qr(temp, temp2+1, 0, a+1, sizea, b+1, sizeb);
      temp2[0] = sizeb;
      NORM(temp2);
      if (a0 < 0L)
      {
         unsigned long i = 0; 
         for (; i < sizeb; i++)
         {
            if (temp2[i+1]) break;
         }
         if (i < sizeb)
         {
            fmpz_sub(temp2, b, temp2);
         } 
         fmpz_set(res, temp2);
      } else fmpz_set(res, temp2);
      flint_stack_release();  
      flint_stack_release();  
   }
}