Skip to content

Commit

Permalink
Merge pull request #1754 from flintlib/fmpz_mod2
Browse files Browse the repository at this point in the history
Have fmpz_mod_mat use a context object
  • Loading branch information
fredrik-johansson authored Jan 28, 2024
2 parents ab28e24 + 9c26b04 commit 9cb68f9
Show file tree
Hide file tree
Showing 123 changed files with 1,278 additions and 1,833 deletions.
108 changes: 55 additions & 53 deletions doc/source/fmpz_mod_mat.rst

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion doc/source/fq_default_mat.rst
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ Random matrix generation
The matrix can be transformed into a dense matrix with unchanged
rank by subsequently calling :func:`fq_default_mat_randops`.

.. function:: void fq_default_mat_randops(fq_default_mat_t mat, slong count, flint_rand_t state, const fq_default_ctx_t ctx)
.. function:: void fq_default_mat_randops(fq_default_mat_t mat, flint_rand_t state, slong count, const fq_default_ctx_t ctx)

Randomises ``mat`` by performing elementary row or column
operations. More precisely, at most ``count`` random additions
Expand Down
2 changes: 1 addition & 1 deletion doc/source/fq_mat.rst
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ Random matrix generation
The matrix can be transformed into a dense matrix with unchanged
rank by subsequently calling :func:`fq_mat_randops`.

.. function:: void fq_mat_randops(fq_mat_t mat, slong count, flint_rand_t state, const fq_ctx_t ctx)
.. function:: void fq_mat_randops(fq_mat_t mat, flint_rand_t state, slong count, const fq_ctx_t ctx)

Randomises ``mat`` by performing elementary row or column
operations. More precisely, at most ``count`` random additions
Expand Down
2 changes: 1 addition & 1 deletion doc/source/fq_nmod_mat.rst
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ Random matrix generation
The matrix can be transformed into a dense matrix with unchanged
rank by subsequently calling :func:`fq_nmod_mat_randops`.

.. function:: void fq_nmod_mat_randops(fq_nmod_mat_t mat, slong count, flint_rand_t state, const fq_nmod_ctx_t ctx)
.. function:: void fq_nmod_mat_randops(fq_nmod_mat_t mat, flint_rand_t state, slong count, const fq_nmod_ctx_t ctx)

Randomises ``mat`` by performing elementary row or column
operations. More precisely, at most ``count`` random additions
Expand Down
2 changes: 1 addition & 1 deletion doc/source/fq_zech_mat.rst
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ Random matrix generation
The matrix can be transformed into a dense matrix with unchanged
rank by subsequently calling :func:`fq_zech_mat_randops`.

.. function:: void fq_zech_mat_randops(fq_zech_mat_t mat, slong count, flint_rand_t state, const fq_zech_ctx_t ctx)
.. function:: void fq_zech_mat_randops(fq_zech_mat_t mat, flint_rand_t state, slong count, const fq_zech_ctx_t ctx)

Randomises ``mat`` by performing elementary row or column
operations. More precisely, at most ``count`` random additions
Expand Down
2 changes: 1 addition & 1 deletion doc/source/nmod_mat.rst
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ Random matrix generation
The matrix can be transformed into a dense matrix with unchanged
rank by subsequently calling :func:`nmod_mat_randops`.

.. function:: void nmod_mat_randops(nmod_mat_t mat, slong count, flint_rand_t state)
.. function:: void nmod_mat_randops(nmod_mat_t mat, flint_rand_t state, slong count)

Randomises ``mat`` by performing elementary row or column
operations. More precisely, at most ``count`` random additions
Expand Down
204 changes: 88 additions & 116 deletions src/fmpz_mod_mat.h

Large diffs are not rendered by default.

13 changes: 10 additions & 3 deletions src/fmpz_mod_mat/add.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
Copyright (C) 2017 Luca De Feo
Copyright (C) 2024 Fredrik Johansson
This file is part of FLINT.
Expand All @@ -9,10 +10,16 @@
(at your option) any later version. See <https://www.gnu.org/licenses/>.
*/

#include "fmpz_mod_vec.h"
#include "fmpz_mod_mat.h"

