int fmpz_mat_solve_fflu(fmpz_mat_t X, fmpz_t den, const fmpz_mat_t A, const fmpz_mat_t B) { fmpz_mat_t LU; slong dim, *perm; int result; if (fmpz_mat_is_empty(A) || fmpz_mat_is_empty(B)) { fmpz_one(den); return 1; } dim = fmpz_mat_nrows(A); perm = _perm_init(dim); fmpz_mat_init_set(LU, A); result = (fmpz_mat_fflu(LU, den, perm, LU, 1) == dim); if (result) fmpz_mat_solve_fflu_precomp(X, perm, LU, B); else fmpz_zero(den); _perm_clear(perm); fmpz_mat_clear(LU); return result; }
void _fmpz_mat_det_bareiss(fmpz_t det, fmpz_mat_t tmp) { long *perm, n = fmpz_mat_nrows(tmp); perm = _perm_init(n); fmpz_mat_fflu(tmp, det, perm, tmp, 1); if (_perm_parity(perm, n) == 1) fmpz_neg(det, det); _perm_clear(perm); }
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; }
int main() { slong iter; flint_rand_t state; flint_printf("lu...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000; iter++) { fmpq_mat_t Q; acb_mat_t A, LU, P, L, U, T; slong i, j, n, qbits, prec, *perm; int q_invertible, r_invertible; n = n_randint(state, 8); qbits = 1 + n_randint(state, 100); prec = 2 + n_randint(state, 202); fmpq_mat_init(Q, n, n); acb_mat_init(A, n, n); acb_mat_init(LU, n, n); acb_mat_init(P, n, n); acb_mat_init(L, n, n); acb_mat_init(U, n, n); acb_mat_init(T, n, n); perm = _perm_init(n); fmpq_mat_randtest(Q, state, qbits); q_invertible = fmpq_mat_is_invertible(Q); if (!q_invertible) { acb_mat_set_fmpq_mat(A, Q, prec); r_invertible = acb_mat_lu(perm, LU, A, prec); if (r_invertible) { flint_printf("FAIL: matrix is singular over Q but not over R\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("LU = \n"); acb_mat_printd(LU, 15); flint_printf("\n\n"); } } else { /* now this must converge */ while (1) { acb_mat_set_fmpq_mat(A, Q, prec); r_invertible = acb_mat_lu(perm, LU, A, prec); if (r_invertible) { break; } else { if (prec > 10000) { flint_printf("FAIL: failed to converge at 10000 bits\n"); abort(); } prec *= 2; } } acb_mat_one(L); for (i = 0; i < n; i++) for (j = 0; j < i; j++) acb_set(acb_mat_entry(L, i, j), acb_mat_entry(LU, i, j)); for (i = 0; i < n; i++) for (j = i; j < n; j++) acb_set(acb_mat_entry(U, i, j), acb_mat_entry(LU, i, j)); for (i = 0; i < n; i++) acb_one(acb_mat_entry(P, perm[i], i)); acb_mat_mul(T, P, L, prec); acb_mat_mul(T, T, U, prec); if (!acb_mat_contains_fmpq_mat(T, Q)) { flint_printf("FAIL (containment, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("LU = \n"); acb_mat_printd(LU, 15); flint_printf("\n\n"); flint_printf("L = \n"); acb_mat_printd(L, 15); flint_printf("\n\n"); flint_printf("U = \n"); acb_mat_printd(U, 15); flint_printf("\n\n"); flint_printf("P*L*U = \n"); acb_mat_printd(T, 15); flint_printf("\n\n"); abort(); } } fmpq_mat_clear(Q); acb_mat_clear(A); acb_mat_clear(LU); acb_mat_clear(P); acb_mat_clear(L); acb_mat_clear(U); acb_mat_clear(T); _perm_clear(perm); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
int fmpz_poly_mat_inv(fmpz_poly_mat_t Ainv, fmpz_poly_t den, const fmpz_poly_mat_t A) { long n = fmpz_poly_mat_nrows(A); if (n == 0) { fmpz_poly_one(den); return 1; } else if (n == 1) { fmpz_poly_set(den, E(A, 0, 0)); fmpz_poly_one(E(Ainv, 0, 0)); return !fmpz_poly_is_zero(den); } else if (n == 2) { fmpz_poly_mat_det(den, A); if (fmpz_poly_is_zero(den)) { return 0; } else if (Ainv == A) { fmpz_poly_swap(E(A, 0, 0), E(A, 1, 1)); fmpz_poly_neg(E(A, 0, 1), E(A, 0, 1)); fmpz_poly_neg(E(A, 1, 0), E(A, 1, 0)); return 1; } else { fmpz_poly_set(E(Ainv, 0, 0), E(A, 1, 1)); fmpz_poly_set(E(Ainv, 1, 1), E(A, 0, 0)); fmpz_poly_neg(E(Ainv, 0, 1), E(A, 0, 1)); fmpz_poly_neg(E(Ainv, 1, 0), E(A, 1, 0)); return 1; } } else { fmpz_poly_mat_t LU, I; long * perm; int result; perm = _perm_init(n); fmpz_poly_mat_init_set(LU, A); result = (fmpz_poly_mat_fflu(LU, den, perm, LU, 1) == n); if (result) { fmpz_poly_mat_init(I, n, n); fmpz_poly_mat_one(I); fmpz_poly_mat_solve_fflu_precomp(Ainv, perm, LU, I); fmpz_poly_mat_clear(I); } else fmpz_poly_zero(den); if (_perm_parity(perm, n)) { fmpz_poly_mat_neg(Ainv, Ainv); fmpz_poly_neg(den, den); } _perm_clear(perm); fmpz_poly_mat_clear(LU); return result; } }
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; }
int main(void) { int i; FLINT_TEST_INIT(state); flint_printf("inv...."); fflush(stdout); /* check inv(inv(a)) == a */ for (i = 0; i < 10000; i++) { slong n, *a, *b, *c; n = n_randint(state, 100); a = _perm_init(n); b = _perm_init(n); c = _perm_init(n); _perm_randtest(a, n, state); _perm_inv(b, a, n); _perm_inv(c, b, n); if (!_perm_equal(a, c, n)) { flint_printf("FAIL:\n"); flint_printf("a: "); _perm_print(a, n); flint_printf("\n\n"); flint_printf("b: "); _perm_print(b, n); flint_printf("\n\n"); flint_printf("c: "); _perm_print(c, n); flint_printf("\n\n"); abort(); } _perm_clear(a); _perm_clear(b); _perm_clear(c); } /* check aliasing */ for (i = 0; i < 10000; i++) { slong n, *a, *b; n = n_randint(state, 100); a = _perm_init(n); b = _perm_init(n); _perm_randtest(a, n, state); _perm_inv(b, a, n); _perm_inv(a, a, n); if (!_perm_equal(a, b, n)) { flint_printf("FAIL:\n"); flint_printf("a: "); _perm_print(a, n); flint_printf("\n\n"); flint_printf("b: "); _perm_print(b, n); flint_printf("\n\n"); abort(); } _perm_clear(a); _perm_clear(b); } FLINT_TEST_CLEANUP(state); flint_printf("PASS\n"); return 0; }