int fmpz_mat_solve_cramer(fmpz_mat_t X, fmpz_t den, const fmpz_mat_t A, const fmpz_mat_t B) { long i, dim = fmpz_mat_nrows(A); if (dim == 0) { fmpz_one(den); return 1; } else if (dim == 1) { fmpz_set(den, fmpz_mat_entry(A, 0, 0)); if (fmpz_is_zero(den)) return 0; if (!fmpz_mat_is_empty(B)) _fmpz_vec_set(X->rows[0], B->rows[0], fmpz_mat_ncols(B)); return 1; } else if (dim == 2) { fmpz_t t, u; _fmpz_mat_det_cofactor_2x2(den, A->rows); if (fmpz_is_zero(den)) return 0; fmpz_init(t); fmpz_init(u); for (i = 0; i < fmpz_mat_ncols(B); i++) { fmpz_mul (t, fmpz_mat_entry(A, 1, 1), fmpz_mat_entry(B, 0, i)); fmpz_submul(t, fmpz_mat_entry(A, 0, 1), fmpz_mat_entry(B, 1, i)); fmpz_mul (u, fmpz_mat_entry(A, 0, 0), fmpz_mat_entry(B, 1, i)); fmpz_submul(u, fmpz_mat_entry(A, 1, 0), fmpz_mat_entry(B, 0, i)); fmpz_swap(fmpz_mat_entry(X, 0, i), t); fmpz_swap(fmpz_mat_entry(X, 1, i), u); } fmpz_clear(t); fmpz_clear(u); return 1; } else if (dim == 3) { return _fmpz_mat_solve_cramer_3x3(X, den, A, B); } else { printf("Exception: fmpz_mat_solve_cramer: dim > 3 not implemented"); abort(); } }
void _fmpz_mat_solve_cramer_2x2(fmpz * x, fmpz_t d, fmpz ** const a, const fmpz * b) { fmpz_mul (&x[0], &a[1][1], &b[0]); fmpz_submul(&x[0], &a[0][1], &b[1]); fmpz_mul (&x[1], &a[0][0], &b[1]); fmpz_submul(&x[1], &a[1][0], &b[0]); _fmpz_mat_det_cofactor_2x2(d, a); }
void _fmpz_mat_inv_2x2(fmpz ** b, fmpz_t den, fmpz ** const a) { fmpz_t tmp; _fmpz_mat_det_cofactor_2x2(den, a); fmpz_neg(&b[0][1], &a[0][1]); fmpz_neg(&b[1][0], &a[1][0]); fmpz_init(tmp); fmpz_set(tmp, &a[0][0]); fmpz_set(&b[0][0], &a[1][1]); fmpz_set(&b[1][1], tmp); fmpz_clear(tmp); }