Exemple #1
0
static void
_toposort_init(_toposort_s *s, slong size)
{
    s->size = size;
    s->u = flint_calloc(size, sizeof(int));
    s->v = flint_calloc(size, sizeof(int));
    s->post = flint_malloc(size * sizeof(slong));
    s->npost = 0;
}
static void
_tarjan_init(_tarjan_t t, slong dim)
{
    slong i;
    t->index = flint_calloc(dim, sizeof(slong));
    t->lowlink = flint_calloc(dim, sizeof(slong));
    t->onstack = flint_calloc(dim, sizeof(int));
    _si_stack_init(t->S, dim);
    t->dim = dim;
    t->nsccs = 0;
    t->idx = 0;
    for (i = 0; i < dim; i++)
    {
        t->index[i] = _tarjan_UNDEFINED;
    }
}
Exemple #3
0
/* Assumes poly1 and poly2 are not length 0 and len1 >= len2. */
void
_fmpz_poly_mul_karatsuba(fmpz * res, const fmpz * poly1,
                         long len1, const fmpz * poly2, long len2)
{
    fmpz *rev1, *rev2, *out, *temp;
    long length, loglen = 0;

    if (len1 == 1)
    {
        fmpz_mul(res, poly1, poly2);
        return;
    }

    while ((1L << loglen) < len1)
        loglen++;
    length = (1L << loglen);

    rev1 = (fmpz *) flint_calloc(4 * length, sizeof(fmpz *));
    rev2 = rev1 + length;
    out  = rev1 + 2 * length;
    temp = _fmpz_vec_init(2 * length);

    revbin1(rev1, poly1, len1, loglen);
    revbin1(rev2, poly2, len2, loglen);

    _fmpz_poly_mul_kara_recursive(out, rev1, rev2, temp, loglen);

    _fmpz_vec_zero(res, len1 + len2 - 1);
    revbin2(res, out, len1 + len2 - 1, loglen + 1);

    _fmpz_vec_clear(temp, 2 * length);
    flint_free(rev1);
}
Exemple #4
0
void
fmpz_poly_realloc(fmpz_poly_t poly, long alloc)
{
    if (alloc == 0)             /* Clear up, reinitialise */
    {
        fmpz_poly_clear(poly);
        fmpz_poly_init(poly);
        return;
    }

    if (poly->alloc)            /* Realloc */
    {
        fmpz_poly_truncate(poly, alloc);

        poly->coeffs = (fmpz *) flint_realloc(poly->coeffs, alloc * sizeof(fmpz));
        if (alloc > poly->alloc)
            mpn_zero((mp_ptr) (poly->coeffs + poly->alloc),
                     alloc - poly->alloc);
    }
    else                        /* Nothing allocated already so do it now */
    {
        poly->coeffs = (fmpz *) flint_calloc(alloc, sizeof(fmpz));
    }

    poly->alloc = alloc;
}
Exemple #5
0
void padic_poly_init2(padic_poly_t poly, slong alloc, slong prec)
{
    poly->coeffs = alloc ? (fmpz *) flint_calloc(alloc, sizeof(fmpz)) : NULL;
    poly->alloc  = alloc;
    poly->length = 0;
    poly->val    = 0;
    poly->N      = prec;
}
Exemple #6
0
int
main(void)
{
    int i;
    mp_size_t j;

    flint_rand_t state;

    printf("split/combine_bits....");
    fflush(stdout);

    flint_randinit(state);
    _flint_rand_init_gmp(state);

    for (i = 0; i < 10000; i++)
    {
        mp_size_t total_limbs = n_randint(state, 1000) + 1;
        mp_limb_t * in = flint_malloc(total_limbs*sizeof(mp_limb_t));
        mp_limb_t * out = flint_calloc(total_limbs, sizeof(mp_limb_t));
        
        mp_bitcnt_t bits = n_randint(state, 200) + 1;
        mp_size_t limbs = (2*bits - 1)/FLINT_BITS + 1;
        long length = (total_limbs*FLINT_BITS - 1)/bits + 1;
        
        mp_limb_t ** poly;
        poly = flint_malloc(length*sizeof(mp_limb_t *));
        for (j = 0; j < length; j++)
           poly[j] = flint_malloc((limbs + 1)*sizeof(mp_limb_t));

        mpn_urandomb(in, state->gmp_state, total_limbs*FLINT_BITS);

        fft_split_bits(poly, in, total_limbs, bits, limbs);
        fft_combine_bits(out, poly, length, bits, limbs, total_limbs);
        
        for (j = 0; j < total_limbs; j++)
        {
           if (in[j] != out[j])
           {
              printf("FAIL:\n");
              printf("Error in limb %ld, %lu != %lu\n", j, in[j], out[j]);
              abort();
           }
        }

        flint_free(in);
        flint_free(out);

        for (j = 0; j < length; j++)
           flint_free(poly[j]);

        flint_free(poly);
    }

    flint_randclear(state);
    
    printf("PASS\n");
    return 0;
}
Exemple #7
0
void fmpz_mod_poly_init2(fmpz_mod_poly_t poly, const fmpz_t p, slong alloc)
{
    if (alloc)                  /* allocate space for alloc small coeffs */
        poly->coeffs = (fmpz *) flint_calloc(alloc, sizeof(fmpz));
    else
        poly->coeffs = NULL;

    poly->alloc = alloc;
    poly->length = 0;
    fmpz_init(&(poly->p));
    fmpz_set(&(poly->p), p);
}
Exemple #8
0
void fmpz_poly_factor_realloc(fmpz_poly_factor_t fac, long alloc)
{
    if (alloc == 0)             /* Clear up, reinitialise */
    {
        fmpz_poly_factor_clear(fac);
        fmpz_poly_factor_init(fac);
    }
    else if (fac->alloc)            /* Realloc */
    {
        if (fac->alloc > alloc)
        {
            long i;

            for (i = alloc; i < fac->num; i++)
                fmpz_poly_clear(fac->p + i);

            fac->p   = flint_realloc(fac->p, alloc * sizeof(fmpz_poly_struct));
            fac->exp = flint_realloc(fac->exp, alloc * sizeof(long));
            fac->alloc     = alloc;
        }
        else if (fac->alloc < alloc)
        {
            long i;

            fac->p   = flint_realloc(fac->p, alloc * sizeof(fmpz_poly_struct));
            fac->exp = flint_realloc(fac->exp, alloc * sizeof(long));

            for (i = fac->alloc; i < alloc; i++)
            {
                fmpz_poly_init(fac->p + i);
                fac->exp[i] = 0L;
            }
            fac->alloc = alloc;
        }
    }
    else                        /* Nothing allocated already so do it now */
    {
        long i;

        fac->p   = flint_malloc(alloc * sizeof(fmpz_poly_struct));
        fac->exp = flint_calloc(alloc, sizeof(long));

        for (i = 0; i < alloc; i++)
            fmpz_poly_init(fac->p + i);
        fac->num   = 0;
        fac->alloc = alloc;
    }
}
Exemple #9
0
void _fmpz_poly_sqrlow_KS(fmpz * res, const fmpz * poly, long len, long n)
{
    int neg;
    long bits, limbs, loglen, sign = 0;
    mp_limb_t *arr_in, *arr_out;

    FMPZ_VEC_NORM(poly, len);

    if (len == 0)
    {
        _fmpz_vec_zero(res, n);
        return;
    }

    neg = (fmpz_sgn(poly + len - 1) > 0) ? 0 : -1;

    if (n > 2 * len - 1)
    {
        _fmpz_vec_zero(res + 2 * len - 1, n - (2 * len - 1));
        n = 2 * len - 1;
    }

    bits = _fmpz_vec_max_bits(poly, len);
    if (bits < 0)
    {
        sign = 1;
        bits = - bits;
    }

    loglen = FLINT_BIT_COUNT(len);
    bits   = 2 * bits + loglen + sign;
    limbs  = (bits * len - 1) / FLINT_BITS + 1;

    arr_in  = flint_calloc(limbs, sizeof(mp_limb_t));
    arr_out = flint_malloc((2 * limbs) * sizeof(mp_limb_t));

    _fmpz_poly_bit_pack(arr_in, poly, len, bits, neg);

    mpn_sqr(arr_out, arr_in, limbs);

    if (sign)
        _fmpz_poly_bit_unpack(res, n, arr_out, bits, 0);
    else
        _fmpz_poly_bit_unpack_unsigned(res, n, arr_out, bits);

    flint_free(arr_in);
    flint_free(arr_out);
}
Exemple #10
0
void 
tmod_mat_init(tmod_mat_t mat, long rows, long cols)
 {
  if(rows && cols)
   {
    slong i;
    mp_limb_t* e;
    mat->entries = flint_calloc(rows * cols, sizeof(mp_limb_t));
    mat->rows = flint_malloc(rows * sizeof(mp_limb_t *));
    e = mat->entries;
    for (i = 0; i < rows; i++, e += cols)
      mat->rows[i] = e;
   }
  else
   mat->entries = NULL;
  mat->r = rows;
  mat->c = cols;
 }
Exemple #11
0
void
nmod_mat_init(nmod_mat_t mat, long rows, long cols, mp_limb_t n)
{
    if ((rows) && (cols))
    {
        long i;
        mat->entries = flint_calloc(rows * cols, sizeof(mp_limb_t));
        mat->rows = flint_malloc(rows * sizeof(mp_limb_t *));

        for (i = 0; i < rows; i++)
            mat->rows[i] = mat->entries + i * cols;
    }
    else
        mat->entries = NULL;

    mat->r = rows;
    mat->c = cols;

    _nmod_mat_set_mod(mat, n);
}
Exemple #12
0
void fmpq_mat_init(fmpq_mat_t mat, slong rows, slong cols)
{
    if ((rows) && (cols))
    {
        slong i;
        mat->entries = (fmpq *) flint_calloc(rows * cols, sizeof(fmpq));
        mat->rows = (fmpq **) flint_malloc(rows * sizeof(fmpq *));

        /* Set denominators */
        for (i = 0; i < rows * cols; i++)
            mat->entries[i].den = WORD(1);

        for (i = 0; i < rows; i++)
            mat->rows[i] = mat->entries + i * cols;
    }
    else
        mat->entries = NULL;

    mat->r = rows;
    mat->c = cols;
}
Exemple #13
0
void
acb_modular_theta_const_sum_rs(acb_t theta2, acb_t theta3, acb_t theta4,
                               const acb_t q, long N, long prec)
{
    long * tab;
    long k, term_prec, i, e, eprev;
    long M, m2, m3, num_square, num_trigonal;
    double log2q_approx, log2term_approx;
    acb_ptr qpow;
    acb_t tmp1, tmp2;
    mag_t qmag;

    mag_init(qmag);
    acb_get_mag(qmag, q);
    log2q_approx = mag_get_log2_d_approx(qmag);
    mag_clear(qmag);

    acb_init(tmp1);
    acb_init(tmp2);

    /* choose rectangular splitting parameters */
    m2 = acb_modular_rs_optimal_m(trigonal_best_m, trigonal_best_m_residues, N);
    m3 = acb_modular_rs_optimal_m(square_best_m, square_best_m_residues, N);
    M = FLINT_MAX(m2, m3) + 1;

    /* build addition sequence */
    tab = flint_calloc(M, sizeof(long));

    for (k = 0; k*(k+1) < N; k++)
        tab[(k*(k+1)) % m2] = -1;
    num_trigonal = k;

    for (k = 0; k*k < N; k++)
        tab[(k*k) % m3] = -1;
    num_square = k;

    tab[m2] = -1;
    tab[m3] = -1;

    /* compute powers in addition sequence */
    qpow = _acb_vec_init(M);
    acb_modular_fill_addseq(tab, M);

    for (k = 0; k < M; k++)
    {
        if (k == 0)
        {
            acb_one(qpow + k);
        }
        else if (k == 1)
        {
            acb_set_round(qpow + k, q, prec);
        }
        else if (tab[k] != 0)
        {
            log2term_approx = k * log2q_approx;
            term_prec = FLINT_MIN(FLINT_MAX(prec + log2term_approx + 16.0, 16.0), prec);
            acb_mul_approx(qpow + k, tmp1, tmp2, qpow + tab[k], qpow + k - tab[k], term_prec, prec);
        }
    }

    /* compute theta2 */
    acb_zero(theta2);
    term_prec = prec;

    for (k = num_trigonal - 1; k >= 0; k--)
    {
        e = k * (k + 1);  /* exponent */
        eprev = (k + 1) * (k + 2);

        log2term_approx = e * log2q_approx;
        term_prec = FLINT_MIN(FLINT_MAX(prec + log2term_approx + 16.0, 16.0), prec);

        /* giant steps */
        for (i = e / m2; i < eprev / m2; i++)
        {
            if (!acb_is_zero(theta2))
                acb_mul_approx(theta2, tmp1, tmp2, theta2, qpow + m2, term_prec, prec);
        }

        acb_add(theta2, theta2, qpow + (e % m2), prec);
    }

    acb_mul_2exp_si(theta2, theta2, 1);

    /* compute theta3, theta4 */
    acb_zero(theta3);
    acb_zero(theta4);
    term_prec = prec;

    for (k = num_square - 1; k >= 0; k--)
    {
        e = k * k;  /* exponent */
        eprev = (k + 1) * (k + 1);

        log2term_approx = e * log2q_approx;
        term_prec = FLINT_MIN(FLINT_MAX(prec + log2term_approx + 16.0, 16.0), prec);

        /* giant steps */
        for (i = e / m3; i < eprev / m3; i++)
        {
            if (!acb_is_zero(theta3))
                acb_mul_approx(theta3, tmp1, tmp2, theta3, qpow + m3, term_prec, prec);

            if (!acb_is_zero(theta4))
                acb_mul_approx(theta4, tmp1, tmp2, theta4, qpow + m3, term_prec, prec);
        }

        if (k == 0)
        {
            acb_mul_2exp_si(theta3, theta3, 1);
            acb_mul_2exp_si(theta4, theta4, 1);
        }

        acb_add(theta3, theta3, qpow + (e % m3), prec);

        if (k % 2 == 0)
            acb_add(theta4, theta4, qpow + (e % m3), prec);
        else
            acb_sub(theta4, theta4, qpow + (e % m3), prec);
    }

    acb_clear(tmp1);
    acb_clear(tmp2);

    _acb_vec_clear(qpow, M);
    flint_free(tab);
}
void
_acb_poly_powsum_one_series_sieved(acb_ptr z, const acb_t s, slong n, slong len, slong prec)
{
    slong * divisors;
    slong powers_alloc;
    slong i, j, k, ibound, kprev, power_of_two, horner_point;
    int critical_line, integer;

    acb_ptr powers;
    acb_ptr t, u, x;
    acb_ptr p1, p2;
    arb_t logk, v, w;

    critical_line = arb_is_exact(acb_realref(s)) &&
        (arf_cmp_2exp_si(arb_midref(acb_realref(s)), -1) == 0);

    integer = arb_is_zero(acb_imagref(s)) && arb_is_int(acb_realref(s));

    divisors = flint_calloc(n / 2 + 1, sizeof(slong));
    powers_alloc = (n / 6 + 1) * len;
    powers = _acb_vec_init(powers_alloc);

    ibound = n_sqrt(n);
    for (i = 3; i <= ibound; i += 2)
        if (DIVISOR(i) == 0)
            for (j = i * i; j <= n; j += 2 * i)
                DIVISOR(j) = i;

    t = _acb_vec_init(len);
    u = _acb_vec_init(len);
    x = _acb_vec_init(len);
    arb_init(logk);
    arb_init(v);
    arb_init(w);

    power_of_two = 1;
    while (power_of_two * 2 <= n)
        power_of_two *= 2;
    horner_point = n / power_of_two;

    _acb_vec_zero(z, len);

    kprev = 0;
    COMPUTE_POWER(x, 2, kprev);

    for (k = 1; k <= n; k += 2)
    {
        /* t = k^(-s) */
        if (DIVISOR(k) == 0)
        {
            COMPUTE_POWER(t, k, kprev);
        }
        else
        {
            p1 = POWER(DIVISOR(k));
            p2 = POWER(k / DIVISOR(k));

            if (len == 1)
                acb_mul(t, p1, p2, prec);
            else
                _acb_poly_mullow(t, p1, len, p2, len, len, prec);
        }

        if (k * 3 <= n)
            _acb_vec_set(POWER(k), t, len);

        _acb_vec_add(u, u, t, len, prec);

        while (k == horner_point && power_of_two != 1)
        {
            _acb_poly_mullow(t, z, len, x, len, len, prec);
            _acb_vec_add(z, t, u, len, prec);

            power_of_two /= 2;
            horner_point = n / power_of_two;
            horner_point -= (horner_point % 2 == 0);
        }
    }

    _acb_poly_mullow(t, z, len, x, len, len, prec);
    _acb_vec_add(z, t, u, len, prec);

    flint_free(divisors);
    _acb_vec_clear(powers, powers_alloc);
    _acb_vec_clear(t, len);
    _acb_vec_clear(u, len);
    _acb_vec_clear(x, len);
    arb_clear(logk);
    arb_clear(v);
    arb_clear(w);
}
Exemple #15
0
slong
_acb_poly_validate_roots(acb_ptr roots,
        acb_srcptr poly, slong len, slong prec)
{
    slong i, j, deg;
    slong isolated, nonisolated, total_isolated;
    acb_ptr deriv;
    acb_ptr tmp;
    int *overlap;

    deg = len - 1;

    deriv = _acb_vec_init(deg);
    overlap = flint_calloc(deg, sizeof(int));
    tmp = flint_malloc(sizeof(acb_struct) * deg);

    _acb_poly_derivative(deriv, poly, len, prec);

    /* compute an inclusion interval for each point */
    for (i = 0; i < deg; i++)
    {
        _acb_poly_root_inclusion(roots + i, roots + i,
            poly, deriv, len, prec);
    }

    /* find which points do not overlap with any other points */
    for (i = 0; i < deg; i++)
    {
        for (j = i + 1; j < deg; j++)
        {
            if (acb_overlaps(roots + i, roots + j))
            {
                overlap[i] = overlap[j] = 1;
            }
        }
    }

    /* count and move all isolated roots to the front of the array */
    total_isolated = 0;
    for (i = 0; i < deg; i++)
        total_isolated += (overlap[i] == 0);

    for (i = 0; i < deg; i++)
        tmp[i] = roots[i];

    isolated = 0;
    nonisolated = 0;
    for (i = 0; i < deg; i++)
    {
        if (overlap[i] == 0)
        {
            roots[isolated] = tmp[i];
            isolated++;
        }
        else
        {
            roots[total_isolated + nonisolated] = tmp[i];
            nonisolated++;
        }
    }

    _acb_vec_clear(deriv, deg);
    flint_free(tmp);
    flint_free(overlap);

    return isolated;
}
Exemple #16
0
void _qadic_norm_resultant(fmpz_t rop, const fmpz *op, slong len, 
                           const fmpz *a, const slong *j, slong lena, 
                           const fmpz_t p, slong N)
{
    const slong d = j[lena - 1];

    fmpz_t pN;

    fmpz_init(pN);
    fmpz_pow_ui(pN, p, N);

    if (len == 1)
    {
        fmpz_powm_ui(rop, op + 0, d, pN);
    }
    else  /* len >= 2 */
    {
        {
            const slong n = d + len - 1;
            slong i, k;
            fmpz *M;

            M = flint_calloc(n * n, sizeof(fmpz));

            for (k = 0; k < len-1; k++)
            {
                for (i = 0; i < lena; i++)
                {
                    M[k * n + k + (d - j[i])] = a[i];
                }
            }
            for (k = 0; k < d; k++)
            {
                for (i = 0; i < len; i++)
                {
                    M[(len-1 + k) * n + k + (len-1 - i)] = op[i];
                }
            }

            _fmpz_mod_mat_det(rop, M, n, pN);
            
            flint_free(M);
        }

        /*
            XXX:  This part of the code is currently untested as the Conway 
            polynomials used for the extension Qq/Qp are monic.
         */
        if (!fmpz_is_one(a + (lena - 1)))
        {
            fmpz_t f;

            fmpz_init(f);
            fmpz_powm_ui(f, a + (lena - 1), len - 1, pN);
            _padic_inv(f, f, p, N);
            fmpz_mul(rop, f, rop);
            fmpz_mod(rop, rop, pN);
            fmpz_clear(f);
        }
    }
    fmpz_clear(pN);
}
Exemple #17
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;
}
void
acb_modular_theta_const_sum_basecase(acb_t theta2, acb_t theta3, acb_t theta4,
    const acb_t q, slong N, slong prec)
{
    slong * tab;
    slong k, term_prec;
    double log2q_approx, log2term_approx;
    mag_t qmag;
    acb_ptr qpow;
    acb_t s1, s2, s3, t1, t2;

    if (N < 2)
    {
        acb_set_ui(theta2, 2 * (N > 0));
        acb_set_ui(theta3, N > 0);
        acb_set(theta4, theta3);
        return;
    }

    if (N < 25)
    {
        acb_t q1, q2, q4, q8, q16;

        acb_init(q1);
        acb_init(q2);
        acb_init(q4);
        acb_init(q8);
        acb_init(q16);

        acb_set_round(q1, q, prec);

        if (N > 2) acb_mul(q2, q1, q1, prec);
        if (N > 4) acb_mul(q4, q2, q2, prec);
        if (N > 9) acb_mul(q8, q4, q4, prec);
        if (N > 16) acb_mul(q16, q8, q8, prec);

        /* theta2 = 2 + 2q^2 + 2q^4 [2q^2 + 2q^8 + 2q^16] */
        if (N > 6)
        {
            if (N > 12)
            {
                acb_add(theta2, q2, q8, prec);
                if (N > 20)
                    acb_add(theta2, theta2, q16, prec);
                acb_mul(theta2, theta2, q4, prec);
            }
            else
            {
                acb_mul(theta2, q2, q4, prec);
            }
            acb_add(theta2, theta2, q2, prec);
            acb_add_ui(theta2, theta2, 1, prec);
        }
        else if (N > 2)
            acb_add_ui(theta2, q2, 1, prec);
        else
            acb_one(theta2);

        acb_mul_2exp_si(theta2, theta2, 1);

        /* theta3 = [1 + 2q^4 + 2q^16] + [2q + 2q^9] */
        /* theta4 = [1 + 2q^4 + 2q^16] - [2q + 2q^9] */
        if (N > 4)
        {
            if (N > 16)
                acb_add(q4, q4, q16, prec);
            acb_mul_2exp_si(q4, q4, 1);
            acb_add_ui(q4, q4, 1, prec);

            if (N > 9)
                acb_addmul(q1, q1, q8, prec);
            acb_mul_2exp_si(q1, q1, 1);

            acb_add(theta3, q4, q1, prec);
            acb_sub(theta4, q4, q1, prec);
        }
        else
        {
            acb_mul_2exp_si(q1, q1, 1);
            acb_add_ui(theta3, q1, 1, prec);
            acb_sub_ui(theta4, q1, 1, prec);
            acb_neg(theta4, theta4);
        }

        acb_clear(q1);
        acb_clear(q2);
        acb_clear(q4);
        acb_clear(q8);
        acb_clear(q16);

        return;
    }

    mag_init(qmag);
    acb_init(s1);
    acb_init(s2);
    acb_init(s3);
    acb_init(t1);
    acb_init(t2);

    tab = flint_calloc(N, sizeof(slong));
    qpow = _acb_vec_init(N);

    for (k = 0; k*(k+1) < N; k++) tab[k*(k+1)] = -1;
    for (k = 0; 4*k*k < N; k++) tab[4*k*k] = -1;
    for (k = 0; 4*k*(k+1) + 1 < N; k++) tab[4*k*(k+1)] = -1;
    if (N > 0) tab[0] = 0;
    if (N > 1) tab[1] = 1;

    acb_modular_fill_addseq(tab, N);

    acb_get_mag(qmag, q);
    log2q_approx = mag_get_log2_d_approx(qmag);

    for (k = 0; k < N; k++)
    {
        if (k == 0)
        {
            acb_one(qpow + k);
        }
        else if (k == 1)
        {
            acb_set_round(qpow + k, q, prec);
        }
        else if (tab[k] != 0)
        {
            log2term_approx = k * log2q_approx;
            term_prec = FLINT_MIN(FLINT_MAX(prec + log2term_approx + 16.0, 16.0), prec);
            acb_mul_approx(qpow + k, t1, t2, qpow + tab[k], qpow + k - tab[k], term_prec, prec);
        }
    }

    for (k = 0; k*(k+1) < N; k++) acb_add(s1, s1, qpow + k*(k+1), prec);
    for (k = 1; 4*k*k < N; k++) acb_add(s2, s2, qpow + 4*k*k, prec);
    for (k = 0; 4*k*(k+1) + 1 < N; k++) acb_add(s3, s3, qpow + 4*k*(k+1), prec);

    /*
    theta2 = 2 + 2q^2 + 2q^6 + 2q^12 + 2q^20 + 2q^30 + ...
    theta3 = 1 + 2 (q^4 + q^16 + ...) + 2q (1 + q^8 + q^24 + ...)
    theta4 = 1 + 2 (q^4 + q^16 + ...) - 2q (1 + q^8 + q^24 + ...)
    */
    acb_mul(s3, s3, q, prec);
    acb_mul_2exp_si(s3, s3, 1);
    acb_mul_2exp_si(s2, s2, 1);
    acb_add(theta3, s2, s3, prec);
    acb_sub(theta4, s2, s3, prec);
    acb_add_ui(theta3, theta3, 1, prec);
    acb_add_ui(theta4, theta4, 1, prec);
    acb_mul_2exp_si(theta2, s1, 1);
 
    _acb_vec_clear(qpow, N);
    flint_free(tab);

    acb_clear(s1);
    acb_clear(s2);
    acb_clear(s3);
    acb_clear(t1);
    acb_clear(t2);
    mag_clear(qmag);
}
Exemple #19
0
void
_fmpz_poly_mullow_KS(fmpz * res, const fmpz * poly1, long len1,
                                 const fmpz * poly2, long len2, long n)
{
    int neg1, neg2;
    long limbs1, limbs2, loglen;
    long bits1, bits2, bits;
    mp_limb_t *arr1, *arr2, *arr3;
    long sign = 0;

    FMPZ_VEC_NORM(poly1, len1);
    FMPZ_VEC_NORM(poly2, len2);

    if (!len1 | !len2)
    {
        _fmpz_vec_zero(res, n);
        return;
    }

    neg1 = (fmpz_sgn(poly1 + len1 - 1) > 0) ? 0 : -1;
    neg2 = (fmpz_sgn(poly2 + len2 - 1) > 0) ? 0 : -1;

    if (n > len1 + len2 - 1)
    {
       _fmpz_vec_zero(res + len1 + len2 - 1, n - (len1 + len2 - 1));
       n = len1 + len2 - 1;
    }

    bits1 = _fmpz_vec_max_bits(poly1, len1);
    if (bits1 < 0)
    {
        sign = 1;
        bits1 = -bits1;
    }

    if (poly1 != poly2)
    {
        bits2 = _fmpz_vec_max_bits(poly2, len2);
        if (bits2 < 0)
        {
            sign = 1;
            bits2 = -bits2;
        }
    }
    else
        bits2 = bits1;

    loglen = FLINT_BIT_COUNT(FLINT_MIN(len1, len2));
    bits = bits1 + bits2 + loglen + sign;

    limbs1 = (bits * len1 - 1) / FLINT_BITS + 1;
    limbs2 = (bits * len2 - 1) / FLINT_BITS + 1;

    if (poly1 == poly2)
    {
        arr1 = (mp_ptr) flint_calloc(limbs1, sizeof(mp_limb_t));
        arr2 = arr1;
        _fmpz_poly_bit_pack(arr1, poly1, len1, bits, neg1);
    }
    else
    {
        arr1 = (mp_ptr) flint_calloc(limbs1 + limbs2, sizeof(mp_limb_t));
        arr2 = arr1 + limbs1;
        _fmpz_poly_bit_pack(arr1, poly1, len1, bits, neg1);
        _fmpz_poly_bit_pack(arr2, poly2, len2, bits, neg2);
    }

    arr3 = (mp_ptr) flint_malloc((limbs1 + limbs2) * sizeof(mp_limb_t));

    if (limbs1 == limbs2)
        mpn_mul_n(arr3, arr1, arr2, limbs1);
    else if (limbs1 > limbs2)
        mpn_mul(arr3, arr1, limbs1, arr2, limbs2);
    else
        mpn_mul(arr3, arr2, limbs2, arr1, limbs1);
    
    if (sign)
        _fmpz_poly_bit_unpack(res, n, arr3, bits, neg1 ^ neg2);
    else
        _fmpz_poly_bit_unpack_unsigned(res, n, arr3, bits);

    flint_free(arr1);
    flint_free(arr3);
}
Exemple #20
0
int main(void)
{
    int i, j, n = 10000, result;
    flint_rand_t state;

    FILE *in, *out;
    int fd[2];
    pid_t childpid;

    printf("print/ read....");
    fflush(stdout);

    flint_randinit(state);

    /* Randomise n integers, write to and read from a pipe */
    {
        fmpz *a;

        a = flint_calloc(n, sizeof(fmpz));
        for (i = 0; i < n; i++)
            fmpz_randtest(a + i, state, 200);

        if (pipe(fd))
        {
            printf("FAIL:\n");
            printf("Failed to set-up the pipe.\n");
            abort();
        }

        if((childpid = fork()) == -1)
        {
            printf("FAIL:\n");
            printf("Failed to fork the process.\n");
            abort();
        }

        if(childpid == 0)  /* Child process */
        {
            int r;

            close(fd[0]);
            out = fdopen(fd[1], "w");
            if (out == NULL)
            {
                printf("FAIL:\n");
                printf("Could not open output file at the pipe.\n");
                abort();
            }

            for (j = 0; j < n; j++)
            {
                r = fmpz_fprint(out, a + j);
                if ((j < n - 1) && (r > 0))
                    r = fprintf(out, "\n");

                if (r <= 0)
                {
                    printf("FAIL:\n");
                    printf("Write error.\n");
                    abort();
                }
            }

            fclose(out);
            exit(0);
        }
        else  /* Parent process */
        {
            int r;
            fmpz_t t;

            close(fd[1]);
            in = fdopen(fd[0], "r");
            if (in == NULL)
            {
                printf("FAIL:\n");
                printf("Could not open input file at the pipe.\n");
                abort();
            }

            fmpz_init(t);

            i = 0;
            while (!feof(in))
            {
                r = fmpz_fread(in, t);
                if (r <= 0)
                {
                    printf("FAIL:\n");
                    printf("Read error.\n");
                    abort();
                }

                result = fmpz_equal(t, a + i);
                if (!result)
                {
                    printf("FAIL:\n");
                    printf("a[i] = "), fmpz_print(a + i), printf("\n");
                    printf("t    = "), fmpz_print(t), printf("\n");
                    abort();
                }

                ++i;
            }

            fmpz_clear(t);
            fclose(in);
        }

        if (i != n)
        {
            printf("FAIL:\n");
            printf("Only %d out of %d objects were processed.\n", i, n);
            abort();
        }

        for (i = 0; i < n; i++)
            fmpz_clear(a + i);
        flint_free(a);
    }

    /* Write bad data to a pipe and read it */
    {
        char str[5] = {'b', 'l', 'a', 'h', '\0'};

        if (pipe(fd))
        {
            printf("FAIL:\n");
            printf("Failed to set-up the pipe.\n");
            abort();
        }

        if((childpid = fork()) == -1)
        {
            printf("FAIL:\n");
            printf("Failed to fork the process.\n");
            abort();
        }

        if(childpid == 0)  /* Child process */
        {
            int r;

            close(fd[0]);
            out = fdopen(fd[1], "w");
            if (out == NULL)
            {
                printf("FAIL:\n");
                printf("Could not open output file at the pipe.\n");
                abort();
            }

            r = fprintf(out, "blah");
            if (r <= 0)
            {
                printf("FAIL:\n");
                printf("Write error.\n");
                abort();
            }

            fclose(out);
            exit(0);
        }
        else  /* Parent process */
        {
            int r;
            fmpz_t t;

            close(fd[1]);
            in = fdopen(fd[0], "r");
            if (in == NULL)
            {
                printf("FAIL:\n");
                printf("Could not open input file at the pipe.\n");
                abort();
            }

            fmpz_init(t);

            i = 0;
            while (!feof(in))
            {
                r = fmpz_fread(in, t);
                if (r > 0)
                {
                    printf("FAIL:\n");
                    printf("r = %d\n", r);
                    abort();
                }
                ++i;
            }

            fmpz_clear(t);
            fclose(in);
        }

        /* For {'b','l','a','h','\0'} we expect 5 reads */
        if (i != 5)
        {
            printf("FAIL:\n");
            printf("Carried out %d reads, but \"%s\" has only 4 characters.\n", i, str);
            abort();
        }
    }

    flint_randclear(state);
    _fmpz_cleanup();
    printf("PASS\n");
    return EXIT_SUCCESS;
}