Пример #1
0
Файл: lcm.c Проект: goens/flint2
void
_fmpz_vec_lcm(fmpz_t res, const fmpz * vec, long len)
{
    long i;

    fmpz_one(res);
    for (i = 0; i < len && !fmpz_is_zero(res); i++)
        fmpz_lcm(res, res, vec + i);

    fmpz_abs(res, res);
}
Пример #2
0
void
_fmpq_mat_get_fmpz_mat_rowwise(fmpz_mat_struct ** num, fmpz * den,
                        const fmpq_mat_struct ** mat, slong n)
{
    fmpz_t t, lcm;
    slong i, j, k;

    if (fmpq_mat_is_empty(mat[0]))
        return;

    fmpz_init(t);
    fmpz_init(lcm);

    for (i = 0; i < mat[0]->r; i++)
    {
        /* Compute common denominator of row */
        fmpz_set(lcm, fmpq_mat_entry_den(mat[0], i, 0));

        for (k = 0; k < n; k++)
            for (j = (k == 0); j < mat[k]->c; j++)
                fmpz_lcm(lcm, lcm, fmpq_mat_entry_den(mat[k], i, j));

        if (den != NULL)
            fmpz_set(den + i, lcm);

        for (k = 0; k < n; k++)
        {
            /* Rescale numerators in row */
            if (fmpz_is_one(lcm))
            {
                for (j = 0; j < mat[k]->c; j++)
                    fmpz_set(fmpz_mat_entry(num[k], i, j),
                             fmpq_mat_entry_num(mat[k], i, j));
            }
            else
            {
                for (j = 0; j < mat[k]->c; j++)
                {
                    fmpz_divexact(t, lcm, fmpq_mat_entry_den(mat[k], i, j));
                    fmpz_mul(fmpz_mat_entry(num[k], i, j),
                             fmpq_mat_entry_num(mat[k], i, j), t);
                }
            }
        }
    }

    fmpz_clear(t);
    fmpz_clear(lcm);
}
static void
_set_vec(fmpz * rnum, fmpz_t den,
                const fmpz * xnum, const fmpz * xden, slong len)
{
    slong j;
    fmpz_t t;
    fmpz_init(t);
    fmpz_one(den);

    for (j = 0; j < len; j++)
        fmpz_lcm(den, den, xden + j);

    for (j = 0; j < len; j++)
    {
        fmpz_divexact(t, den, xden + j);
        fmpz_mul(rnum + j, xnum + j, t);
    }

    fmpz_clear(t);
}
Пример #4
0
void
fmpz_holonomic_get_nth_fmpq(fmpq_t res, const fmpz_holonomic_t op, const fmpq * initial, long n0, long n)
{
    long r = fmpz_holonomic_order(op);

    if (r == 0)
    {
        fmpq_zero(res);
        return;
    }
    else if (n < n0)
    {
        printf("not implemented\n");
        abort();
    }
    else if (n - n0 < r)
    {
        fmpq_set(res, initial + n - n0);
        return;
    }
    else
    {
        fmpz_mat_t M;
        long i;
        fmpz_t Q;
        fmpz_mat_init(M, r, r);
        fmpz_init(Q);

        fmpz_holonomic_forward_fmpz_mat(M, Q, op, n0, n - n0 - r + 1);

        {
            fmpz_t g, t;
            fmpz_init(g);
            fmpz_init(t);

            fmpz_one(g);
            for (i = 0; i < r; i++)
                fmpz_lcm(g, g, fmpq_denref(initial + i));

            fmpz_divexact(t, g, fmpq_denref(initial + 0));
            fmpz_mul(t, t, fmpq_numref(initial + 0));
            fmpz_mul(fmpz_mat_entry(M, r - 1, 0), fmpz_mat_entry(M, r - 1, 0), t);

            for (i = 1; i < r; i++)
            {
                fmpz_divexact(t, g, fmpq_denref(initial + i));
                fmpz_mul(t, t, fmpq_numref(initial + i));
                fmpz_addmul(fmpz_mat_entry(M, r - 1, 0), fmpz_mat_entry(M, r - 1, i), t);
            }

            fmpz_set(fmpq_numref(res), fmpz_mat_entry(M, r - 1, 0));
            fmpz_mul(fmpq_denref(res), Q, g);
            fmpq_canonicalise(res);

            fmpz_clear(g);
            fmpz_clear(t);
        }

        fmpz_mat_clear(M);
        fmpz_clear(Q);
    }
}
Пример #5
0
void nf_elem_rep_mat_fmpz_mat_den(fmpz_mat_t res, fmpz_t den, const nf_elem_t a, const nf_t nf)
{
    if (nf->flag & NF_LINEAR)
    {
        fmpz_set(fmpz_mat_entry(res, 0, 0), LNF_ELEM_NUMREF(a));
        fmpz_set(den, LNF_ELEM_DENREF(a));
    }
    else if (nf->flag & NF_QUADRATIC)
    {
        nf_elem_t t;
        const fmpz * const anum = QNF_ELEM_NUMREF(a);
        const fmpz * const aden = QNF_ELEM_DENREF(a);
        fmpz * const tnum = QNF_ELEM_NUMREF(t);
        fmpz * const tden = QNF_ELEM_DENREF(t);

        nf_elem_init(t, nf);
        nf_elem_mul_gen(t, a, nf);

        if (fmpz_equal(tden, aden))
        {
            fmpz_set(fmpz_mat_entry(res, 0, 0), anum);
            fmpz_set(fmpz_mat_entry(res, 0, 1), anum + 1);
            fmpz_set(fmpz_mat_entry(res, 1, 0), tnum);
            fmpz_set(fmpz_mat_entry(res, 1, 1), tnum + 1);

            fmpz_set(den, tden);
        }
        else
        {
            fmpz_lcm(den, tden, aden);
            fmpz_divexact(fmpz_mat_entry(res, 0, 0), den, aden);
            fmpz_mul(fmpz_mat_entry(res, 0, 1), anum + 1, fmpz_mat_entry(res, 0, 0));
            fmpz_mul(fmpz_mat_entry(res, 0, 0), anum, fmpz_mat_entry(res, 0, 0));

            fmpz_divexact(fmpz_mat_entry(res, 1, 0), den, tden);
            fmpz_mul(fmpz_mat_entry(res, 1, 1), tnum + 1, fmpz_mat_entry(res, 1, 0));
            fmpz_mul(fmpz_mat_entry(res, 1, 0), tnum, fmpz_mat_entry(res, 1, 0));
        }
        nf_elem_clear(t, nf);
    }
    else
    {
        slong i, j;
        nf_elem_t t;
        slong d = fmpq_poly_degree(nf->pol);

        nf_elem_init(t, nf);
        nf_elem_set(t, a, nf);

        if (NF_ELEM(a)->length == 0)
        {
            fmpz_mat_zero(res);
            fmpz_one(den);
        }
        else if (NF_ELEM(a)->length == 1)
        {
            fmpz_mat_zero(res);
            for (i = 0; i <= d - 1; i++)
            {
              fmpz_set(fmpz_mat_entry(res, i, i), fmpq_poly_numref(NF_ELEM(a)));
            }
            fmpz_set(den, fmpq_poly_denref(NF_ELEM(a)));
        }
        else
        {
            /* Special case if defining polynomial is monic and integral and the element also has trivial denominator */
            if (nf->flag & NF_MONIC && fmpz_is_one(fmpq_poly_denref(nf->pol)) && fmpz_is_one(fmpq_poly_denref(NF_ELEM(a))))
            {
                fmpz_one(den);

                for (i = 0; i <= NF_ELEM(a)->length - 1; i++)
                    fmpz_set(fmpz_mat_entry(res, 0, i), fmpq_poly_numref(NF_ELEM(a)) + i);

                for (i = NF_ELEM(a)->length; i <= d - 1; i++)
                    fmpz_zero(fmpz_mat_entry(res, 0, i));

                for (j = 1; j <= d - NF_ELEM(a)->length; j++)
                {
                    nf_elem_mul_gen(t, t, nf);
                    for (i = 0; i < j; i++)
                        fmpz_zero(fmpz_mat_entry(res, j, i));

                    for (i = 0; i <= NF_ELEM(a)->length - 1; i++)
                        fmpz_set(fmpz_mat_entry(res, j, j + i), fmpq_poly_numref(NF_ELEM(a)) + i);

                    for (i = j + NF_ELEM(a)->length; i <= d - 1; i++)
                        fmpz_zero(fmpz_mat_entry(res, j, i));
                }

                for (j = d - NF_ELEM(a)->length + 1; j <= d - 1; j++)
                {
                    nf_elem_mul_gen(t, t, nf);
                    for (i = 0; i <= d - 1; i++)
                        fmpz_set(fmpz_mat_entry(res, j, i), fmpq_poly_numref(NF_ELEM(t)) + i);
                }
            }
            else
            {
                /* Now the general case. For 0 <= j < d - 2 we store the
                 * denominator for row j at res[d - 1, j]. At the end we
                 * divide the lcm of all of them by the corresponding
                 * denominator of the row to get the correct multiplier for
                 * row.
                 */

                for (i = 0; i <= NF_ELEM(a)->length - 1; i++)
                    fmpz_set(fmpz_mat_entry(res, 0, i), fmpq_poly_numref(NF_ELEM(a)) + i);

                for (i = NF_ELEM(a)->length; i <= d - 1; i++)
                    fmpz_zero(fmpz_mat_entry(res, 0, i));

                fmpz_set(fmpz_mat_entry(res, d - 1, 0), fmpq_poly_denref(NF_ELEM(a)));

                for (j = 1; j <= d - NF_ELEM(a)->length; j++)
                {
                    nf_elem_mul_gen(t, t, nf);
                    for (i = 0; i < j; i++)
                        fmpz_zero(fmpz_mat_entry(res, j, i));

                    for (i = 0; i <= NF_ELEM(a)->length - 1; i++)
                        fmpz_set(fmpz_mat_entry(res, j, j + i), fmpq_poly_numref(NF_ELEM(a)) + i);

                    for (i = j + NF_ELEM(a)->length; i <= d - 1; i++)
                        fmpz_zero(fmpz_mat_entry(res, j, i));

                    fmpz_set(fmpz_mat_entry(res, d - 1, j), fmpq_poly_denref(NF_ELEM(a)));
                }

                for (j = d - NF_ELEM(a)->length + 1; j <= d - 2; j++)
                {
                    nf_elem_mul_gen(t, t, nf);
                    for (i = 0; i <= d - 1; i++)
                        fmpz_set(fmpz_mat_entry(res, j, i), fmpq_poly_numref(NF_ELEM(t)) + i);

                    fmpz_set(fmpz_mat_entry(res, d - 1, j), fmpq_poly_denref(NF_ELEM(t)));

                }

                nf_elem_mul_gen(t, t, nf);
                /* Now compute the correct denominator */

                fmpz_set(fmpz_mat_entry(res, d - 1, d - 1), fmpq_poly_denref(NF_ELEM(t)));

                fmpz_set(den, fmpq_poly_denref(NF_ELEM(t)));

                for (j = 0; j <= d - 2; j++)
                    fmpz_lcm(den, den, fmpz_mat_entry(res, d - 1, j));

                for (j = 0; j <= d - 2; j++)
                {
                    if (!fmpz_equal(den, fmpz_mat_entry(res, d - 1, j)))
                    {
                        fmpz_divexact(fmpz_mat_entry(res, d - 1, j), den, fmpz_mat_entry(res, d - 1, j));

                        for (i = 0; i <= d - 1; i++)
                            fmpz_mul(fmpz_mat_entry(res, j, i), fmpz_mat_entry(res, j, i), fmpz_mat_entry(res, d - 1, j));
                    }
                }

                if (fmpz_equal(den, fmpz_mat_entry(res, d - 1, d - 1)))
                {
                    for (i = 0; i < d; i++)
                        fmpz_set(fmpz_mat_entry(res, d - 1, i), fmpq_poly_numref(NF_ELEM(t)) + i);
                }
                else
                {
                    fmpz_divexact(fmpz_mat_entry(res, d - 1, d - 1), den, fmpq_poly_denref(NF_ELEM(t)));
                    for (i = 0; i < d; i++)
                        fmpz_mul(fmpz_mat_entry(res, d - 1, i), fmpq_poly_numref(NF_ELEM(t)) + i, fmpz_mat_entry(res, d - 1, d - 1));
                }
            }
        }
        nf_elem_clear(t, nf);
    }
}