Beispiel #1
0
void _fmpq_poly_scalar_mul_fmpz(fmpz * rpoly, fmpz_t rden, 
                                const fmpz * poly, const fmpz_t den, long len,
                                const fmpz_t c)
{
    fmpz_t gcd;  /* GCD( den, c ) */

    if (fmpz_is_zero(c))
    {
        _fmpz_vec_zero(rpoly, len);
        fmpz_one(rden);
        return;
    }

    fmpz_init(gcd);
    fmpz_one(gcd);
    if (*c != 1L)
        fmpz_gcd(gcd, c, den);
    if (*gcd == 1L)
    {
        _fmpz_vec_scalar_mul_fmpz(rpoly, poly, len, c);
        fmpz_set(rden, den);
    }
    else
    {
        fmpz_t c2;
        fmpz_init(c2);
        fmpz_divexact(c2, c, gcd);
        _fmpz_vec_scalar_mul_fmpz(rpoly, poly, len, c2);
        fmpz_divexact(rden, den, gcd);
        fmpz_clear(c2);
    }
    fmpz_clear(gcd);
}
Beispiel #2
0
/* Assumes poly1 and poly2 are not length 0. */
void
_fmpz_poly_mul_classical(fmpz * res, const fmpz * poly1,
                         slong len1, const fmpz * poly2, slong len2)
{
    if (len1 == 1 && len2 == 1) /* Special case if the length of both inputs is 1 */
    {
        fmpz_mul(res, poly1, poly2);
    }
    else                        /* Ordinary case */
    {
        slong i;

        /* Set res[i] = poly1[i]*poly2[0] */
        _fmpz_vec_scalar_mul_fmpz(res, poly1, len1, poly2);

        /* Set res[i+len1-1] = in1[len1-1]*in2[i] */
        _fmpz_vec_scalar_mul_fmpz(res + len1, poly2 + 1, len2 - 1,
                                  poly1 + len1 - 1);

        /* out[i+j] += in1[i]*in2[j] */
        for (i = 0; i < len1 - 1; i++)
            _fmpz_vec_scalar_addmul_fmpz(res + i + 1, poly2 + 1, len2 - 1,
                                         poly1 + i);
    }
}
Beispiel #3
0
/*
   Assumes poly1 and poly2 are not length 0 and 0 < n <= len1 + len2 - 1.
 */