void fmpz_mod_mat_add(fmpz_mod_mat_t C, const fmpz_mod_mat_t A, const fmpz_mod_mat_t B)
void fmpz_mod_mat_add(fmpz_mod_mat_t C, const fmpz_mod_mat_t A, const fmpz_mod_mat_t B, const fmpz_mod_ctx_t ctx)
{
fmpz_mat_add(C->mat, A->mat, B->mat);
_fmpz_mod_mat_reduce(C);
slong i;
slong r = fmpz_mod_mat_nrows(A, ctx);
slong c = fmpz_mod_mat_ncols(A, ctx);

if (c != 0)
for (i = 0; i < r; i++)
_fmpz_mod_vec_add(C->rows[i], A->rows[i], B->rows[i], c, ctx);
}
95 changes: 47 additions & 48 deletions src/fmpz_mod_mat/can_solve.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Copyright (C) 2018 Tommy Hofmann
Copyright (C) 2020 William Hart
Copyright (C) 2021 Daniel Schultz
Copyright (C) 2024 Fredrik Johansson
This file is part of FLINT.
Expand All @@ -16,43 +17,41 @@
#include "fmpz_mod_mat.h"

int fmpz_mod_mat_can_solve(fmpz_mod_mat_t X, const fmpz_mod_mat_t A,
const fmpz_mod_mat_t B)
const fmpz_mod_mat_t B, const fmpz_mod_ctx_t ctx)
{
slong i, j, k, col, *pivots, rank, *perm;
fmpz_mod_mat_t LU, LU2, PB;
int result = 1;

if (A->mat->r != B->mat->r || A->mat->c != X->mat->r || X->mat->c != B->mat->c)
if (A->r != B->r || A->c != X->r || X->c != B->c)
{
return 0;
}

if (A->mat->r == 0 || B->mat->c == 0)
if (A->r == 0 || B->c == 0)
{
fmpz_mod_mat_zero(X);

fmpz_mod_mat_zero(X, ctx);
return 1;
}

if (A->mat->c == 0)
if (A->c == 0)
{
fmpz_mod_mat_zero(X);

return fmpz_mod_mat_is_zero(B);
fmpz_mod_mat_zero(X, ctx);
return fmpz_mod_mat_is_zero(B, ctx);
}

fmpz_mod_mat_init_set(LU, A);
perm = flint_malloc(sizeof(slong) * A->mat->r);
for (i = 0; i < A->mat->r; i++)
fmpz_mod_mat_init_set(LU, A, ctx);
perm = flint_malloc(sizeof(slong) * A->r);
for (i = 0; i < A->r; i++)
perm[i] = i;

rank = fmpz_mod_mat_lu(perm, LU, 0);
rank = fmpz_mod_mat_lu(perm, LU, 0, ctx);

fmpz_mod_mat_window_init(PB, B, 0, 0, B->mat->r, B->mat->c);
for (i = 0; i < B->mat->r; i++)
PB->mat->rows[i] = B->mat->rows[perm[i]];
fmpz_mod_mat_window_init(PB, B, 0, 0, B->r, B->c, ctx);
for (i = 0; i < B->r; i++)
PB->rows[i] = B->rows[perm[i]];

fmpz_mod_mat_init(LU2, rank, rank, A->mod);
fmpz_mod_mat_init(LU2, rank, rank, ctx);

pivots = flint_malloc(sizeof(slong)*rank);

Expand All @@ -65,77 +64,77 @@ int fmpz_mod_mat_can_solve(fmpz_mod_mat_t X, const fmpz_mod_mat_t A,
pivots[i] = col;

for (j = 0; j < rank; j++)
fmpz_mod_mat_set_entry(LU2, j, i, fmpz_mod_mat_entry(LU, j, col));
fmpz_mod_mat_set_entry(LU2, j, i, fmpz_mod_mat_entry(LU, j, col), ctx);

col++;
}

X->mat->r = rank;
PB->mat->r = rank;
LU->mat->r = rank;
fmpz_mod_mat_solve_tril(X, LU, PB, 1);
LU->mat->r = A->mat->r;
X->r = rank;
PB->r = rank;
LU->r = rank;
fmpz_mod_mat_solve_tril(X, LU, PB, 1, ctx);
LU->r = A->r;

if (A->mat->r > rank)
if (A->r > rank)
{
fmpz_mod_mat_t P;

LU->mat->rows += rank;
LU->mat->r = A->mat->r - rank;
X->mat->r = LU->mat->c;
LU->rows += rank;
LU->r = A->r - rank;
X->r = LU->c;

fmpz_mod_mat_init(P, LU->mat->r, B->mat->c, A->mod);
fmpz_mod_mat_init(P, LU->r, B->c, ctx);

fmpz_mod_mat_mul(P, LU, X);
fmpz_mod_mat_mul(P, LU, X, ctx);

PB->mat->r = LU->mat->r;
PB->mat->rows += rank;
PB->r = LU->r;
PB->rows += rank;

result = fmpz_mod_mat_equal(P, PB);
result = fmpz_mod_mat_equal(P, PB, ctx);

PB->mat->rows -= rank;
fmpz_mod_mat_clear(P);
PB->rows -= rank;
fmpz_mod_mat_clear(P, ctx);

LU->mat->rows -= rank;
LU->rows -= rank;

if (!result)
{
X->mat->r = A->mat->c;
fmpz_mod_mat_zero(X);
X->r = A->c;
fmpz_mod_mat_zero(X, ctx);
goto cleanup;
}
}

fmpz_mod_mat_solve_triu(X, LU2, X, 0);
fmpz_mod_mat_solve_triu(X, LU2, X, 0, ctx);

X->mat->r = A->mat->c;
X->r = A->c;

k = rank - 1;
for (i = A->mat->c - 1; i >= 0; i--)
for (i = A->c - 1; i >= 0; i--)
{
if (k < 0 || i != pivots[k])
{
for (j = 0; j < B->mat->c; j++)
for (j = 0; j < B->c; j++)
fmpz_zero(fmpz_mod_mat_entry(X, i, j));
}
else
{
for (j = 0; j < B->mat->c; j++)
fmpz_mod_mat_set_entry(X, i, j, fmpz_mod_mat_entry(X, k, j));
for (j = 0; j < B->c; j++)
fmpz_mod_mat_set_entry(X, i, j, fmpz_mod_mat_entry(X, k, j), ctx);

k--;
}
}

cleanup:

fmpz_mod_mat_clear(LU2);
fmpz_mod_mat_clear(LU2, ctx);

PB->mat->r = B->mat->r;
fmpz_mod_mat_window_clear(PB);
PB->r = B->r;
fmpz_mod_mat_window_clear(PB, ctx);

LU->mat->r = A->mat->r;
fmpz_mod_mat_clear(LU);
LU->r = A->r;
fmpz_mod_mat_clear(LU, ctx);
flint_free(perm);

flint_free(pivots);
Expand Down
6 changes: 3 additions & 3 deletions src/fmpz_mod_mat/charpoly_berkowitz.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ void _fmpz_mod_mat_charpoly_berkowitz(fmpz* cp, const fmpz_mod_mat_t mat,
void fmpz_mod_mat_charpoly_berkowitz(fmpz_mod_poly_t cp,
const fmpz_mod_mat_t mat, const fmpz_mod_ctx_t ctx)
{
if (!fmpz_mod_mat_is_square(mat))
if (!fmpz_mod_mat_is_square(mat, ctx))
{
flint_throw(FLINT_ERROR, "Exception (fmpz_mod_mat_charpoly_berkowitz). Non-square matrix.\n");
}

fmpz_mod_poly_fit_length(cp, fmpz_mod_mat_nrows(mat) + 1, ctx);
fmpz_mod_poly_fit_length(cp, fmpz_mod_mat_nrows(mat, ctx) + 1, ctx);
_fmpz_mod_mat_charpoly_berkowitz(cp->coeffs, mat, ctx);
_fmpz_mod_poly_set_length(cp, fmpz_mod_mat_nrows(mat) + 1);
_fmpz_mod_poly_set_length(cp, fmpz_mod_mat_nrows(mat, ctx) + 1);
_fmpz_mod_poly_normalise(cp);
}
5 changes: 2 additions & 3 deletions src/fmpz_mod_mat/clear.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@
#include "fmpz.h"
#include "fmpz_mod_mat.h"

void fmpz_mod_mat_clear(fmpz_mod_mat_t mat)
void fmpz_mod_mat_clear(fmpz_mod_mat_t mat, const fmpz_mod_ctx_t ctx)
{
fmpz_mat_clear(mat->mat);
fmpz_clear(mat->mod);
fmpz_mat_clear(mat);
}
12 changes: 6 additions & 6 deletions src/fmpz_mod_mat/comparison.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@
#include "fmpz.h"
#include "fmpz_mod_mat.h"

int fmpz_mod_mat_equal(const fmpz_mod_mat_t mat1, const fmpz_mod_mat_t mat2)
int fmpz_mod_mat_equal(const fmpz_mod_mat_t mat1, const fmpz_mod_mat_t mat2, const fmpz_mod_ctx_t ctx)
{
return fmpz_equal(mat1->mod, mat2->mod) && fmpz_mat_equal(mat1->mat, mat2->mat);
return fmpz_mat_equal(mat1, mat2);
}

int fmpz_mod_mat_is_zero(const fmpz_mod_mat_t mat)
int fmpz_mod_mat_is_zero(const fmpz_mod_mat_t mat, const fmpz_mod_ctx_t ctx)
{
return fmpz_mat_is_zero(mat->mat);
return fmpz_mat_is_zero(mat);
}

int fmpz_mod_mat_is_one(const fmpz_mod_mat_t mat)
int fmpz_mod_mat_is_one(const fmpz_mod_mat_t mat, const fmpz_mod_ctx_t ctx)
{
return fmpz_is_one(mat->mod) || fmpz_mat_is_one(mat->mat);
return fmpz_is_one(ctx->n) || fmpz_mat_is_one(mat);
}
9 changes: 4 additions & 5 deletions src/fmpz_mod_mat/fmpz_vec_mul.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,12 @@
*/

#include "fmpz.h"
#include "fmpz_mod_vec.h"
#include "fmpz_mod_mat.h"

void fmpz_mod_mat_fmpz_vec_mul(fmpz * c, const fmpz * a, slong alen,
const fmpz_mod_mat_t B)
const fmpz_mod_mat_t B, const fmpz_mod_ctx_t ctx)
{
slong i;
fmpz_mat_fmpz_vec_mul(c, a, alen, B->mat);
for (i = fmpz_mod_mat_ncols(B) - 1; i >= 0; i--)
fmpz_mod(c + i, c + i, B->mod);
fmpz_mat_fmpz_vec_mul(c, a, alen, B);
_fmpz_mod_vec_set_fmpz_vec(c, c, fmpz_mod_mat_ncols(B, ctx), ctx);
}
9 changes: 5 additions & 4 deletions src/fmpz_mod_mat/fmpz_vec_mul_ptr.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@
*/

#include "fmpz.h"
#include "fmpz_mod.h"
#include "fmpz_mod_mat.h"

void fmpz_mod_mat_fmpz_vec_mul_ptr(fmpz * const * c,
const fmpz * const * a, slong alen, const fmpz_mod_mat_t B)
const fmpz * const * a, slong alen, const fmpz_mod_mat_t B, const fmpz_mod_ctx_t ctx)
{
slong i;
fmpz_mat_fmpz_vec_mul_ptr(c, a, alen, B->mat);
for (i = fmpz_mod_mat_ncols(B) - 1; i >= 0; i--)
fmpz_mod(c[i], c[i], B->mod);
fmpz_mat_fmpz_vec_mul_ptr(c, a, alen, B);
for (i = 0; i < fmpz_mod_mat_ncols(B, ctx); i++)
fmpz_mod_set_fmpz(c[i], c[i], ctx);
}
4 changes: 2 additions & 2 deletions src/fmpz_mod_mat/howell_form.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

