void arb_mat_set_round_fmpz_mat(arb_mat_t dest, const fmpz_mat_t src, slong prec) { slong i, j; if (arb_mat_ncols(dest) != 0) { for (i = 0; i < arb_mat_nrows(dest); i++) for (j = 0; j < arb_mat_ncols(dest); j++) arb_set_round_fmpz(arb_mat_entry(dest, i, j), fmpz_mat_entry(src, i, j), prec); } }
void arb_mat_randtest(arb_mat_t mat, flint_rand_t state, slong prec, slong mag_bits) { slong i, j; if (n_randint(state, 2)) for (i = 0; i < arb_mat_nrows(mat); i++) for (j = 0; j < arb_mat_ncols(mat); j++) arb_randtest(arb_mat_entry(mat, i, j), state, prec, mag_bits); else for (i = 0; i < arb_mat_nrows(mat); i++) for (j = 0; j < arb_mat_ncols(mat); j++) arb_randtest_precise(arb_mat_entry(mat, i, j), state, prec, mag_bits); }
void arb_mat_mul_classical(arb_mat_t C, const arb_mat_t A, const arb_mat_t B, long prec) { long ar, ac, br, bc, i, j, k; ar = arb_mat_nrows(A); ac = arb_mat_ncols(A); br = arb_mat_nrows(B); bc = arb_mat_ncols(B); if (ac != br || ar != arb_mat_nrows(C) || bc != arb_mat_ncols(C)) { printf("arb_mat_mul: incompatible dimensions\n"); abort(); } if (br == 0) { arb_mat_zero(C); return; } if (A == C || B == C) { arb_mat_t T; arb_mat_init(T, ar, bc); arb_mat_mul(T, A, B, prec); arb_mat_swap(T, C); arb_mat_clear(T); return; } for (i = 0; i < ar; i++) { for (j = 0; j < bc; j++) { arb_mul(arb_mat_entry(C, i, j), arb_mat_entry(A, i, 0), arb_mat_entry(B, 0, j), prec); for (k = 1; k < br; k++) { arb_addmul(arb_mat_entry(C, i, j), arb_mat_entry(A, i, k), arb_mat_entry(B, k, j), prec); } } } }
int arb_mat_lu(long * P, arb_mat_t LU, const arb_mat_t A, long prec) { arb_t d, e; arb_ptr * a; long i, j, m, n, r, row, col; int result; m = arb_mat_nrows(A); n = arb_mat_ncols(A); result = 1; if (m == 0 || n == 0) return result; arb_mat_set(LU, A); a = LU->rows; row = col = 0; for (i = 0; i < m; i++) P[i] = i; arb_init(d); arb_init(e); while (row < m && col < n) { r = arb_mat_find_pivot_partial(LU, row, m, col); if (r == -1) { result = 0; break; } else if (r != row) arb_mat_swap_rows(LU, P, row, r); arb_set(d, a[row] + col); for (j = row + 1; j < m; j++) { arb_div(e, a[j] + col, d, prec); arb_neg(e, e); _arb_vec_scalar_addmul(a[j] + col, a[row] + col, n - col, e, prec); arb_zero(a[j] + col); arb_neg(a[j] + row, e); } row++; col++; } arb_clear(d); arb_clear(e); return result; }
int _spd_solve(arb_mat_t X, const arb_mat_t A, const arb_mat_t B, slong prec) { slong n, m; int result; arb_mat_t L; n = arb_mat_nrows(A); m = arb_mat_ncols(X); if (n == 0 || m == 0) return 1; n = arb_mat_nrows(A); arb_mat_init(L, n, n); result = arb_mat_cho(L, A, prec); if (result) { arb_mat_solve_cho_precomp(X, L, B, prec); } arb_mat_clear(L); return result; }
int arb_mat_contains(const arb_mat_t mat1, const arb_mat_t mat2) { slong i, j; if ((arb_mat_nrows(mat1) != arb_mat_nrows(mat2)) || (arb_mat_ncols(mat1) != arb_mat_ncols(mat2))) return 0; for (i = 0; i < arb_mat_nrows(mat1); i++) for (j = 0; j < arb_mat_ncols(mat1); j++) if (!arb_contains(arb_mat_entry(mat1, i, j), arb_mat_entry(mat2, i, j))) return 0; return 1; }
int arb_mat_approx_solve(arb_mat_t X, const arb_mat_t A, const arb_mat_t B, slong prec) { int result; slong n, m, *perm; arb_mat_t LU; n = arb_mat_nrows(A); m = arb_mat_ncols(X); if (n == 0 || m == 0) return 1; perm = _perm_init(n); arb_mat_init(LU, n, n); result = arb_mat_approx_lu(perm, LU, A, prec); if (result) arb_mat_approx_solve_lu_precomp(X, perm, LU, B, prec); arb_mat_clear(LU); _perm_clear(perm); return result; }
void arb_mat_bound_inf_norm(mag_t b, const arb_mat_t A) { slong i, j, r, c; mag_t s, t; r = arb_mat_nrows(A); c = arb_mat_ncols(A); mag_zero(b); if (r == 0 || c == 0) return; mag_init(s); mag_init(t); for (i = 0; i < r; i++) { mag_zero(s); for (j = 0; j < c; j++) { arb_get_mag(t, arb_mat_entry(A, i, j)); mag_add(s, s, t); } mag_max(b, b, s); } mag_clear(s); mag_clear(t); }
void arb_mat_zero(arb_mat_t mat) { slong i, j; for (i = 0; i < arb_mat_nrows(mat); i++) for (j = 0; j < arb_mat_ncols(mat); j++) arb_zero(arb_mat_entry(mat, i, j)); }
void arb_mat_L2norm(arb_t out, const arb_mat_t in, slong prec) { int nrows = arb_mat_nrows(in); int ncols = arb_mat_ncols(in); arb_zero(out); for(int i = 0; i < nrows; i++) { for(int j = 0; j < ncols; j++) { arb_addmul(out, arb_mat_entry(in, i, j), arb_mat_entry(in, i, j), prec); } } arb_sqrtpos(out, out, prec); }
void arb_mat_sub(arb_mat_t res, const arb_mat_t mat1, const arb_mat_t mat2, slong prec) { slong i, j; for (i = 0; i < arb_mat_nrows(mat1); i++) for (j = 0; j < arb_mat_ncols(mat1); j++) arb_sub(arb_mat_entry(res, i, j), arb_mat_entry(mat1, i, j), arb_mat_entry(mat2, i, j), prec); }
void arb_mat_ones(arb_mat_t mat) { slong R, C, i, j; R = arb_mat_nrows(mat); C = arb_mat_ncols(mat); for (i = 0; i < R; i++) for (j = 0; j < C; j++) arb_one(arb_mat_entry(mat, i, j)); }
int arb_mat_is_triu(const arb_mat_t A) { slong i, j, n, m; n = arb_mat_nrows(A); m = arb_mat_ncols(A); for (i = 1; i < n; i++) for (j = 0; j < FLINT_MIN(i, m); j++) if (!arb_is_zero(arb_mat_entry(A, i, j))) return 0; return 1; }
void arb_mat_print_sage_float(const arb_mat_t A) { int nrows = arb_mat_nrows(A); int ncols = arb_mat_ncols(A); printf("["); for(int j = 0; j < nrows; j++) { printf("["); for(int k = 0; k < ncols; k++) { double x = arf_get_d(arb_midref(arb_mat_entry(A, j, k)), ARF_RND_NEAR); printf("%e", x); if(k < nrows - 1) printf(", "); } printf("],\n"); } printf("]\n"); }
void arb_mat_mul(arb_mat_t C, const arb_mat_t A, const arb_mat_t B, slong prec) { if (flint_get_num_threads() > 1 && ((double) arb_mat_nrows(A) * (double) arb_mat_nrows(B) * (double) arb_mat_ncols(B) * (double) prec > 100000)) { arb_mat_mul_threaded(C, A, B, prec); } else { arb_mat_mul_classical(C, A, B, prec); } }
int arb_mat_inv(arb_mat_t X, const arb_mat_t A, slong prec) { if (X == A) { int r; arb_mat_t T; arb_mat_init(T, arb_mat_nrows(A), arb_mat_ncols(A)); r = arb_mat_inv(T, A, prec); arb_mat_swap(T, X); arb_mat_clear(T); return r; } arb_mat_one(X); return arb_mat_solve(X, A, X, prec); }
void arb_mat_solve_cho_precomp(arb_mat_t X, const arb_mat_t L, const arb_mat_t B, slong prec) { slong i, j, c, n, m; n = arb_mat_nrows(X); m = arb_mat_ncols(X); arb_mat_set(X, B); for (c = 0; c < m; c++) { /* solve Ly = b */ for (i = 0; i < n; i++) { for (j = 0; j < i; j++) { arb_submul(arb_mat_entry(X, i, c), arb_mat_entry(L, i, j), arb_mat_entry(X, j, c), prec); } arb_div(arb_mat_entry(X, i, c), arb_mat_entry(X, i, c), arb_mat_entry(L, i, i), prec); } /* solve Ux = y */ for (i = n - 1; i >= 0; i--) { for (j = i + 1; j < n; j++) { arb_submul(arb_mat_entry(X, i, c), arb_mat_entry(L, j, i), arb_mat_entry(X, j, c), prec); } arb_div(arb_mat_entry(X, i, c), arb_mat_entry(X, i, c), arb_mat_entry(L, i, i), prec); } } }
void arb_mat_frobenius_norm(arb_t res, const arb_mat_t A, slong prec) { slong i, j, r, c; r = arb_mat_nrows(A); c = arb_mat_ncols(A); arb_zero(res); if (r == 0 || c == 0) return; for (i = 0; i < r; i++) { for (j = 0; j < c; j++) { arb_srcptr x = arb_mat_entry(A, i, j); arb_addmul(res, x, x, prec); } } arb_sqrtpos(res, res, prec); }
void arb_mat_exp(arb_mat_t B, const arb_mat_t A, slong prec) { slong i, j, dim, wp, N, q, r; mag_t norm, err; arb_mat_t T; dim = arb_mat_nrows(A); if (dim != arb_mat_ncols(A)) { flint_printf("arb_mat_exp: a square matrix is required!\n"); abort(); } if (dim == 0) { return; } else if (dim == 1) { arb_exp(arb_mat_entry(B, 0, 0), arb_mat_entry(A, 0, 0), prec); return; } wp = prec + 3 * FLINT_BIT_COUNT(prec); mag_init(norm); mag_init(err); arb_mat_init(T, dim, dim); arb_mat_bound_inf_norm(norm, A); if (mag_is_zero(norm)) { arb_mat_one(B); } else { q = pow(wp, 0.25); /* wanted magnitude */ if (mag_cmp_2exp_si(norm, 2 * wp) > 0) /* too big */ r = 2 * wp; else if (mag_cmp_2exp_si(norm, -q) < 0) /* tiny, no need to reduce */ r = 0; else r = FLINT_MAX(0, q + MAG_EXP(norm)); /* reduce to magnitude 2^(-r) */ arb_mat_scalar_mul_2exp_si(T, A, -r); mag_mul_2exp_si(norm, norm, -r); N = _arb_mat_exp_choose_N(norm, wp); mag_exp_tail(err, norm, N); _arb_mat_exp_taylor(B, T, N, wp); for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) arb_add_error_mag(arb_mat_entry(B, i, j), err); for (i = 0; i < r; i++) { arb_mat_mul(T, B, B, wp); arb_mat_swap(T, B); } for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) arb_set_round(arb_mat_entry(B, i, j), arb_mat_entry(B, i, j), prec); } mag_clear(norm); mag_clear(err); arb_mat_clear(T); }
void arb_mat_inv_cho_precomp(arb_mat_t X, const arb_mat_t L, slong prec) { slong n; if (arb_mat_nrows(X) != arb_mat_nrows(L) || arb_mat_ncols(X) != arb_mat_ncols(L)) { flint_printf("arb_mat_inv_cho_precomp: incompatible dimensions\n"); abort(); } if (arb_mat_is_empty(L)) return; n = arb_mat_nrows(L); if (n == 1) { arb_inv(arb_mat_entry(X, 0, 0), arb_mat_entry(L, 0, 0), prec); _arb_sqr(arb_mat_entry(X, 0, 0), arb_mat_entry(X, 0, 0), prec); return; } if (X == L) { flint_printf("arb_mat_inv_cho_precomp: unsupported aliasing\n"); abort(); } /* invert a 2x2 or larger matrix given its L * L^T decomposition */ { slong i, j, k; arb_struct *s; arb_mat_zero(X); s = _arb_vec_init(n); for (i = 0; i < n; i++) { arb_inv(s + i, arb_mat_entry(L, i, i), prec); } for (j = n-1; j >= 0; j--) { for (i = j; i >= 0; i--) { if (i == j) { arb_set(arb_mat_entry(X, i, j), s + i); } else { arb_zero(arb_mat_entry(X, i, j)); } for (k = i + 1; k < n; k++) { arb_submul(arb_mat_entry(X, i, j), arb_mat_entry(L, k, i), arb_mat_entry(X, k, j), prec); } arb_div(arb_mat_entry(X, i, j), arb_mat_entry(X, i, j), arb_mat_entry(L, i, i), prec); arb_set(arb_mat_entry(X, j, i), arb_mat_entry(X, i, j)); } } _arb_vec_clear(s, n); } }
int main() { slong iter; flint_rand_t state; flint_printf("mul_entrywise...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_mat_t A, B, C; arb_mat_t a, b, c, d; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); m = n_randint(state, 10); n = n_randint(state, 10); fmpq_mat_init(A, m, n); fmpq_mat_init(B, m, n); fmpq_mat_init(C, m, n); arb_mat_init(a, m, n); arb_mat_init(b, m, n); arb_mat_init(c, m, n); arb_mat_init(d, m, n); fmpq_mat_randtest(A, state, qbits1); fmpq_mat_randtest(B, state, qbits2); _fmpq_mat_mul_entrywise(C, A, B); arb_mat_set_fmpq_mat(a, A, rbits1); arb_mat_set_fmpq_mat(b, B, rbits2); arb_mat_mul_entrywise(c, a, b, rbits3); if (!arb_mat_contains_fmpq_mat(c, C)) { flint_printf("FAIL\n\n"); flint_printf("m = %wd, n = %wd, bits3 = %wd\n", m, n, rbits3); flint_printf("A = "); fmpq_mat_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_mat_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_mat_print(C); flint_printf("\n\n"); flint_printf("a = "); arb_mat_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_mat_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_mat_printd(c, 15); flint_printf("\n\n"); abort(); } /* test aliasing with a */ if (arb_mat_nrows(a) == arb_mat_nrows(c) && arb_mat_ncols(a) == arb_mat_ncols(c)) { arb_mat_set(d, a); arb_mat_mul_entrywise(d, d, b, rbits3); if (!arb_mat_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); abort(); } } /* test aliasing with b */ if (arb_mat_nrows(b) == arb_mat_nrows(c) && arb_mat_ncols(b) == arb_mat_ncols(c)) { arb_mat_set(d, b); arb_mat_mul_entrywise(d, a, d, rbits3); if (!arb_mat_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); abort(); } } fmpq_mat_clear(A); fmpq_mat_clear(B); fmpq_mat_clear(C); arb_mat_clear(a); arb_mat_clear(b); arb_mat_clear(c); arb_mat_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }