void fmpz_mat_solve_cramer(fmpz * x, fmpz_t den, const fmpz_mat_t A, const fmpz * b) { long dim = A->r; switch (dim) { case 0: fmpz_set_ui(den, 1UL); break; case 1: fmpz_set(den, A->rows[0]); fmpz_set(x, b); break; case 2: _fmpz_mat_solve_cramer_2x2(x, den, A->rows, b); break; case 3: _fmpz_mat_solve_cramer_3x3(x, den, A->rows, b); break; default: printf("Exception: fmpz_mat_solve_cramer: dim > 3 not implemented"); abort(); } }
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(); } }