diff --git a/doc/source/nmod_poly.rst b/doc/source/nmod_poly.rst
index 2bb50ab4d2..94f4d05a8a 100644
--- a/doc/source/nmod_poly.rst
+++ b/doc/source/nmod_poly.rst
@@ -199,9 +199,9 @@ Assignment and basic manipulation
If ``len`` is greater than the current length of ``poly``,
then nothing happens.
-.. function:: void nmod_poly_set_trunc(nmod_poly_t res, const nmod_poly_t poly, slong n)
+.. function:: void nmod_poly_set_trunc(nmod_poly_t res, const nmod_poly_t poly, slong len)
- Notionally truncate ``poly`` to length `n` and set ``res`` to the
+ Notionally truncate ``poly`` to length ``len`` and set ``res`` to the
result. The result is normalised.
.. function:: void _nmod_poly_reverse(mp_ptr output, mp_srcptr input, slong len, slong m)
@@ -399,6 +399,17 @@ Comparison
Returns `1` if the polynomials are equal, otherwise `0`.
+.. function:: int nmod_poly_equal_nmod(const nmod_poly_t poly, ulong cst)
+
+ Returns `1` if the polynomial ``poly`` is constant, equal to ``cst``.
+ ``cst`` is assumed to be already reduced, i.e. less than the modulus of
+ ``poly``.
+
+.. function:: int nmod_poly_equal_ui(const nmod_poly_t poly, ulong cst)
+
+ Returns `1` if the polynomial ``poly`` is constant, equal to ``cst`` up to
+ reduction modulo the modulus of ``poly``.
+
.. function:: int nmod_poly_equal_trunc(const nmod_poly_t poly1, const nmod_poly_t poly2, slong n)
Notionally truncate ``poly1`` and ``poly2`` to length `n` and return
@@ -444,7 +455,7 @@ Shifting
.. function:: void nmod_poly_shift_right(nmod_poly_t res, const nmod_poly_t poly, slong k)
Sets ``res`` to ``poly`` shifted right by ``k`` coefficients,
- i.e.\ divide by `x^k` and throws away the remainder. If ``k`` is
+ i.e. divide by `x^k` and throw away the remainder. If ``k`` is
greater than or equal to the length of ``poly``, the result is the
zero polynomial.
diff --git a/doc/source/nmod_poly_mat.rst b/doc/source/nmod_poly_mat.rst
index c5dc25053a..c6497311c2 100644
--- a/doc/source/nmod_poly_mat.rst
+++ b/doc/source/nmod_poly_mat.rst
@@ -51,6 +51,30 @@ Memory management
Frees all memory associated with the matrix. The matrix must be
reinitialised if it is to be used again.
+Truncate, shift
+--------------------------------------------------------------------------------
+
+.. function:: void nmod_poly_mat_set_trunc(nmod_poly_mat_t res, const nmod_poly_mat_t pmat, long len)
+
+ Set ``res`` to the truncation of ``pmat`` to length ``len``. Entries of
+ ``res`` are normalized.
+
+.. function:: void nmod_poly_mat_truncate(nmod_poly_mat_t pmat, long len)
+
+ Truncates ``pmat`` to the given length ``len``, and normalize its entries.
+ If ``len`` is greater than the maximum length of the entries of ``pmat``,
+ then nothing happens.
+
+.. function:: void nmod_poly_mat_shift_left(nmod_poly_mat_t res, const nmod_poly_mat_t pmat, slong k)
+
+ Sets ``res`` to ``pmat`` shifted left by ``k`` coefficients, that is,
+ multiplied by `x^k`.
+
+.. function:: void nmod_poly_mat_shift_right(nmod_poly_mat_t res, const nmod_poly_mat_t pmat, slong k)
+
+ Sets ``res`` to ``pmat`` shifted right by ``k`` coefficients, that is,
+ divide by `x^k` and throw away the remainder. If ``k`` is greater than or
+ equal to the length of ``pmat``, the result is the zero polynomial matrix.
Basic properties
--------------------------------------------------------------------------------
@@ -84,6 +108,12 @@ Basic assignment and manipulation
Sets ``mat1`` to a copy of ``mat2``.
+.. function:: void nmod_poly_mat_set_nmod_mat(nmod_poly_mat_t pmat, const nmod_mat_t cmat)
+
+ Sets the already-initialized polynomial matrix ``pmat`` to a constant
+ matrix with the same entries as ``cmat``. Both input matrices must have the
+ same dimensions and modulus.
+
.. function:: void nmod_poly_mat_swap(nmod_poly_mat_t mat1, nmod_poly_mat_t mat2)
Swaps ``mat1`` and ``mat2`` efficiently.
@@ -146,6 +176,11 @@ Basic comparison and properties
Returns nonzero if ``mat1`` and ``mat2`` have the same shape and
all their entries agree, and returns zero otherwise.
+.. function:: int nmod_poly_mat_equal_nmod_mat(const nmod_poly_mat_t pmat, const nmod_mat_t cmat)
+
+ Returns nonzero if ``pmat`` is a constant matrix with the same dimensions
+ and entries as ``cmat``; returns zero otherwise.
+
.. function:: int nmod_poly_mat_is_zero(const nmod_poly_mat_t mat)
Returns nonzero if all entries in ``mat`` are zero, and returns
@@ -168,7 +203,21 @@ Basic comparison and properties
Returns a non-zero value if the number of rows is equal to the
number of columns in ``mat``, and otherwise returns zero.
+.. function:: void nmod_poly_mat_get_coeff_mat(nmod_mat_t coeff, const nmod_poly_mat_t pmat, slong deg)
+
+ Sets ``coeff`` to be the coefficient of ``pmat`` of degree ``deg``, where
+ ``pmat`` is seen as a polynomial with matrix coefficients and coefficients
+ are numbered from zero. ``coeff`` must be already initialized with the
+ right dimensions and modulus. For entries of ``pmat`` of degree less than
+ ``deg``, the corresponding entry of ``coeff`` is zero.
+.. function:: void nmod_poly_mat_set_coeff_mat(nmod_poly_mat_t pmat, const nmod_mat_t coeff, slong deg)
+
+ Sets the coefficient of ``pmat`` of degree ``deg`` to ``coeff``, where
+ ``pmat`` is seen as a polynomial with matrix coefficients and coefficients
+ are numbered from zero. For each entry of ``pmat``, if ``deg`` is larger
+ than its degree, this entry is first resized to the appropriate length,
+ with intervening coefficients being set to zero.
Norms
--------------------------------------------------------------------------------
@@ -178,6 +227,10 @@ Norms
Returns the maximum polynomial length among all the entries in ``A``.
+.. function:: slong nmod_poly_mat_degree(const nmod_poly_mat_t pmat)
+
+ Returns the degree of the polynomial matrix ``pmat``. The zero matrix is
+ deemed to have degree `-1`.
Evaluation
diff --git a/src/nmod_poly.h b/src/nmod_poly.h
index cb9a889f5c..b681f868d5 100644
--- a/src/nmod_poly.h
+++ b/src/nmod_poly.h
@@ -22,6 +22,7 @@
#define NMOD_POLY_INLINE static __inline__
#endif
+#include "nmod.h" /* for nmod_set_ui */
#include "nmod_types.h"
#include "thread_pool.h"
@@ -220,6 +221,15 @@ void nmod_poly_reverse(nmod_poly_t output, const nmod_poly_t input, slong m);
/* Comparison ***************************************************************/
int nmod_poly_equal(const nmod_poly_t a, const nmod_poly_t b);
+
+int nmod_poly_equal_nmod(const nmod_poly_t poly, ulong cst);
+
+NMOD_POLY_INLINE
+int nmod_poly_equal_ui(const nmod_poly_t poly, ulong cst)
+{
+ return nmod_poly_equal_nmod(poly, nmod_set_ui(cst, poly->mod));
+}
+
int nmod_poly_equal_trunc(const nmod_poly_t poly1, const nmod_poly_t poly2, slong n);
NMOD_POLY_INLINE
diff --git a/src/nmod_poly/equal.c b/src/nmod_poly/equal.c
index af4f957ee5..538fc45f3a 100644
--- a/src/nmod_poly/equal.c
+++ b/src/nmod_poly/equal.c
@@ -23,3 +23,11 @@ int nmod_poly_equal(const nmod_poly_t a, const nmod_poly_t b)
return 1;
}
+
+int nmod_poly_equal_nmod(const nmod_poly_t poly, ulong cst)
+{
+ if (cst == 0)
+ return nmod_poly_is_zero(poly);
+ else
+ return (poly->length == 1 && poly->coeffs[0] == cst);
+}
diff --git a/src/nmod_poly/shift_left.c b/src/nmod_poly/shift_left.c
deleted file mode 100644
index b1ce96a406..0000000000
--- a/src/nmod_poly/shift_left.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- Copyright (C) 2010 William Hart
-
- This file is part of FLINT.
-
- FLINT is free software: you can redistribute it and/or modify it under
- the terms of the GNU Lesser General Public License (LGPL) as published
- by the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version. See .
-*/
-
-#include "nmod_poly.h"
-
-void _nmod_poly_shift_left(mp_ptr res, mp_srcptr poly, slong len, slong k)
-{
- flint_mpn_copyd(res + k, poly, len);
- flint_mpn_zero(res, k);
-}
-
-void nmod_poly_shift_left(nmod_poly_t res, const nmod_poly_t poly, slong k)
-{
- if (nmod_poly_is_zero(poly))
- {
- nmod_poly_zero(res);
- return;
- }
-
- nmod_poly_fit_length(res, poly->length + k);
-
- _nmod_poly_shift_left(res->coeffs, poly->coeffs, poly->length, k);
-
- res->length = poly->length + k;
-}
-
diff --git a/src/nmod_poly/shift_right.c b/src/nmod_poly/shift_left_right.c
similarity index 64%
rename from src/nmod_poly/shift_right.c
rename to src/nmod_poly/shift_left_right.c
index fa1af137a3..7ee049fde8 100644
--- a/src/nmod_poly/shift_right.c
+++ b/src/nmod_poly/shift_left_right.c
@@ -11,6 +11,27 @@
#include "nmod_poly.h"
+void _nmod_poly_shift_left(mp_ptr res, mp_srcptr poly, slong len, slong k)
+{
+ flint_mpn_copyd(res + k, poly, len);
+ flint_mpn_zero(res, k);
+}
+
+void nmod_poly_shift_left(nmod_poly_t res, const nmod_poly_t poly, slong k)
+{
+ if (nmod_poly_is_zero(poly))
+ {
+ nmod_poly_zero(res);
+ return;
+ }
+
+ nmod_poly_fit_length(res, poly->length + k);
+
+ _nmod_poly_shift_left(res->coeffs, poly->coeffs, poly->length, k);
+
+ res->length = poly->length + k;
+}
+
void _nmod_poly_shift_right(mp_ptr res, mp_srcptr poly, slong len, slong k)
{
flint_mpn_copyi(res, poly + k, len);
@@ -30,3 +51,4 @@ void nmod_poly_shift_right(nmod_poly_t res, const nmod_poly_t poly, slong k)
res->length = len;
}
}
+
diff --git a/src/nmod_poly_mat.h b/src/nmod_poly_mat.h
index b212bd9618..4641224a58 100644
--- a/src/nmod_poly_mat.h
+++ b/src/nmod_poly_mat.h
@@ -62,8 +62,30 @@ nmod_poly_mat_swap_entrywise(nmod_poly_mat_t mat1, nmod_poly_mat_t mat2)
void nmod_poly_mat_set(nmod_poly_mat_t mat1, const nmod_poly_mat_t mat2);
+void nmod_poly_mat_set_nmod_mat(nmod_poly_mat_t pmat, const nmod_mat_t cmat);
+
void nmod_poly_mat_clear(nmod_poly_mat_t mat);
+/* Truncate, shift *********************************************************/
+
+void nmod_poly_mat_set_trunc(nmod_poly_mat_t res,
+ const nmod_poly_mat_t pmat,
+ long len);
+
+NMOD_POLY_MAT_INLINE
+void nmod_poly_mat_truncate(nmod_poly_mat_t pmat, long len)
+{
+ nmod_poly_mat_set_trunc(pmat, pmat, len);
+}
+
+void nmod_poly_mat_shift_left(nmod_poly_mat_t res,
+ const nmod_poly_mat_t pmat,
+ slong k);
+
+void nmod_poly_mat_shift_right(nmod_poly_mat_t res,
+ const nmod_poly_mat_t pmat,
+ slong k);
+
/* Basic properties **********************************************************/
NMOD_POLY_MAT_INLINE mp_limb_t
@@ -72,11 +94,23 @@ nmod_poly_mat_modulus(const nmod_poly_mat_t mat)
return mat->modulus;
}
+void nmod_poly_mat_get_coeff_mat(nmod_mat_t coeff,
+ const nmod_poly_mat_t pmat,
+ slong deg);
+
+void nmod_poly_mat_set_coeff_mat(nmod_poly_mat_t pmat,
+ const nmod_mat_t coeff,
+ slong deg);
+
+
/* Comparison ****************************************************************/
int nmod_poly_mat_equal(const nmod_poly_mat_t mat1,
const nmod_poly_mat_t mat2);
+int nmod_poly_mat_equal_nmod_mat(const nmod_poly_mat_t pmat,
+ const nmod_mat_t cmat);
+
int nmod_poly_mat_is_zero(const nmod_poly_mat_t mat);
int nmod_poly_mat_is_one(const nmod_poly_mat_t mat);
@@ -128,6 +162,13 @@ void nmod_poly_mat_print(const nmod_poly_mat_t mat, const char * x);
slong nmod_poly_mat_max_length(const nmod_poly_mat_t A);
+NMOD_POLY_MAT_INLINE
+slong nmod_poly_mat_degree(const nmod_poly_mat_t pmat)
+{
+ return nmod_poly_mat_max_length(pmat)-1;
+}
+
+
/* Scalar arithmetic *********************************************************/
void nmod_poly_mat_scalar_mul_nmod_poly(nmod_poly_mat_t B,
diff --git a/src/nmod_poly_mat/equal.c b/src/nmod_poly_mat/equal.c
index 2269445ac9..a9f9416c63 100644
--- a/src/nmod_poly_mat/equal.c
+++ b/src/nmod_poly_mat/equal.c
@@ -1,5 +1,6 @@
/*
Copyright (C) 2011 Fredrik Johansson
+ Copyright (C) 2023 Vincent Neiger
This file is part of FLINT.
@@ -9,8 +10,8 @@
(at your option) any later version. See .
*/
-#include "flint.h"
#include "nmod_poly.h"
+#include "nmod_mat.h"
#include "nmod_poly_mat.h"
int
@@ -28,3 +29,18 @@ nmod_poly_mat_equal(const nmod_poly_mat_t A, const nmod_poly_mat_t B)
return 0;
return 1;
}
+
+int
+nmod_poly_mat_equal_nmod_mat(const nmod_poly_mat_t pmat,
+ const nmod_mat_t cmat)
+{
+ if (pmat->r != cmat->r || pmat->c != cmat->c)
+ return 0;
+
+ for (slong i = 0; i < pmat->r; i++)
+ for (slong j = 0; j < pmat->c; j++)
+ if (! nmod_poly_equal_nmod(nmod_poly_mat_entry(pmat, i, j),
+ nmod_mat_entry(cmat, i, j)))
+ return 0;
+ return 1;
+}
diff --git a/src/nmod_poly_mat/get_set_coeff_mat.c b/src/nmod_poly_mat/get_set_coeff_mat.c
new file mode 100644
index 0000000000..0bb53b791a
--- /dev/null
+++ b/src/nmod_poly_mat/get_set_coeff_mat.c
@@ -0,0 +1,33 @@
+/*
+ Copyright (C) 2023 Vincent Neiger
+
+ This file is part of FLINT.
+
+ FLINT is free software: you can redistribute it and/or modify it under
+ the terms of the GNU Lesser General Public License (LGPL) as published
+ by the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version. See .
+*/
+
+#include "nmod_mat.h"
+#include "nmod_poly.h"
+#include "nmod_poly_mat.h"
+
+void nmod_poly_mat_get_coeff_mat(nmod_mat_t res, const nmod_poly_mat_t mat, slong deg)
+{
+ for (slong i = 0; i < mat->r; i++)
+ for (slong j = 0; j < mat->c; j++)
+ nmod_mat_set_entry(res, i, j,
+ nmod_poly_get_coeff_ui(nmod_poly_mat_entry(mat, i, j), deg));
+}
+
+void nmod_poly_mat_set_coeff_mat(nmod_poly_mat_t pmat,
+ const nmod_mat_t coeff,
+ slong deg)
+{
+ for (slong i = 0; i < pmat->r; i++)
+ for (slong j = 0; j < pmat->c; j++)
+ nmod_poly_set_coeff_ui(nmod_poly_mat_entry(pmat, i, j),
+ deg, nmod_mat_entry(coeff, i, j));
+}
+
diff --git a/src/nmod_poly_mat/set.c b/src/nmod_poly_mat/set.c
index daac9cc5d1..cc26edb4a4 100644
--- a/src/nmod_poly_mat/set.c
+++ b/src/nmod_poly_mat/set.c
@@ -1,5 +1,6 @@
/*
Copyright (C) 2011 Fredrik Johansson
+ Copyright (C) 2023 Vincent Neiger
This file is part of FLINT.
@@ -9,8 +10,8 @@
(at your option) any later version. See .
*/
-#include "flint.h"
#include "nmod_poly.h"
+#include "nmod_mat.h"
#include "nmod_poly_mat.h"
void
@@ -26,3 +27,22 @@ nmod_poly_mat_set(nmod_poly_mat_t B, const nmod_poly_mat_t A)
nmod_poly_mat_entry(A, i, j));
}
}
+
+void nmod_poly_mat_set_nmod_mat(nmod_poly_mat_t pmat, const nmod_mat_t cmat)
+{
+ for (slong i = 0; i < cmat->r; i++)
+ {
+ for (slong j = 0; j < cmat->c; j++)
+ {
+ if (nmod_mat_entry(cmat, i, j) == 0)
+ nmod_poly_zero(nmod_poly_mat_entry(pmat, i, j));
+ else
+ {
+ nmod_poly_realloc(nmod_poly_mat_entry(pmat, i, j), 1);
+ nmod_poly_mat_entry(pmat, i, j)->coeffs[0]
+ = nmod_mat_entry(cmat, i, j);
+ }
+ }
+ }
+}
+
diff --git a/src/nmod_poly_mat/set_trunc.c b/src/nmod_poly_mat/set_trunc.c
new file mode 100644
index 0000000000..13ec02d3eb
--- /dev/null
+++ b/src/nmod_poly_mat/set_trunc.c
@@ -0,0 +1,55 @@
+/*
+ Copyright (C) 2023 Vincent Neiger
+
+ This file is part of FLINT.
+
+ FLINT is free software: you can redistribute it and/or modify it under
+ the terms of the GNU Lesser General Public License (LGPL) as published
+ by the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version. See .
+*/
+
+#include "nmod_vec.h" /* for nmod_vec_set */
+#include "nmod_poly_mat.h"
+
+void nmod_poly_mat_set_trunc(nmod_poly_mat_t res, const nmod_poly_mat_t pmat, long len)
+{
+ nmod_poly_struct * res_ij;
+ nmod_poly_struct * pmat_ij;
+
+ if (pmat == res)
+ {
+ for (slong i = 0; i < pmat->r; i++)
+ {
+ for (slong j = 0; j < pmat->c; j++)
+ {
+ res_ij = nmod_poly_mat_entry(res, i, j);
+ if (res_ij->length > len)
+ {
+ res_ij->length = len;
+ _nmod_poly_normalise(res_ij);
+ }
+ }
+ }
+ }
+ else
+ {
+ slong rlen;
+ for (slong i = 0; i < pmat->r; i++)
+ {
+ for (slong j = 0; j < pmat->c; j++)
+ {
+ res_ij = nmod_poly_mat_entry(res, i, j);
+ pmat_ij = nmod_poly_mat_entry(pmat, i, j);
+
+ rlen = FLINT_MIN(len, pmat_ij->length);
+ while (rlen > 0 && pmat_ij->coeffs[rlen - 1] == 0)
+ rlen--;
+
+ nmod_poly_fit_length(res_ij, rlen);
+ _nmod_vec_set(res_ij->coeffs, pmat_ij->coeffs, rlen);
+ _nmod_poly_set_length(res_ij, rlen);
+ }
+ }
+ }
+}
diff --git a/src/nmod_poly_mat/shift_left_right.c b/src/nmod_poly_mat/shift_left_right.c
new file mode 100644
index 0000000000..9d9f7faa63
--- /dev/null
+++ b/src/nmod_poly_mat/shift_left_right.c
@@ -0,0 +1,26 @@
+/*
+ Copyright (C) 2023 Vincent Neiger
+
+ This file is part of FLINT.
+
+ FLINT is free software: you can redistribute it and/or modify it under
+ the terms of the GNU Lesser General Public License (LGPL) as published
+ by the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version. See .
+*/
+
+#include "nmod_poly_mat.h"
+
+void nmod_poly_mat_shift_left(nmod_poly_mat_t res, const nmod_poly_mat_t pmat, slong k)
+{
+ for (slong i = 0; i < pmat->r; i++)
+ for (slong j = 0; j < pmat->c; j++)
+ nmod_poly_shift_left(nmod_poly_mat_entry(res, i, j), nmod_poly_mat_entry(pmat, i, j), k);
+}
+
+void nmod_poly_mat_shift_right(nmod_poly_mat_t res, const nmod_poly_mat_t pmat, slong k)
+{
+ for (slong i = 0; i < pmat->r; i++)
+ for (slong j = 0; j < pmat->c; j++)
+ nmod_poly_shift_right(nmod_poly_mat_entry(res, i, j), nmod_poly_mat_entry(pmat, i, j), k);
+}
diff --git a/src/nmod_poly_mat/test/t-get-set-coeff-mat.c b/src/nmod_poly_mat/test/t-get-set-coeff-mat.c
new file mode 100644
index 0000000000..80613a9356
--- /dev/null
+++ b/src/nmod_poly_mat/test/t-get-set-coeff-mat.c
@@ -0,0 +1,94 @@
+/*
+ Copyright (C) 2023 Vincent Neiger
+
+ This file is part of FLINT.
+
+ FLINT is free software: you can redistribute it and/or modify it under
+ the terms of the GNU Lesser General Public License (LGPL) as published
+ by the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version. See .
+*/
+
+#include "ulong_extras.h"
+#include "nmod_poly_mat.h"
+#include "nmod_mat.h"
+
+int
+main(void)
+{
+ int i, result;
+ ulong j;
+ FLINT_TEST_INIT(state);
+
+
+ flint_printf("get/set_coeff_mat....");
+ fflush(stdout);
+
+ for (i = 0; i < 100 * flint_test_multiplier(); i++)
+ {
+ nmod_poly_mat_t pmat1;
+ nmod_poly_mat_t pmat2;
+ nmod_mat_t cmat1;
+ nmod_mat_t cmat2;
+ mp_limb_t mod;
+ slong m, n, deg;
+
+ mod = n_randtest_prime(state, 0);
+ m = n_randint(state, 20);
+ n = n_randint(state, 20);
+ deg = 3 + n_randint(state, 10);
+
+ nmod_poly_mat_init(pmat1, m, n, mod);
+ nmod_poly_mat_init(pmat2, m, n, mod);
+ nmod_mat_init(cmat1, m, n, mod);
+ nmod_mat_init(cmat2, m, n, mod);
+
+ // test 1: set then get does not change values
+ nmod_mat_randtest(cmat1, state);
+ nmod_poly_mat_set_coeff_mat(pmat1, cmat1, deg-1);
+ nmod_poly_mat_get_coeff_mat(cmat2, pmat1, deg-1);
+ if (! nmod_mat_equal(cmat1, cmat2))
+ {
+ flint_printf("FAIL (set then get):\n");
+ flint_printf("pmat1:\n");
+ nmod_poly_mat_print(pmat1, "x");
+ flint_printf("cmat1:\n");
+ nmod_mat_print(cmat1);
+ flint_printf("cmat2:\n");
+ nmod_mat_print(cmat2);
+ flint_printf("\n");
+ fflush(stdout);
+ flint_abort();
+ }
+
+ // test 2: copying via repeated get-set works
+ nmod_poly_mat_randtest(pmat1, state, deg);
+ for (int d=0; d.
+*/
+
+#include "ulong_extras.h"
+#include "nmod_mat.h"
+#include "nmod_poly_mat.h"
+
+int
+main(void)
+{
+ slong i;
+
+ FLINT_TEST_INIT(state);
+
+ flint_printf("set_nmod_mat....");
+ fflush(stdout);
+
+ for (i = 0; i < 400 * flint_test_multiplier(); i++)
+ {
+ nmod_poly_mat_t pmat;
+ nmod_mat_t cmat;
+ mp_limb_t mod;
+ slong m, n, deg;
+
+ mod = n_randtest_prime(state, 0);
+ m = n_randint(state, 20);
+ n = n_randint(state, 20);
+ deg = 1 + n_randint(state, 10);
+
+ nmod_poly_mat_init(pmat, m, n, mod);
+ nmod_mat_init(cmat, m, n, mod);
+
+ nmod_poly_mat_set_nmod_mat(pmat, cmat);
+ if (! nmod_poly_mat_equal_nmod_mat(pmat, cmat))
+ {
+ flint_printf("FAIL:\n");
+ flint_printf("pmat:\n");
+ nmod_poly_mat_print(pmat, "x");
+ flint_printf("cmat:\n");
+ nmod_mat_print(cmat);
+ flint_printf("\n");
+ fflush(stdout);
+ flint_abort();
+ }
+
+ nmod_poly_mat_randtest(pmat, state, deg);
+ nmod_poly_mat_set_nmod_mat(pmat, cmat);
+ if (! nmod_poly_mat_equal_nmod_mat(pmat, cmat))
+ {
+ flint_printf("FAIL:\n");
+ flint_printf("pmat:\n");
+ nmod_poly_mat_print(pmat, "x");
+ flint_printf("cmat:\n");
+ nmod_mat_print(cmat);
+ flint_printf("\n");
+ fflush(stdout);
+ flint_abort();
+ }
+
+ nmod_poly_mat_clear(pmat);
+ nmod_mat_clear(cmat);
+ }
+
+ FLINT_TEST_CLEANUP(state);
+
+ flint_printf("PASS\n");
+ return 0;
+}
diff --git a/src/nmod_poly_mat/test/t-set_trunc.c b/src/nmod_poly_mat/test/t-set_trunc.c
new file mode 100644
index 0000000000..e751990cc1
--- /dev/null
+++ b/src/nmod_poly_mat/test/t-set_trunc.c
@@ -0,0 +1,108 @@
+/*
+ Copyright (C) 2023 Vincent Neiger
+
+ This file is part of FLINT.
+
+ FLINT is free software: you can redistribute it and/or modify it under
+ the terms of the GNU Lesser General Public License (LGPL) as published
+ by the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version. See .
+*/
+
+#include "ulong_extras.h"
+#include "nmod_poly_mat.h"
+
+
+void test_with_dims(ulong m, ulong n, flint_rand_t state)
+{
+ int result;
+
+ nmod_poly_mat_t a, b, c;
+ ulong p;
+ slong len;
+
+ p = n_randtest_prime(state, 0);
+
+ nmod_poly_mat_init(a, m, n, p);
+ nmod_poly_mat_init(b, m, n, p);
+ nmod_poly_mat_init(c, m, n, p);
+
+ nmod_poly_mat_randtest(a, state, n_randint(state, 100));
+ nmod_poly_mat_randtest(b, state, n_randint(state, 100));
+ len = n_randint(state, 50);
+
+ nmod_poly_mat_set_trunc(b, a, len);
+
+ nmod_poly_t poly;
+ nmod_poly_init(poly, p);
+ for (int i=0; i.
+*/
+
+#include "nmod_poly_mat.h"
+
+/* Check a << shift >> shift == a */
+void test_with_dimensions1(ulong rdim, ulong cdim, flint_rand_t state)
+{
+ int result;
+
+ nmod_poly_mat_t a, b;
+ mp_limb_t n = n_randtest_not_zero(state);
+ slong shift = n_randint(state, 100);
+
+ nmod_poly_mat_init(a, rdim, cdim, n);
+ nmod_poly_mat_init(b, rdim, cdim, n);
+ nmod_poly_mat_randtest(a, state, n_randint(state, 100));
+
+ nmod_poly_mat_shift_left(b, a, shift);
+ nmod_poly_mat_shift_right(b, b, shift);
+
+ result = (nmod_poly_mat_equal(a, b));
+ if (!result)
+ {
+ flint_printf("FAIL:\n");
+ flint_printf("shift = %wd, rdim = %ld, cdim = %ld, n = %wu\n",
+ shift, rdim, cdim, n);
+ nmod_poly_mat_print(a, "X"), flint_printf("\n\n");
+ nmod_poly_mat_print(b, "X"), flint_printf("\n\n");
+ fflush(stdout);
+ flint_abort();
+ }
+
+ nmod_poly_mat_clear(a);
+ nmod_poly_mat_clear(b);
+}
+
+/* Check a << shift >> shift == a aliasing the other way */
+void test_with_dimensions2(ulong rdim, ulong cdim, flint_rand_t state)
+{
+ int result;
+
+ nmod_poly_mat_t a, b, c;
+ mp_limb_t n = n_randtest_not_zero(state);
+ slong shift = n_randint(state, 100);
+
+ nmod_poly_mat_init(a, rdim, cdim, n);
+ nmod_poly_mat_init(b, rdim, cdim, n);
+ nmod_poly_mat_init(c, rdim, cdim, n);
+ nmod_poly_mat_randtest(c, state, n_randint(state, 100));
+
+ nmod_poly_mat_set(a, c);
+ nmod_poly_mat_shift_left(c, c, shift);
+ nmod_poly_mat_shift_right(b, c, shift);
+
+ result = (nmod_poly_mat_equal(a, b));
+ if (!result)
+ {
+ flint_printf("FAIL:\n");
+ flint_printf("shift = %wd, rdim = %ld, cdim = %ld, n = %wu\n",
+ shift, rdim, cdim, n);
+ nmod_poly_mat_print(a, "X"), flint_printf("\n\n");
+ nmod_poly_mat_print(b, "X"), flint_printf("\n\n");
+ fflush(stdout);
+ flint_abort();
+ }
+
+ nmod_poly_mat_clear(a);
+ nmod_poly_mat_clear(b);
+ nmod_poly_mat_clear(c);
+}
+
+int
+main(void)
+{
+ int i, result;
+ FLINT_TEST_INIT(state);
+
+
+ flint_printf("shift_left_right....");
+ fflush(stdout);
+
+ for (i = 0; i < 100 * flint_test_multiplier(); i++)
+ {
+ test_with_dimensions1(2,5,state);
+ test_with_dimensions1(3,3,state);
+ test_with_dimensions1(5,2,state);
+ }
+ for (i = 0; i < 100 * flint_test_multiplier(); i++)
+ {
+ test_with_dimensions2(2,5,state);
+ test_with_dimensions2(3,3,state);
+ test_with_dimensions2(5,2,state);
+ }
+
+ FLINT_TEST_CLEANUP(state);
+
+ flint_printf("PASS\n");
+ return 0;
+}