#include "test_helpers.h"
#include "fmpz.h"
#include "fmpz_mat.h"
#include "fmpz_poly.h"
FLINT_STATIC_NOINLINE void set_matrix(fmpz_mat_t am, slong n)
{
slong ix, jx;
for (ix = 0; ix < n/2; ix++)
for (jx = 0; jx < n/2; jx++)
{
fmpz_zero(fmpz_mat_entry(am, ix + n/2, jx));
fmpz_zero(fmpz_mat_entry(am, ix, jx + n/2));
fmpz_set(fmpz_mat_entry(am, ix + n/2, jx + n/2), fmpz_mat_entry(am, ix, jx));
}
}
TEST_FUNCTION_START(fmpz_mat_minpoly, state)
{
slong n, rep;
for (rep = 0; rep < 1000 * flint_test_multiplier(); rep++)
{
fmpz_t c;
fmpz_mat_t A;
fmpz_poly_t f, g, q, r;
slong ix;
n = n_randint(state, 10);
fmpz_init(c);
fmpz_mat_init(A, n, n);
fmpz_poly_init(f);
fmpz_poly_init(g);
fmpz_poly_init(q);
fmpz_poly_init(r);
if (n_randint(state, 50) == 0)
fmpz_mat_randtest(A, state, 10000);
else
fmpz_mat_randtest(A, state, 10);
set_matrix(A, n);
for (ix = 0; ix < 10; ix++)
{
fmpz_randtest(c, state, 5);
fmpz_mat_similarity(A, n_randint(state, n), c);
}
fmpz_mat_minpoly(f, A);
fmpz_mat_charpoly(g, A);
fmpz_poly_divrem(q, r, g, f);
if (!fmpz_poly_is_zero(r))
{
flint_printf("FAIL: minpoly(A) doesn't divide charpoly(A).\n");
flint_printf("Matrix A:\n"), fmpz_mat_print(A), flint_printf("\n");
flint_printf("mp(A) = "), fmpz_poly_print_pretty(f, "X"), flint_printf("\n");
flint_printf("cp(A) = "), fmpz_poly_print_pretty(g, "X"), flint_printf("\n");
fflush(stdout);
flint_abort();
}
fmpz_clear(c);
fmpz_mat_clear(A);
fmpz_poly_clear(f);
fmpz_poly_clear(g);
fmpz_poly_clear(q);
fmpz_poly_clear(r);
}
for (rep = 0; rep < 1000 * flint_test_multiplier(); rep++)
{
fmpz_t c;
fmpz_mat_t A, B;
fmpz_poly_t f, g;
slong ix;
n = n_randint(state, 10);
fmpz_init(c);
fmpz_mat_init(A, n, n);
fmpz_mat_init(B, n, n);
fmpz_poly_init(f);
fmpz_poly_init(g);
fmpz_mat_randtest(A, state, 10);
set_matrix(A, n);
fmpz_mat_set(B, A);
for (ix = 0; ix < 10; ix++)
{
fmpz_randtest(c, state, 5);
fmpz_mat_similarity(B, n_randint(state, n), c);
}
fmpz_mat_minpoly(f, A);
fmpz_mat_minpoly(g, B);
if (!fmpz_poly_equal(f, g))
{
flint_printf("FAIL: minpoly(A) != minpoly(P^{-1}AP).\n");
flint_printf("Matrix A:\n"), fmpz_mat_print(A), flint_printf("\n");
flint_printf("Matrix P^{-1}AP:\n"), fmpz_mat_print(B), flint_printf("\n");
flint_printf("mp(A) = "), fmpz_poly_print_pretty(f, "X"), flint_printf("\n");
flint_printf("mp(P^{-1}AP) = "), fmpz_poly_print_pretty(g, "X"), flint_printf("\n");
fflush(stdout);
flint_abort();
}
fmpz_clear(c);
fmpz_mat_clear(A);
fmpz_mat_clear(B);
fmpz_poly_clear(f);
fmpz_poly_clear(g);
}
{
fmpz_mat_t A;
fmpz_poly_t f;
fmpz_mat_init(A, 2, 2);
fmpz_poly_init(f);
fmpz_mat_zero(A);
fmpz_mat_minpoly(f, A);
if (fmpz_poly_length(f) != 2 || f->coeffs[0] != 0 || f->coeffs[1] != 1)
TEST_FUNCTION_FAIL("minpoly(A) != X for zero matrix A\n"
"minpoly(A) = %{fmpz_poly}\n",
f);
fmpz_mat_clear(A);
fmpz_poly_clear(f);
}
TEST_FUNCTION_END(state);
}