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; +}