void
_fmpz_poly_mullow_classical(fmpz * res, const fmpz * poly1, long len1, 
                                        const fmpz * poly2, long len2, long n)
{
    if ((len1 == 1 && len2 == 1) || n == 1) /* Special case if the length of output is 1 */
    {
        fmpz_mul(res, poly1, poly2);
    }
    else                        /* Ordinary case */
    {
        long i;

        /* Set res[i] = poly1[i]*poly2[0] */
        _fmpz_vec_scalar_mul_fmpz(res, poly1, FLINT_MIN(len1, n), poly2);

        /* Set res[i+len1-1] = in1[len1-1]*in2[i] */
        if (n > len1)
            _fmpz_vec_scalar_mul_fmpz(res + len1, poly2 + 1, n - len1,
                                      poly1 + len1 - 1);

        /* out[i+j] += in1[i]*in2[j] */
        for (i = 0; i < FLINT_MIN(len1, n) - 1; i++)
            _fmpz_vec_scalar_addmul_fmpz(res + i + 1, poly2 + 1,
                                         FLINT_MIN(len2, n - i) - 1, 
                                         poly1 + i);
    }
}
Beispiel #4
0
int padic_poly_get_fmpz_poly(fmpz_poly_t rop, const padic_poly_t op, 
                             const padic_ctx_t ctx)
{
    const slong len = op->length;

    if (op->val < 0)
    {
        return 0;
    }

    if (padic_poly_is_zero(op))
    {
        fmpz_poly_zero(rop);
        return 1;
    }

    fmpz_poly_fit_length(rop, len);
    _fmpz_poly_set_length(rop, len);

    if (op->val == 0)
    {
        _fmpz_vec_set(rop->coeffs, op->coeffs, len);
    }
    else  /* op->val > 0 */
    {
        fmpz_t pow;

        fmpz_init(pow);
        fmpz_pow_ui(pow, ctx->p, op->val);
        _fmpz_vec_scalar_mul_fmpz(rop->coeffs, op->coeffs, len, pow);
        fmpz_clear(pow);
    }

    return 1;
}
Beispiel #5
0
/* Assumes poly1 and poly2 are not length 0 and len1 >= len2. */
void
_fmpz_poly_mulmid_classical(fmpz * res, const fmpz * poly1,
                            slong len1, const fmpz * poly2, slong len2)
{
    if ((len1 == 1) && (len2 == 1)) /* Special case if the length of both inputs is 1 */
    {
        fmpz_mul(res, poly1, poly2);
    }
    else                        /* Ordinary case */
    {
        slong i;

        /* Set res[i] = poly1[i]*poly2[0]  */
        _fmpz_vec_scalar_mul_fmpz(res, poly1 + len2 - 1, len1 - len2 + 1,
                                  poly2);

        /* out[i+j] += in1[i]*in2[j] */
        for (i = 0; i < len2 - 1; i++)
            _fmpz_vec_scalar_addmul_fmpz(res, poly2 + len2 - i - 1,
                                         FLINT_MIN(i + 1, len1 - len2 + 1),
                                         poly1 + i);
        for (; i < len1 - 1; i++)
            _fmpz_vec_scalar_addmul_fmpz(res + i - len2 + 2, poly2 + 1,
                                         FLINT_MIN(len2 - 1, len1 - i - 1),
                                         poly1 + i);
    }
}
Beispiel #6
0
void _qadic_exp_balanced(fmpz *rop, const fmpz *x, slong v, slong len, 
                         const fmpz *a, const slong *j, slong lena, 
                         const fmpz_t p, slong N, const fmpz_t pN)
{
    const slong d = j[lena - 1];

    fmpz_t pw;
    fmpz *r, *s, *t;
    slong i, w;

    r = _fmpz_vec_init(d);
    s = _fmpz_vec_init(2*d - 1);
    t = _fmpz_vec_init(d);
    fmpz_init(pw);

    fmpz_pow_ui(pw, p, v);
    _fmpz_vec_scalar_mul_fmpz(t, x, len, pw);
    _fmpz_vec_scalar_mod_fmpz(t, t, len, pN);
    _fmpz_vec_zero(t + len, d - len);

    fmpz_set(pw, p);
    fmpz_one(rop + 0);
    _fmpz_vec_zero(rop + 1, d - 1);
    w = 1;

    while (!_fmpz_vec_is_zero(t, d))
    {
        fmpz_mul(pw, pw, pw);

        for (i = 0; i < d; i++)
        {
            fmpz_fdiv_r(r + i, t + i, pw);
            fmpz_sub(t + i, t + i, r + i);
        }

        if (!_fmpz_vec_is_zero(r, d))
        {
            _qadic_exp_bsplit(r, r, w, d, a, j, lena, p, N);
            _fmpz_poly_mul(s, rop, d, r, d);
            _fmpz_poly_reduce(s, 2*d - 1, a, j, lena);
            _fmpz_vec_scalar_mod_fmpz(rop, s, d, pN);
        }

        w *= 2;
    }

    _fmpz_vec_clear(r, d);
    _fmpz_vec_clear(s, 2*d - 1);
    _fmpz_vec_clear(t, d);
    fmpz_clear(pw);
}
Beispiel #7
0
int
main(void)
{
    int i, result;
    FLINT_TEST_INIT(state);

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

    

    /* Check that content(a f) = abs(a) content(f) */
    for (i = 0; i < 1000 * flint_test_multiplier(); i++)
    {
        fmpz_t a, c, d;
        fmpz *f;
        slong len = n_randint(state, 100);

        fmpz_init(a);
        fmpz_init(c);
        fmpz_init(d);
        f = _fmpz_vec_init(len);
        _fmpz_vec_randtest(f, state, len, 200);
        fmpz_randtest(a, state, 100);

        _fmpz_vec_content(c, f, len);
        _fmpz_vec_scalar_mul_fmpz(f, f, len, a);
        fmpz_abs(a, a);
        fmpz_mul(c, a, c);
        _fmpz_vec_content(d, f, len);

        result = (fmpz_equal(c, d));
        if (!result)
        {
            flint_printf("FAIL:\n");
            fmpz_print(c), flint_printf("\n\n");
            fmpz_print(d), flint_printf("\n\n");
            abort();
        }

        fmpz_clear(a);
        fmpz_clear(c);
        fmpz_clear(d);
        _fmpz_vec_clear(f, len);
    }

    FLINT_TEST_CLEANUP(state);
    
    flint_printf("PASS\n");
    return 0;
}
Beispiel #8
0
void
_fmpz_poly_pseudo_divrem_basecase(fmpz * Q, fmpz * R, ulong * d,
                                  const fmpz * A, long lenA, const fmpz * B,
                                  long lenB)
{
    const fmpz * leadB = B + (lenB - 1);
    long iQ = lenA - lenB, iR = lenA - 1;
    fmpz_t rem;

    fmpz_init(rem);

    *d = 0;
    _fmpz_vec_zero(Q, lenA - lenB + 1);
    if (R != A)
        _fmpz_vec_set(R, A, lenA);

    while (iR >= lenB - 1)
    {
        fmpz_fdiv_qr(Q + iQ, rem, R + iR, leadB);
        if (!fmpz_is_zero(rem))
        {
            _fmpz_vec_scalar_mul_fmpz(Q, Q, lenA - lenB + 1, leadB);
            fmpz_set(Q + iQ, R + iR);
            _fmpz_vec_scalar_mul_fmpz(R, R, lenA, leadB);
            (*d)++;
        }

        if (lenB > 1)
            _fmpz_vec_scalar_submul_fmpz(R + (iR - lenB + 1), B, lenB - 1, Q + iQ);

        fmpz_zero(R + iR);

        iR--;
        iQ--;
    }

    fmpz_clear(rem);
}
Beispiel #9
0
void
fmpz_poly_scalar_mul_fmpz(fmpz_poly_t poly1, const fmpz_poly_t poly2,
                          const fmpz_t x)
{
    /* Either scalar or input poly is zero */
    if ((*x == 0) || (poly2->length == 0))
    {
        fmpz_poly_zero(poly1);
        return;
    }

    fmpz_poly_fit_length(poly1, poly2->length);
    _fmpz_vec_scalar_mul_fmpz(poly1->coeffs, poly2->coeffs, poly2->length, x);
    _fmpz_poly_set_length(poly1, poly2->length);
}
Beispiel #10
0
/* Assumes len > 0. */
void _fmpz_poly_sqr_classical(fmpz *rop, const fmpz *op, long len)
{
    if (len == 1)  /* Special case */
    {
        fmpz_mul(rop, op, op);
    }
    else   /* Ordinary case */
    {
        long i;

        _fmpz_vec_scalar_mul_fmpz(rop, op, len, op);

        _fmpz_vec_scalar_mul_fmpz(rop + len, op + 1, len - 1, op + len - 1);

        for (i = 1; i < len - 1; i++)
            _fmpz_vec_scalar_addmul_fmpz(rop + i + 1, op + 1, i - 1, op + i);

        for (i = 1; i < 2 * len - 2; i++)
            fmpz_mul_ui(rop + i, rop + i, 2);

        for (i = 1; i < len - 1; i++)
            fmpz_addmul(rop + 2 * i, op + i, op + i);
    }
}
Beispiel #11
0
void
_fmpz_poly_pseudo_divrem_cohen(fmpz * Q, fmpz * R, const fmpz * A, 
                               long lenA, const fmpz * B, long lenB)
{
    const fmpz * leadB = B + (lenB - 1);
    long e, lenQ;
    fmpz_t pow;
    
    if (lenB == 1)
    {
        fmpz_init(pow);
        fmpz_pow_ui(pow, leadB, lenA - 1);
        _fmpz_vec_scalar_mul_fmpz(Q, A, lenA, pow);
        _fmpz_vec_zero(R, lenA);
        fmpz_clear(pow);
        return;
    }

    lenQ = lenA - lenB + 1;
    _fmpz_vec_zero(Q, lenQ);
    if (R != A)
        _fmpz_vec_set(R, A, lenA);
    e = lenA - lenB;
    
    /* Unroll the first run of the while loop */
    {
        fmpz_set(Q + (lenQ - 1), R + (lenA - 1));

        _fmpz_vec_scalar_mul_fmpz(R, R, lenA - 1, leadB);
        _fmpz_vec_scalar_submul_fmpz(R + (lenA - lenB), B, lenB - 1, R + (lenA - 1));
        fmpz_zero(R + (lenA - 1));

        for (lenA -= 2; (lenA >= 0) && (R[lenA] == 0L); lenA--) ;
        lenA++;
    }
    while (lenA >= lenB)
    {
        _fmpz_vec_scalar_mul_fmpz(Q, Q, lenQ, leadB);
        fmpz_add(Q + (lenA - lenB), Q + (lenA - lenB), R + (lenA - 1));

        _fmpz_vec_scalar_mul_fmpz(R, R, lenA - 1, leadB);
        _fmpz_vec_scalar_submul_fmpz(R + lenA - lenB, B, lenB - 1, R + (lenA - 1));
        fmpz_zero(R + (lenA - 1));

        for (lenA -= 2; (lenA >= 0) && (R[lenA] == 0L); lenA--) ;
        lenA++;

        e--;
    }

    fmpz_init(pow);
    fmpz_pow_ui(pow, leadB, e);
    _fmpz_vec_scalar_mul_fmpz(Q, Q, lenQ, pow);
    _fmpz_vec_scalar_mul_fmpz(R, R, lenA, pow);
    fmpz_clear(pow);
}
Beispiel #12
0
/* Assumes poly1 and poly2 are not length 0. */
void
_fmpz_poly_mulhigh_classical(fmpz * res, const fmpz * poly1,
                             long len1, const fmpz * poly2, long len2,
                             long start)
{
    _fmpz_vec_zero(res, start);

    if (len1 == 1 && len2 == 1) /* Special case if the length of both inputs is 1 */
    {
        if (start == 0)
            fmpz_mul(res, poly1, poly2);
    }
    else                        /* Ordinary case */
    {
        long i, m, n;

        /* Set res[i] = poly1[i]*poly2[0] */
        if (start < len1)
            _fmpz_vec_scalar_mul_fmpz(res + start, poly1 + start, len1 - start,
                                      poly2);

        /* Set res[i+len1-1] = in1[len1-1]*in2[i] */
        m = FLINT_MAX(len1 - 1, start);
        _fmpz_vec_scalar_mul_fmpz(res + m, poly2 + m - len1 + 1,
                                  len2 - 1 + len1 - m, poly1 + len1 - 1);

        /* out[i+j] += in1[i]*in2[j] */
        m = FLINT_MAX(start, len2 - 1);
        for (i = m - len2 + 1; i < len1 - 1; i++)
        {
            n = FLINT_MAX(i + 1, start);
            _fmpz_vec_scalar_addmul_fmpz(res + n, poly2 + n - i, len2 + i - n,
                                         poly1 + i);
        }
    }
}
Beispiel #13
0
static void 
_qadic_exp_bsplit(fmpz *y, const fmpz *x, slong v, slong len, 
                  const fmpz *a, const slong *j, slong lena, 
                  const fmpz_t p, slong N)
{
    const slong d = j[lena - 1];
    const slong n = _padic_exp_bound(v, N, p);

    if (n == 1)
    {
        fmpz_one(y + 0);
        _fmpz_vec_zero(y + 1, d - 1);
    }
    else
    {
        fmpz *P, *T;
        fmpz_t Q, R;
        slong f;

        P = _fmpz_vec_init(2*d - 1);
        T = _fmpz_vec_init(2*d - 1);
        fmpz_init(Q);
        fmpz_init(R);

        _qadic_exp_bsplit_series(P, Q, T, x, len, 1, n, a, j, lena);

        fmpz_add(T + 0, T + 0, Q);  /* (T,Q) := (T,Q) + 1 */

        /* Note exp(x) is a unit so val(T) == val(Q). */
        f = fmpz_remove(Q, Q, p);
        fmpz_pow_ui(R, p, f);
        _fmpz_vec_scalar_divexact_fmpz(T, T, d, R);

        _padic_inv(Q, Q, p, N);
        _fmpz_vec_scalar_mul_fmpz(y, T, d, Q);

        _fmpz_vec_clear(P, 2*d - 1);
        _fmpz_vec_clear(T, 2*d - 1);
        fmpz_clear(Q);
        fmpz_clear(R);
    }
}
Beispiel #14
0
void fmpq_poly_randtest_unsigned(fmpq_poly_t poly, flint_rand_t state,
                                 long len, mp_bitcnt_t bits)
{
    ulong m;

    m = n_randlimb(NULL);

    fmpq_poly_fit_length(poly, len);
    _fmpq_poly_set_length(poly, len);

    if (m & 1UL)
    {
        _fmpz_vec_randtest_unsigned(poly->coeffs, state, len, bits);
    }
    else
    {
        fmpz_t x;

        fmpz_init(x);
        fmpz_randtest_unsigned(x, state, bits / 2);
        _fmpz_vec_randtest_unsigned(poly->coeffs, state, len, (bits + 1) / 2);
        _fmpz_vec_scalar_mul_fmpz(poly->coeffs, poly->coeffs, len, x);
        fmpz_clear(x);
    }

    if (m & 2UL)
    {
        fmpz_randtest_not_zero(poly->den, state, FLINT_MAX(bits, 1));
        fmpz_abs(poly->den, poly->den);
        fmpq_poly_canonicalise(poly);
    }
    else
    {
        fmpz_set_ui(poly->den, 1);
        _fmpq_poly_normalise(poly);
    }
}
Beispiel #15
0
/* Assumes len1 != 0 != len2 */
int
_fmpz_poly_gcd_heuristic(fmpz * res, const fmpz * poly1, long len1, 
                                        const fmpz * poly2, long len2)
{
	ulong bits1, bits2, max_bits, pack_bits, bound_bits, bits_G, bits_Q;
   ulong limbs1, limbs2, limbsg, pack_limbs, qlimbs;
   ulong log_glen, log_length;
   long sign1, sign2, glen, qlen;
	fmpz_t ac, bc, d, gc;
   fmpz * A, * B, * G, * Q, * t;
   mp_ptr array1, array2, arrayg, q, temp;
   int divides;

   fmpz_init(ac);
   fmpz_init(bc);
   fmpz_init(d);
   
	/* compute gcd of content of poly1 and poly2 */
   _fmpz_poly_content(ac, poly1, len1);
   _fmpz_poly_content(bc, poly2, len2);
   fmpz_gcd(d, ac, bc);

   /* special case, one of the polys is a constant */
   if (len2 == 1) /* if len1 == 1 then so does len2 */
   {
      fmpz_set(res, d);

      fmpz_clear(ac);
      fmpz_clear(bc);
	   fmpz_clear(d);

      return 1;
   }
   
   /* divide poly1 and poly2 by their content */
   A = _fmpz_vec_init(len1);
   B = _fmpz_vec_init(len2);
   _fmpz_vec_scalar_divexact_fmpz(A, poly1, len1, ac);
   _fmpz_vec_scalar_divexact_fmpz(B, poly2, len2, bc);
   fmpz_clear(ac);
   fmpz_clear(bc);
	   
	/* special case, one of the polys is length 2 */
   if (len2 == 2) /* if len1 == 2 then so does len2 */
	{
		Q = _fmpz_vec_init(len1 - len2 + 1);
		if (_fmpz_poly_divides(Q, A, len1, B, 2))
      {
		   _fmpz_vec_scalar_mul_fmpz(res, B, 2, d);
         if (fmpz_sgn(res + 1) < 0)
            _fmpz_vec_neg(res, res, 2);
      }
		else  
      {
			fmpz_set(res, d);
         fmpz_zero(res + 1);
      }

		fmpz_clear(d);
		_fmpz_vec_clear(A, len1);
      _fmpz_vec_clear(B, len2);
      _fmpz_vec_clear(Q, len1 - len2 + 1);
      
      return 1;
	}
	
   /* 
      Determine how many bits (pack_bits) to pack into. The bound 
      bound_bits ensures that if G | A and G | B with G primitive 
      then G is the gcd of A and B. The bound is taken from 
      http://arxiv.org/abs/cs/0206032v1
   */
   bits1 = FLINT_ABS(_fmpz_vec_max_bits(A, len1));
	bits2 = FLINT_ABS(_fmpz_vec_max_bits(B, len2));
	max_bits = FLINT_MAX(bits1, bits2);
   			
	bound_bits = FLINT_MIN(bits1, bits2) + 6; 
	pack_bits = FLINT_MAX(bound_bits, max_bits); /* need to pack original polys */
   pack_limbs = (pack_bits - 1)/FLINT_BITS + 1;
   
	if (pack_bits >= 32) /* pack into multiples of limbs if >= 32 bits */
      pack_bits = FLINT_BITS*pack_limbs;
		
   /* allocate space to pack into */
   limbs1 = (pack_bits*len1 - 1)/FLINT_BITS + 1;
   limbs2 = (pack_bits*len2 - 1)/FLINT_BITS + 1;
	array1 = flint_calloc(limbs1, sizeof(mp_limb_t));
   array2 = flint_calloc(limbs2, sizeof(mp_limb_t));
   arrayg = flint_calloc(limbs2, sizeof(mp_limb_t));
   
   /* pack first poly and normalise */
   sign1 = (long) fmpz_sgn(A + len1 - 1);
	_fmpz_poly_bit_pack(array1, A, len1, pack_bits, sign1);
	while (array1[limbs1 - 1] == 0) limbs1--;

   /* pack second poly and normalise */
   sign2 = (long) fmpz_sgn(B + len2 - 1);
   _fmpz_poly_bit_pack(array2, B, len2, pack_bits, sign2);
	while (array2[limbs2 - 1] == 0) limbs2--;
	
	/* compute integer GCD */
   limbsg = mpn_gcd_full(arrayg, array1, limbs1, array2, limbs2);
	
   /* 
      Make space for unpacked gcd. May have one extra coeff due to 
      1 0 -x being packed as 0 -1 -x. 
   */
   glen = FLINT_MIN((limbsg*FLINT_BITS)/pack_bits + 1, len2); 
   G = _fmpz_vec_init(glen);
   
   /* unpack gcd */
   _fmpz_poly_bit_unpack(G, glen, arrayg, pack_bits, 0);
   while (G[glen - 1] == 0) glen--;
   
	/* divide by any content */
   fmpz_init(gc);
	_fmpz_poly_content(gc, G, glen);

   if (!fmpz_is_one(gc)) 
      limbsg = mpn_tdiv_q_fmpz_inplace(arrayg, limbsg, gc);

   /* make space for quotient and remainder of first poly by gcd */
   qlimbs = limbs1 - limbsg + 1;
   qlen = FLINT_MIN(len1, (qlimbs*FLINT_BITS)/pack_bits + 1);
   qlimbs = (qlen*pack_bits - 1)/FLINT_BITS + 1;
   q = flint_calloc(qlimbs, sizeof(mp_limb_t));
   temp = flint_malloc(limbsg*sizeof(mp_limb_t));
   
	divides = 0;

   if (mpn_divides(q, array1, limbs1, arrayg, limbsg, temp)) 
	{
      /* unpack quotient of first poly by gcd */
      Q = _fmpz_vec_init(len1); 
      t = _fmpz_vec_init(len1 + glen);
      _fmpz_poly_bit_unpack(Q, qlen, q, pack_bits, 0);
      while (Q[qlen - 1] == 0) qlen--;
      
      /* divide by content */
      _fmpz_vec_scalar_divexact_fmpz(G, G, glen, gc);
		
      /* check if we really need to multiply out to check for exact quotient */
      bits_G = FLINT_ABS(_fmpz_vec_max_bits(G, glen));
		bits_Q = FLINT_ABS(_fmpz_vec_max_bits(Q, qlen));
		log_glen = FLINT_BIT_COUNT(glen);
		log_length = FLINT_MIN(log_glen, FLINT_BIT_COUNT(qlen));
       
	   divides = (bits_G + bits_Q + log_length < pack_bits);
     
      if (!divides) /* need to multiply out to check exact quotient */
         divides = multiplies_out(A, len1, Q, qlen, G, glen, sign1, t);

		if (divides) /* quotient really was exact */
		{
         mpn_zero(q, qlimbs);
          
         if (mpn_divides(q, array2, limbs2, arrayg, limbsg, temp)) 
	      {
            /* unpack quotient of second poly by gcd */
            qlimbs = limbs2 - limbsg + 1;
            qlen = FLINT_MIN(len2, (qlimbs*FLINT_BITS - 1)/pack_bits + 1);
            _fmpz_poly_bit_unpack(Q, qlen, q, pack_bits, 0);
            while (Q[qlen - 1] == 0) qlen--;
            
            /* check if we really need to multiply out to check for exact quotient */
            bits_Q = FLINT_ABS(_fmpz_vec_max_bits(Q, qlen));
				log_length = FLINT_MIN(log_glen, FLINT_BIT_COUNT(qlen));

				divides = (bits_G + bits_Q + log_length < pack_bits);
		      
            if (!divides) /* we need to multiply out */
               divides = multiplies_out(B, len2, Q, qlen, G, glen, sign1, t);
			} 
		} 

      _fmpz_vec_clear(t, len1 + glen);
      _fmpz_vec_clear(Q, len1);
	}

   flint_free(q); 
	flint_free(temp); 
	flint_free(arrayg); 
	flint_free(array1); 
	flint_free(array2); 
	fmpz_clear(gc); 
	
	_fmpz_vec_clear(A, len1);
	_fmpz_vec_clear(B, len2);
	
   /* we found the gcd, so multiply by content */
   if (divides)
   {
	   _fmpz_vec_zero(res + glen, len2 - glen);
      _fmpz_vec_scalar_mul_fmpz(res, G, glen, d);
   }
		
   fmpz_clear(d);
   _fmpz_vec_clear(G, glen);
		
   return divides;
}
Beispiel #16
0
static void 
_qadic_exp_bsplit_series(fmpz *P, fmpz_t Q, fmpz *T, 
                         const fmpz *x, slong len, slong lo, slong hi, 
                         const fmpz *a, const slong *j, slong lena)
{
    const slong d = j[lena - 1];

    if (hi - lo == 1)
    {
        _fmpz_vec_set(P, x, len);
        _fmpz_vec_zero(P + len, 2*d - 1 - len);

        fmpz_set_si(Q, lo);

        _fmpz_vec_set(T, P, 2*d - 1);
    }
    else if (hi - lo == 2)
    {
        _fmpz_poly_sqr(P, x, len);
        _fmpz_vec_zero(P + (2*len - 1), d - (2*len - 1));
        _fmpz_poly_reduce(P, 2*len - 1, a, j, lena);

        fmpz_set_si(Q, lo);
        fmpz_mul_si(Q, Q, lo + 1);

        _fmpz_vec_scalar_mul_si(T, x, len, lo + 1);
        _fmpz_vec_zero(T + len, d - len);
        _fmpz_vec_add(T, T, P, d);
    }
    else
    {
        const slong m = (lo + hi) / 2;

        fmpz *PR, *TR, *W;
        fmpz_t QR;

        PR = _fmpz_vec_init(2*d - 1);
        TR = _fmpz_vec_init(2*d - 1);
        W  = _fmpz_vec_init(2*d - 1);
        fmpz_init(QR);

        _qadic_exp_bsplit_series(P, Q, T, x, len, lo, m, a, j, lena);

        _qadic_exp_bsplit_series(PR, QR, TR, x, len, m, hi, a, j, lena);

        _fmpz_poly_mul(W, TR, d, P, d);
        _fmpz_poly_reduce(W, 2*d - 1, a, j, lena);

        _fmpz_vec_scalar_mul_fmpz(T, T, d, QR);
        _fmpz_vec_add(T, T, W, d);

        _fmpz_poly_mul(W, P, d, PR, d);
        _fmpz_poly_reduce(W, 2*d - 1, a, j, lena);
        _fmpz_vec_swap(P, W, d);

        fmpz_mul(Q, Q, QR);

        _fmpz_vec_clear(PR, 2*d - 1);
        _fmpz_vec_clear(TR, 2*d - 1);
        _fmpz_vec_clear(W,  2*d - 1);
        fmpz_clear(QR);
    }
}
Beispiel #17
0
int
main(void)
{
    int i, result;
    flint_rand_t state;

    printf("scalar_submul_fmpz....");
    fflush(stdout);

    flint_randinit(state);

    /* Compare with fmpz_vec_scalar_submul_si */
    for (i = 0; i < 10000; i++)
    {
        fmpz *a, *b, *c;
        long len, n;
        fmpz_t n1;
        len = n_randint(state, 100);
        n = (long) n_randbits(state, FLINT_BITS - 1);
        if (n_randint(state, 2))
            n = -n;
        fmpz_init(n1);
        fmpz_set_si(n1, n);

        a = _fmpz_vec_init(len);
        b = _fmpz_vec_init(len);
        c = _fmpz_vec_init(len);
        _fmpz_vec_randtest(a, state, len, 200);
        _fmpz_vec_randtest(b, state, len, 200);
        _fmpz_vec_set(c, b, len);

        _fmpz_vec_scalar_submul_fmpz(b, a, len, n1);
        _fmpz_vec_scalar_submul_si(c, a, len, n);

        result = (_fmpz_vec_equal(c, b, len));
        if (!result)
        {
            printf("FAIL:\n");
            _fmpz_vec_print(c, len), printf("\n\n");
            _fmpz_vec_print(b, len), printf("\n\n");
            abort();
        }

        fmpz_clear(n1);
        _fmpz_vec_clear(a, len);
        _fmpz_vec_clear(b, len);
        _fmpz_vec_clear(c, len);
    }

    /* Compute a different way */
    for (i = 0; i < 10000; i++)
    {
        fmpz *a, *b, *c, *d;
        long len = n_randint(state, 100);
        fmpz_t n1;
        fmpz_init(n1);
        fmpz_randtest(n1, state, 200);

        a = _fmpz_vec_init(len);
        b = _fmpz_vec_init(len);
        c = _fmpz_vec_init(len);
        d = _fmpz_vec_init(len);
        _fmpz_vec_randtest(a, state, len, 200);
        _fmpz_vec_randtest(b, state, len, 200);
        _fmpz_vec_set(c, b, len);

        _fmpz_vec_scalar_submul_fmpz(b, a, len, n1);
        _fmpz_vec_scalar_mul_fmpz(d, a, len, n1);
        _fmpz_vec_sub(c, c, d, len);

        result = (_fmpz_vec_equal(c, b, len));
        if (!result)
        {
            printf("FAIL:\n");
            _fmpz_vec_print(c, len), printf("\n\n");
            _fmpz_vec_print(b, len), printf("\n\n");
            abort();
        }

        fmpz_clear(n1);
        _fmpz_vec_clear(a, len);
        _fmpz_vec_clear(b, len);
        _fmpz_vec_clear(c, len);
        _fmpz_vec_clear(d, len);
    }

    flint_randclear(state);
    _fmpz_cleanup();
    printf("PASS\n");
    return 0;
}
Beispiel #18
0
void _padic_poly_sub(fmpz *rop, slong *val, slong N, 
                     const fmpz *op1, slong val1, slong len1, slong N1, 
                     const fmpz *op2, slong val2, slong len2, slong N2, 
                     const padic_ctx_t ctx)
{
    const slong len = FLINT_MAX(len1, len2);

    *val = FLINT_MIN(val1, val2);

    if (val1 == val2)
    {
        _fmpz_poly_sub(rop, op1, len1, op2, len2);
        _padic_poly_canonicalise(rop, val, len, ctx->p);
    }
    else
    {
        fmpz_t x;

        fmpz_init(x);
        if (val1 < val2)  /* F := p^g (G - p^{h-g} H) */
        {
            fmpz_pow_ui(x, ctx->p, val2 - val1);

            if (rop == op1)
            {
                _fmpz_vec_zero(rop + len1, len2 - len1);
                _fmpz_vec_scalar_submul_fmpz(rop, op2, len2, x);
            }
            else
            {
                _fmpz_vec_scalar_mul_fmpz(rop, op2, len2, x);
                _fmpz_vec_neg(rop, rop, len2);
                _fmpz_poly_add(rop, op1, len1, rop, len2);
            }
        }
        else  /* F := p^h (p^(g-h) G - H) */
        {
            fmpz_pow_ui(x, ctx->p, val1 - val2);

            if (rop == op2)
            {
                _fmpz_vec_neg(rop, op2, len2);
                _fmpz_vec_zero(rop + len2, len1 - len2);
                _fmpz_vec_scalar_addmul_fmpz(rop, op1, len1, x);
            }
            else
            {
                _fmpz_vec_scalar_mul_fmpz(rop, op1, len1, x);
                _fmpz_poly_sub(rop, rop, len1, op2, len2);
            }
        }
        fmpz_clear(x);
    }

    /* Reduce */
    if (N - *val > 0)
    {
        fmpz_t pow;
        int alloc;

        alloc = _padic_ctx_pow_ui(pow, N - *val, ctx);

        if (N >= N1 && N >= N2)
        {
            slong i;
            for (i = 0; i < len; i++)
                if (fmpz_sgn(rop + i) < 0)
                    fmpz_add(rop + i, rop + i, pow);
        }
        else
        {
            _fmpz_vec_scalar_mod_fmpz(rop, rop, len, pow);
        }

        if (alloc)
            fmpz_clear(pow);
    }
    else
    {
        _fmpz_vec_zero(rop, len);
        *val = 0;
    }
}
Beispiel #19
0
void _fmpq_poly_scalar_div_mpq(fmpz * rpoly, fmpz_t rden, 
                               const fmpz * poly, const fmpz_t den, long len, 
                               const fmpz_t r, const fmpz_t s)
{
    fmpz_t gcd1;  /* GCD( poly, r ) */
    fmpz_t gcd2;  /* GCD( s, den )  */
    fmpz_init(gcd1);
    fmpz_init(gcd2);
    fmpz_set_ui(gcd1, 1);
    fmpz_set_ui(gcd2, 1);
    if (*r != 1L)
    {
        _fmpz_vec_content(gcd1, poly, len);
        if (*gcd1 != 1L)
            fmpz_gcd(gcd1, gcd1, r);
    }
    if (*den != 1L && *s != 1L)
        fmpz_gcd(gcd2, s, den);
    
    if (*gcd1 == 1L)
    {
        if (*gcd2 == 1L)
        {
            _fmpz_vec_scalar_mul_fmpz(rpoly, poly, len, s);
            fmpz_mul(rden, den, r);
        }
        else
        {
            fmpz_t s2;
            fmpz_init(s2);
            fmpz_divexact(s2, s, gcd2);
            _fmpz_vec_scalar_mul_fmpz(rpoly, poly, len, s2);
            fmpz_divexact(rden, den, gcd2);
            fmpz_mul(rden, rden, r);
            fmpz_clear(s2);
        }
    }
    else
    {
        fmpz_t r2;
        fmpz_init(r2);
        fmpz_divexact(r2, r, gcd1);
        if (*gcd2 == 1L)
        {
            _fmpz_vec_scalar_divexact_fmpz(rpoly, poly, len, gcd1);
            _fmpz_vec_scalar_mul_fmpz(rpoly, rpoly, len, s);
            fmpz_mul(rden, den, r2);
        }
        else
        {
            fmpz_t s2;
            fmpz_init(s2);
            fmpz_divexact(s2, s, gcd2);
            _fmpz_vec_scalar_divexact_fmpz(rpoly, poly, len, gcd1);
            _fmpz_vec_scalar_mul_fmpz(rpoly, rpoly, len, s2);
            fmpz_divexact(rden, den, gcd2);
            fmpz_mul(rden, rden, r2);
            fmpz_clear(s2);
        }
        fmpz_clear(r2);
    }
    
    if (_fmpz_vec_is_zero(rpoly, len))
        fmpz_set_ui(rden, 1);
    if (fmpz_sgn(rden) < 0)
    {
        _fmpz_vec_neg(rpoly, rpoly, len);
        fmpz_neg(rden, rden);
    }
    
    fmpz_clear(gcd1);
    fmpz_clear(gcd2);
}
Beispiel #20
0
void
_fmpz_poly_compose_divconquer(fmpz * res, const fmpz * poly1, long len1, 
                                          const fmpz * poly2, long len2)
{
    long i, j, k, n;
    long *hlen, alloc, powlen;
    fmpz *v, **h, *pow, *temp;
    
    if (len1 == 1)
    {
        fmpz_set(res, poly1);
        return;
    }
    if (len2 == 1)
    {
        _fmpz_poly_evaluate_fmpz(res, poly1, len1, poly2);
        return;
    }
    if (len1 == 2)
    {
        _fmpz_poly_compose_horner(res, poly1, len1, poly2, len2);
        return;
    }

    /* Initialisation */
    
    hlen = (long *) malloc(((len1 + 1) / 2) * sizeof(long));
    
    for (k = 1; (2 << k) < len1; k++) ;
    
    hlen[0] = hlen[1] = ((1 << k) - 1) * (len2 - 1) + 1;
    for (i = k - 1; i > 0; i--)
    {
        long hi = (len1 + (1 << i) - 1) / (1 << i);
        for (n = (hi + 1) / 2; n < hi; n++)
            hlen[n] = ((1 << i) - 1) * (len2 - 1) + 1;
    }
    powlen = (1 << k) * (len2 - 1) + 1;
    
    alloc = 0;
    for (i = 0; i < (len1 + 1) / 2; i++)
        alloc += hlen[i];

    v = _fmpz_vec_init(alloc +  2 * powlen);
    h = (fmpz **) malloc(((len1 + 1) / 2) * sizeof(fmpz *));
    h[0] = v;
    for (i = 0; i < (len1 - 1) / 2; i++)
    {
        h[i + 1] = h[i] + hlen[i];
        hlen[i]  = 0;
    }
    hlen[(len1 - 1) / 2] = 0;
    pow  = v + alloc;
    temp = pow + powlen;
    
    /* Let's start the actual work */
    
    for (i = 0, j = 0; i < len1 / 2; i++, j += 2)
    {
        if (poly1[j + 1] != 0L)
        {
            _fmpz_vec_scalar_mul_fmpz(h[i], poly2, len2, poly1 + j + 1);
            fmpz_add(h[i], h[i], poly1 + j);
            hlen[i] = len2;
        }
        else if (poly1[j] != 0L)
        {
            fmpz_set(h[i], poly1 + j);
            hlen[i] = 1;
        }
    }
    if ((len1 & 1L))
    {
        if (poly1[j] != 0L)
        {
            fmpz_set(h[i], poly1 + j);
            hlen[i] = 1;
        }
    }
    
    _fmpz_poly_mul(pow, poly2, len2, poly2, len2);
    powlen = 2 * len2 - 1;
    
    for (n = (len1 + 1) / 2; n > 2; n = (n + 1) / 2)
    {
        if (hlen[1] > 0)
        {
            long templen = powlen + hlen[1] - 1;
            _fmpz_poly_mul(temp, pow, powlen, h[1], hlen[1]);
            _fmpz_poly_add(h[0], temp, templen, h[0], hlen[0]);
            hlen[0] = FLINT_MAX(hlen[0], templen);
        }
        
        for (i = 1; i < n / 2; i++)
        {
            if (hlen[2*i + 1] > 0)
            {
                _fmpz_poly_mul(h[i], pow, powlen, h[2*i + 1], hlen[2*i + 1]);
                hlen[i] = hlen[2*i + 1] + powlen - 1;
            } else
                hlen[i] = 0;
            _fmpz_poly_add(h[i], h[i], hlen[i], h[2*i], hlen[2*i]);
            hlen[i] = FLINT_MAX(hlen[i], hlen[2*i]);
        }
        if ((n & 1L))
        {
            _fmpz_vec_set(h[i], h[2*i], hlen[2*i]);
            hlen[i] = hlen[2*i];
        }
        
        _fmpz_poly_mul(temp, pow, powlen, pow, powlen);
        powlen += powlen - 1;
        {
            fmpz * t = pow;
            pow      = temp;
            temp     = t;
        }
    }

    _fmpz_poly_mul(res, pow, powlen, h[1], hlen[1]);
    _fmpz_vec_add(res, res, h[0], hlen[0]);
    
    _fmpz_vec_clear(v, alloc + 2 * powlen);
    free(h);
    free(hlen);
}
Beispiel #21
0
void 
_fmpq_poly_inv_series_newton(fmpz * Qinv, fmpz_t Qinvden, 
                             const fmpz * Q, const fmpz_t Qden, long n)
{
    if (n == 1)
    {
        if (fmpz_sgn(Q) > 0)
        {
            fmpz_set(Qinv, Qden);
            fmpz_set(Qinvden, Q);
        }
        else
        {
            fmpz_neg(Qinv, Qden);
            fmpz_neg(Qinvden, Q);
        }
    }
    else
    {
        const long alloc = FLINT_MAX(n, 3 * FMPQ_POLY_INV_NEWTON_CUTOFF);
        long *a, i, m;
        fmpz *W, *Wden;

        W = _fmpz_vec_init(alloc + 1);
        Wden = W + alloc;

        for (i = 1; (1L << i) < n; i++) ;

        a = (long *) flint_malloc(i * sizeof(long));
        a[i = 0] = n;
        while (n >= FMPQ_POLY_INV_NEWTON_CUTOFF)
            a[++i] = (n = (n + 1) / 2);

        /* Base case */
        {
            fmpz *rev = W + 2 * FMPQ_POLY_INV_NEWTON_CUTOFF;

            _fmpz_poly_reverse(rev, Q, n, n);
            _fmpz_vec_zero(W, 2*n - 2);
            fmpz_one(W + (2*n - 2));
            fmpz_one(Wden);

            _fmpq_poly_div(Qinv, Qinvden, W, Wden, 2*n - 1, rev, Qden, n);
            _fmpq_poly_canonicalise(Qinv, Qinvden, n);

            _fmpz_poly_reverse(Qinv, Qinv, n, n);
        }

        for (i--; i >= 0; i--)
        {
            m = n;
            n = a[i];

            _fmpz_poly_mullow(W, Q, n, Qinv, m, n);
            fmpz_mul(Wden, Qden, Qinvden);

            _fmpz_poly_mullow(Qinv + m, Qinv, m, W + m, n - m, n - m);
            fmpz_mul(Qinvden, Qinvden, Wden);
            _fmpz_vec_scalar_mul_fmpz(Qinv, Qinv, m, Wden);

            _fmpz_vec_neg(Qinv + m, Qinv + m, n - m);

            _fmpq_poly_canonicalise(Qinv, Qinvden, n);
        }

        _fmpz_vec_clear(W, alloc + 1);
        flint_free(a);
    }
}