Beispiel #1
0
void
fmpz_mat_mul_classical(fmpz_mat_t C, const fmpz_mat_t A, const fmpz_mat_t B)
{
    long ar, bc, br;
    long i, j, k;

    ar = A->r;
    br = B->r;
    bc = B->c;

    if (br == 0)
    {
        fmpz_mat_zero(C);
        return;
    }

    for (i = 0; i < ar; i++)
    {
        for (j = 0; j < bc; j++)
        {
            fmpz_mul(fmpz_mat_entry(C, i, j),
                     fmpz_mat_entry(A, i, 0),
                     fmpz_mat_entry(B, 0, j));

            for (k = 1; k < br; k++)
            {
                fmpz_addmul(fmpz_mat_entry(C, i, j),
                            fmpz_mat_entry(A, i, k),
                            fmpz_mat_entry(B, k, j));
            }
        }
    }
}
Beispiel #2
0
int
fmpz_mat_randpermdiag(fmpz_mat_t mat, flint_rand_t state,
                      const fmpz * diag, long n)
{
    int parity;
    long i;
    long * rows;
    long * cols;

    rows = malloc(sizeof(long) * mat->r);
    cols = malloc(sizeof(long) * mat->c);

    for (i = 0; i < mat->r; i++) rows[i] = i;
    for (i = 0; i < mat->c; i++) cols[i] = i;

    parity = shuffle(rows, state, mat->r);
    parity ^= shuffle(cols, state, mat->c);

    fmpz_mat_zero(mat);

    for (i = 0; i < n; i++)
        fmpz_set(&mat->rows[rows[i]][cols[i]], &diag[i]);

    free(rows);
    free(cols);

    return parity;
}
Beispiel #3
0
void
fmpz_mat_unit(fmpz_mat_t mat)
{
    long i;

    fmpz_mat_zero(mat);

    for (i = 0; i < FLINT_MIN(mat->r, mat->c); i++)
        fmpz_set_ui(mat->rows[i] + i, 1UL);
}
void
_brute_force_all_pairs_longest_walk(fmpz_mat_t B, const bool_mat_t A)
{
    slong i, j, n;

    n = bool_mat_nrows(A);

    /* set entries of B according to the longest observed walk */
    {
        slong k;
        bool_mat_t T;
        bool_mat_init(T, n, n);
        bool_mat_one(T);
        fmpz_mat_zero(B);
        for (k = 0; k < 2*n+1; k++)
        {
            for (i = 0; i < n; i++)
            {
                for (j = 0; j < n; j++)
                {
                    if (bool_mat_get_entry(T, i, j))
                    {
                        fmpz_set_si(fmpz_mat_entry(B, i, j), k);
                    }
                }
            }
            bool_mat_mul(T, T, A);
        }
        bool_mat_clear(T);
    }

    /* set special values 0, -1, -2 */
    {
        for (i = 0; i < n; i++)
        {
            for (j = 0; j < n; j++)
            {
                slong x;
                fmpz *p;
                p = fmpz_mat_entry(B, i, j);
                x = fmpz_get_si(p);
                if (x < 1)
                {
                    x = (i == j) ? 0 : -1;
                }
                else if (x > n-1)
                {
                    x = -2;
                }
                fmpz_set_si(p, x);
            }
        }
    }
}
Beispiel #5
0
int
main(void)
{
    long m, n, i, j, rep;
    flint_rand_t state;

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

    flint_randinit(state);

    for (rep = 0; rep < 1000; rep++)
    {
        fmpz_mat_t A;

        m = n_randint(state, 20);
        n = n_randint(state, 20);

        fmpz_mat_init(A, m, n);

        fmpz_mat_randtest(A, state, 100);
        fmpz_mat_zero(A);

        for (i = 0; i < m; i++)
        {
            for (j = 0; j < n; j++)
            {
                if (!fmpz_is_zero(fmpz_mat_entry(A,i,j)))
                {
                    printf("FAIL: nonzero entry\n");
                    abort();
                }
            }
        }

        fmpz_mat_clear(A);
    }

    flint_randclear(state);
    _fmpz_cleanup();
    printf("PASS\n");
    return 0;
}
Beispiel #6
0
slong
bool_mat_nilpotency_degree(const bool_mat_t A)
{
    slong n;

    if (!bool_mat_is_square(A))
    {
        flint_printf("bool_mat_nilpotency_degree: a square matrix is required!\n");
        abort();
    }

    if (bool_mat_is_empty(A))
        return 0;

    n = bool_mat_nrows(A);

    if (n == 1)
    {
        return bool_mat_get_entry(A, 0, 0) ? -1 : 1;
    }
    else
    {
        _toposort_s s;
        slong i;
        int has_cycle;
        int result;

        _toposort_init(&s, n);

        for (has_cycle = 0, i = 0; !has_cycle && i < n; i++)
            if (!s.v[i])
                has_cycle = _toposort_visit(&s, A, i);

        if (has_cycle)
        {
            result = -1;
        }
        else
        {
            /* Find the length of the longest path within the DAG */
            /* http://stackoverflow.com/a/10737524/4072759 */

            slong x, y, z;
            slong max_overall;
            fmpz_mat_t E;

            fmpz_mat_init(E, n, n);
            fmpz_mat_zero(E);
            max_overall = 0;
            for (i = n - 1; i >= 0; i--)
            {
                slong max_in = 0;
                y = s.post[i];
                for (x = 0; x < n; x++)
                {
                    max_in = FLINT_MAX(max_in,
                                       fmpz_get_si(fmpz_mat_entry(E, x, y)));
                }
                for (z = 0; z < n; z++)
                {
                    if (bool_mat_get_entry(A, y, z))
                    {
                        fmpz_set_si(fmpz_mat_entry(E, y, z), max_in + 1);
                        max_overall = FLINT_MAX(max_overall, max_in + 1);
                    }
                }
            }
            fmpz_mat_clear(E);
            result = max_overall + 1;
        }
        _toposort_clear(&s);
        return result;
    }
}
Beispiel #7
0
long
fmpz_mat_nullspace(fmpz_mat_t res, const fmpz_mat_t mat)
{
    long i, j, k, m, n, rank, nullity;
    long * pivots;
    long * nonpivots;
    fmpz_mat_t tmp;
    fmpz_t den;

    m = mat->r;
    n = mat->c;

    fmpz_mat_init_set(tmp, mat);
    fmpz_init(den);

    rank = fmpz_mat_rref(tmp, den, NULL, mat);
    nullity = n - rank;

    fmpz_mat_zero(res);
    if (rank == 0)
    {
        for (i = 0; i < nullity; i++)
            fmpz_one(res->rows[i] + i);
    }
    else if (nullity)
    {
        pivots = flint_malloc(rank * sizeof(long));
        nonpivots = flint_malloc(nullity * sizeof(long));

        for (i = j = k = 0; i < rank; i++)
        {
            while (fmpz_is_zero(tmp->rows[i] + j))
            {
                nonpivots[k] = j;
                k++;
                j++;
            }
            pivots[i] = j;
            j++;
        }
        while (k < nullity)
        {
            nonpivots[k] = j;
            k++;
            j++;
        }

        fmpz_set(den, tmp->rows[0] + pivots[0]);

        for (i = 0; i < nullity; i++)
        {
            for (j = 0; j < rank; j++)
                fmpz_set(res->rows[pivots[j]] + i, tmp->rows[j] + nonpivots[i]);
            fmpz_neg(res->rows[nonpivots[i]] + i, den);
        }

        flint_free(pivots);
        flint_free(nonpivots);
    }

    fmpz_clear(den);
    fmpz_mat_clear(tmp);

    return nullity;
}
Beispiel #8
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);
    }
}