#include "fmpz_mod_mat.h"

slong fmpz_mod_mat_howell_form(fmpz_mod_mat_t mat)
slong fmpz_mod_mat_howell_form(fmpz_mod_mat_t mat, const fmpz_mod_ctx_t ctx)
{
return fmpz_mat_howell_form_mod(mat->mat, mat->mod);
return fmpz_mat_howell_form_mod(mat, ctx->n);
}
6 changes: 2 additions & 4 deletions src/fmpz_mod_mat/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@
#include "fmpz.h"
#include "fmpz_mod_mat.h"

void fmpz_mod_mat_init(fmpz_mod_mat_t mat, slong rows, slong cols, const fmpz_t n)
void fmpz_mod_mat_init(fmpz_mod_mat_t mat, slong rows, slong cols, const fmpz_mod_ctx_t ctx)
{
fmpz_mat_init(mat->mat, rows, cols);
fmpz_init(mat->mod);
_fmpz_mod_mat_set_mod(mat, n);
fmpz_mat_init(mat, rows, cols);
}
5 changes: 2 additions & 3 deletions src/fmpz_mod_mat/init_set.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@
#include "fmpz.h"
#include "fmpz_mod_mat.h"

void fmpz_mod_mat_init_set(fmpz_mod_mat_t mat, const fmpz_mod_mat_t src)
void fmpz_mod_mat_init_set(fmpz_mod_mat_t mat, const fmpz_mod_mat_t src, const fmpz_mod_ctx_t ctx)
{
fmpz_mat_init_set(mat->mat, src->mat);
fmpz_init_set(mat->mod, src->mod);
fmpz_mat_init_set(mat, src);
}
Loading

0 comments on commit 9cb68f9

Please sign in to comment.