Ejemplo n.º 1
0
int check_rref_form(slong * perm, nmod_mat_t A, slong rank)
{
    slong i, j, k, prev_pivot;

    /* bottom should be zero */
    for (i = rank; i < A->r; i++)
        for (j = 0; j < A->c; j++)
            if (nmod_mat_entry(A, i, j) != 0)
                return 0;

    prev_pivot = -1;

    for (i = 0; i < rank; i++)
    {
        for (j = 0; j < A->c; j++)
        {
            if (nmod_mat_entry(A, i, j) != 0)
            {
                /* pivot should have a higher column index than previous */
                if (j <= prev_pivot)
                    return 0;

                /* column should be 0 ... 0 1 0 ... 0 */
                for (k = 0; k < rank; k++)
                    if (nmod_mat_entry(A, k, j) != (i == k))
                        return 0;

                prev_pivot = j;
                break;
            }
        }
    }

    return 1;
}
Ejemplo n.º 2
0
void
nmod_mat_scalar_mul(nmod_mat_t B, const nmod_mat_t A, mp_limb_t c)
{
    if (c == 0UL)
    {
        nmod_mat_zero(B);
    }
    else if (c == 1UL)
    {
        nmod_mat_set(B, A);
    }
    else if (c == A->mod.n - 1UL)
    {
        nmod_mat_neg(B, A);
    }
    else
    {
        long i, j;

        for (i = 0; i < A->r; i++)
            for (j = 0; j < A->c; j++)
                nmod_mat_entry(B, i, j) = n_mulmod2_preinv(
                    nmod_mat_entry(A, i, j), c, A->mod.n, A->mod.ninv);
    }
}
Ejemplo n.º 3
0
void
nmod_mat_solve_tril_classical(nmod_mat_t X, const nmod_mat_t L,
                                                const nmod_mat_t B, int unit)
{
    int nlimbs;
    long i, j, n, m;
    nmod_t mod;
    mp_ptr inv, tmp;

    n = L->r;
    m = B->c;
    mod = L->mod;

    if (!unit)
    {
        inv = _nmod_vec_init(n);
        for (i = 0; i < n; i++)
            inv[i] = n_invmod(nmod_mat_entry(L, i, i), mod.n);
    }
    else
        inv = NULL;

    nlimbs = _nmod_vec_dot_bound_limbs(n, mod);
    tmp = _nmod_vec_init(n);

    for (i = 0; i < m; i++)
    {
        for (j = 0; j < n; j++)
            tmp[j] = nmod_mat_entry(X, j, i);

        for (j = 0; j < n; j++)
        {
            mp_limb_t s;
            s = _nmod_vec_dot(L->rows[j], tmp, j, mod, nlimbs);
            s = nmod_sub(nmod_mat_entry(B, j, i), s, mod);
            if (!unit)
                s = n_mulmod2_preinv(s, inv[j], mod.n, mod.ninv);
            tmp[j] = s;
        }

        for (j = 0; j < n; j++)
            nmod_mat_entry(X, j, i) = tmp[j];
    }

    _nmod_vec_clear(tmp);
    if (!unit)
        _nmod_vec_clear(inv);
}
Ejemplo n.º 4
0
void
fmpz_mat_CRT_ui(fmpz_mat_t res, const fmpz_mat_t mat1,
                        const fmpz_t m1, const nmod_mat_t mat2, int sign)
{
    long i, j;
    mp_limb_t c;
    mp_limb_t m2 = mat2->mod.n;
    mp_limb_t m2inv = mat2->mod.ninv;
    fmpz_t m1m2;

    c = fmpz_fdiv_ui(m1, m2);
    c = n_invmod(c, m2);

    if (c == 0)
    {
        printf("Exception in fmpz_mat_CRT_ui: m1 not invertible modulo m2!\n");
        abort();
    }

    fmpz_init(m1m2);
    fmpz_mul_ui(m1m2, m1, m2);

    for (i = 0; i < mat1->r; i++)
    {
        for (j = 0; j < mat1->c; j++)
            _fmpz_CRT_ui_precomp(fmpz_mat_entry(res, i, j),
                                 fmpz_mat_entry(mat1, i, j), m1,
                    nmod_mat_entry(mat2, i, j), m2, m2inv, m1m2, c, sign);
    }

    fmpz_clear(m1m2);
}
Ejemplo n.º 5
0
Archivo: det.c Proyecto: goens/flint2
mp_limb_t
_nmod_mat_det(nmod_mat_t A)
{
    mp_limb_t det;
    long * P;

    long m = A->r;
    long rank;
    long i;

    P = flint_malloc(sizeof(long) * m);
    rank = nmod_mat_lu(P, A, 1);

    det = 0UL;

    if (rank == m)
    {
        det = 1UL;
        for (i = 0; i < m; i++)
            det = n_mulmod2_preinv(det, nmod_mat_entry(A, i, i),
                A->mod.n, A->mod.ninv);
    }

    if (_perm_parity(P, m) == 1)
        det = nmod_neg(det, A->mod);

    flint_free(P);
    return det;
}
Ejemplo n.º 6
0
mp_limb_t
nmod_mat_trace(const nmod_mat_t mat)
{
    mp_limb_t t;
    slong i, n = nmod_mat_nrows(mat);

    if (n == 0)
        return 0;

    t = nmod_mat_entry(mat, 0, 0);

    for (i = 1; i < n; i++)
        t = nmod_add(t, nmod_mat_entry(mat, i, i), mat->mod);

    return t;
}
Ejemplo n.º 7
0
void
nmod_poly_mat_evaluate_nmod(nmod_mat_t B, const nmod_poly_mat_t A, mp_limb_t x)
{
    slong i, j;

    for (i = 0; i < A->r; i++)
        for (j = 0; j < A->c; j++)
            nmod_mat_entry(B, i, j) = nmod_poly_evaluate_nmod(
                nmod_poly_mat_entry(A, i, j), x);
}
Ejemplo n.º 8
0
void
fmpz_mat_scalar_addmul_nmod_mat_fmpz(fmpz_mat_t B,
                        const nmod_mat_t A, const fmpz_t c)
{
    long i, j;

    for (i = 0; i < A->r; i++)
        for (j = 0; j < A->c; j++)
            fmpz_addmul_ui(fmpz_mat_entry(B,i,j), c, nmod_mat_entry(A,i,j));
}
Ejemplo n.º 9
0
Archivo: inv.c Proyecto: goens/flint2
int nmod_mat_inv(nmod_mat_t B, const nmod_mat_t A)
{
    nmod_mat_t I;
    long i, dim;
    int result;

    dim = A->r;

    switch (dim)
    {
        case 0:
            result = 1;
            break;

        case 1:
            if (nmod_mat_entry(A, 0, 0) == 0UL)
            {
                result = 0;
            }
            else
            {
                nmod_mat_entry(B, 0, 0) = 
                    n_invmod(nmod_mat_entry(A, 0, 0), B->mod.n);
                result = 1;
            }
            break;

        default:
            nmod_mat_init(I, dim, dim, B->mod.n);
            for (i = 0; i < dim; i++)
                nmod_mat_entry(I, i, i) = 1UL;
            result = nmod_mat_solve(B, A, I);
            nmod_mat_clear(I);
    }

    return result;
}
Ejemplo n.º 10
0
Archivo: det.c Proyecto: goens/flint2
mp_limb_t
nmod_mat_det(const nmod_mat_t A)
{
    nmod_mat_t tmp;
    mp_limb_t det;
    long dim = A->r;

    if (dim != A->c)
    {
        printf("nmod_mat_det: nonsquare matrix");
        abort();
    }

    if (dim == 0) return 1UL;
    if (dim == 1) return nmod_mat_entry(A, 0, 0);

    nmod_mat_init_set(tmp, A);
    det = _nmod_mat_det(tmp);
    nmod_mat_clear(tmp);

    return det;
}
Ejemplo n.º 11
0
void
fmpz_mat_multi_CRT_ui_precomp(fmpz_mat_t mat,
    nmod_mat_t * const residues, long nres,
    fmpz_comb_t comb, fmpz_comb_temp_t temp, int sign)
{
    long i, j, k;
    mp_ptr r;

    r = _nmod_vec_init(nres);

    for (i = 0; i < fmpz_mat_nrows(mat); i++)
    {
        for (j = 0; j < fmpz_mat_ncols(mat); j++)
        {
            for (k = 0; k < nres; k++)
                r[k] = nmod_mat_entry(residues[k], i, j);
            fmpz_multi_CRT_ui(fmpz_mat_entry(mat, i, j), r, comb, temp, sign);
        }
    }

    _nmod_vec_clear(r);
}
Ejemplo n.º 12
0
int
nmod_mat_randpermdiag(nmod_mat_t mat, flint_rand_t state,
                            mp_srcptr diag, long n)
{
    int parity;
    long i;
    long * rows;
    long * cols;

    rows = _perm_init(mat->r);
    cols = _perm_init(mat->c);

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

    nmod_mat_zero(mat);
    for (i = 0; i < n; i++)
        nmod_mat_entry(mat, rows[i], cols[i]) = diag[i];

    _perm_clear(rows);
    _perm_clear(cols);

    return parity;
}
Ejemplo n.º 13
0
int
main(void)
{
    slong i;

    FLINT_TEST_INIT(state);

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

    for (i = 0; i < 1000 * flint_test_multiplier(); i++)
    {
        nmod_mat_t A, B, C, D;
        mp_limb_t mod;
        slong j, k, m, n, rank1, rank2;
        slong *perm;
        int equal;
        mp_limb_t c;

        mod = n_randtest_prime(state, 0);

        m = n_randint(state, 20);
        n = n_randint(state, 20);
        perm = _perm_init(2*m);

        nmod_mat_init(A, m, n, mod);
        nmod_mat_init(D, 2*m, n, mod);

        nmod_mat_randtest(A, state);
        nmod_mat_init_set(B, A);
        nmod_mat_init_set(C, A);

        rank1 = nmod_mat_rref(B);

        if (!check_rref_form(perm, B, rank1))
        {
            flint_printf("FAIL (malformed rref)\n");
            nmod_mat_print_pretty(A); flint_printf("\n\n");
            nmod_mat_print_pretty(B); flint_printf("\n\n");
            abort();
        }

        /* Concatenate the original matrix with the rref, scramble the rows,
           and check that the rref is the same */
        _perm_randtest(perm, 2 * m, state);

        for (j = 0; j < m; j++)
        {
            do { c = n_randint(state, mod); } while (c == 0);
            for (k = 0; k < n; k++)
                nmod_mat_entry(D, perm[j], k) =
                    nmod_mul(nmod_mat_entry(A, j, k), c, A->mod);
        }

        for (j = 0; j < m; j++)
        {
            do { c = n_randint(state, mod); } while (c == 0);
            for (k = 0; k < n; k++)
                nmod_mat_entry(D, perm[m + j], k) =
                    nmod_mul(nmod_mat_entry(B, j, k), c, A->mod);
        }

        rank2 = nmod_mat_rref(D);
        equal = (rank1 == rank2);

        if (equal)
        {
            for (j = 0; j < rank2; j++)
                for (k = 0; k < n; k++)
                    equal = equal && (nmod_mat_entry(B, j, k) ==
                                        nmod_mat_entry(D, j, k));
            for (j = rank2; j < 2 * rank2; j++)
                for (k = 0; k < n; k++)
                    equal = equal && (nmod_mat_entry(D, j, k) == 0);
        }

        if (!equal)
        {
            flint_printf("FAIL (rank1 = %wd, rank2 = %wd)!\n", rank1, rank2);
            nmod_mat_print_pretty(A); flint_printf("\n\n");
            nmod_mat_print_pretty(B); flint_printf("\n\n");
            nmod_mat_print_pretty(D); flint_printf("\n\n");
            abort();
        }

        _perm_clear(perm);
        nmod_mat_clear(A);
        nmod_mat_clear(B);
        nmod_mat_clear(C);
        nmod_mat_clear(D);
    }

    FLINT_TEST_CLEANUP(state);
    
    flint_printf("PASS\n");
    return 0;
}