void _arb_poly_sqrt_series(arb_ptr g, arb_srcptr h, long hlen, long len, long prec) { hlen = FLINT_MIN(hlen, len); if (hlen == 1) { arb_sqrt(g, h, prec); _arb_vec_zero(g + 1, len - 1); } else if (len == 2) { arb_sqrt(g, h, prec); arb_div(g + 1, h + 1, h, prec); arb_mul(g + 1, g + 1, g, prec); arb_mul_2exp_si(g + 1, g + 1, -1); } else { arb_ptr t; t = _arb_vec_init(len); _arb_poly_rsqrt_series(t, h, hlen, len, prec); _arb_poly_mullow(g, t, len, h, hlen, len, prec); _arb_vec_clear(t, len); } }
void arb_root_ui(arb_t res, const arb_t x, ulong k, slong prec) { if (k == 0) { arb_indeterminate(res); } else if (k == 1) { arb_set_round(res, x, prec); } else if (k == 2) { arb_sqrt(res, x, prec); } else if (k == 4) { arb_sqrt(res, x, prec + 2); arb_sqrt(res, res, prec); } else { if (k > 50 || prec < (WORD(1) << ((k / 8) + 8))) arb_root_ui_exp(res, x, k, prec); else arb_root_ui_algebraic(res, x, k, prec); } }
void acb_hypgeom_fresnel(acb_t res1, acb_t res2, const acb_t z, int normalized, slong prec) { slong wp; acb_t w; arb_t c; if (!acb_is_finite(z)) { if (res1 != NULL) acb_indeterminate(res1); if (res2 != NULL) acb_indeterminate(res2); return; } acb_init(w); arb_init(c); wp = prec + 8; if (normalized) { arb_const_pi(c, wp); arb_sqrt(c, c, wp); arb_mul_2exp_si(c, c, -1); acb_mul_arb(w, z, c, wp); acb_hypgeom_fresnel_erf_error(res1, res2, w, wp); } else { arb_sqrt_ui(c, 2, wp); arb_mul_2exp_si(c, c, -1); acb_mul_arb(w, z, c, wp); acb_hypgeom_fresnel_erf_error(res1, res2, w, wp); arb_const_pi(c, wp); arb_mul_2exp_si(c, c, -1); arb_sqrt(c, c, wp); if (res1 != NULL) acb_mul_arb(res1, res1, c, wp); if (res2 != NULL) acb_mul_arb(res2, res2, c, wp); } if (res1 != NULL) { acb_mul_2exp_si(res1, res1, -2); acb_set_round(res1, res1, prec); } if (res2 != NULL) { acb_mul_2exp_si(res2, res2, -2); acb_set_round(res2, res2, prec); } acb_clear(w); arb_clear(c); }
int main() { slong iter; flint_rand_t state; flint_printf("sqrt...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000; iter++) { arb_t a, b, c; slong prec = 2 + n_randint(state, 200); arb_init(a); arb_init(b); arb_init(c); arb_randtest_special(a, state, 1 + n_randint(state, 200), 100); arb_sqrt(b, a, prec); arb_mul(c, b, b, prec); if (!arb_contains(c, a)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); abort(); } arb_sqrt(a, a, prec); if (!arb_equal(a, b)) { flint_printf("FAIL: aliasing\n\n"); abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
void arb_sqrt1pm1(arb_t r, const arb_t z, slong prec) { slong magz, wp; if (arb_is_zero(z)) { arb_zero(r); return; } magz = arf_abs_bound_lt_2exp_si(arb_midref(z)); if (magz < -prec) { arb_sqrt1pm1_tiny(r, z, prec); } else { if (magz < 0) wp = prec + (-magz) + 4; else wp = prec + 4; arb_add_ui(r, z, 1, wp); arb_sqrt(r, r, wp); arb_sub_ui(r, r, 1, wp); } }
void arb_pow(arb_t z, const arb_t x, const arb_t y, slong prec) { if (arb_is_zero(y)) { arb_one(z); return; } if (arb_is_zero(x)) { if (arb_is_positive(y)) arb_zero(z); else arb_indeterminate(z); return; } if (arb_is_exact(y) && !arf_is_special(arb_midref(x))) { const arf_struct * ymid = arb_midref(y); /* small half-integer or integer */ if (arf_cmpabs_2exp_si(ymid, BINEXP_LIMIT) < 0 && arf_is_int_2exp_si(ymid, -1)) { fmpz_t e; fmpz_init(e); if (arf_is_int(ymid)) { arf_get_fmpz_fixed_si(e, ymid, 0); arb_pow_fmpz_binexp(z, x, e, prec); } else { arf_get_fmpz_fixed_si(e, ymid, -1); arb_sqrt(z, x, prec + fmpz_bits(e)); arb_pow_fmpz_binexp(z, z, e, prec); } fmpz_clear(e); return; } else if (arf_is_int(ymid) && arf_sgn(arb_midref(x)) < 0) { /* use (-x)^n = (-1)^n * x^n to avoid NaNs at least at high enough precision */ int odd = !arf_is_int_2exp_si(ymid, 1); _arb_pow_exp(z, x, 1, y, prec); if (odd) arb_neg(z, z); return; } } _arb_pow_exp(z, x, 0, y, prec); }
void arb_twobytwo_diag(arb_t u1, arb_t u2, const arb_t a, const arb_t b, const arb_t d, slong prec) { // Compute the orthogonal matrix that diagonalizes // // A = [a b] // [b d] // // This matrix will have the form // // U = [cos x , -sin x] // [sin x, cos x] // // where the diagonal matrix is U^t A U. // We set u1 = cos x, u2 = -sin x. if(arb_contains_zero(b)) { // this is not quite right (doesn't set error intervals) arb_set_ui(u1, 1); arb_set_ui(u2, 0); return; } arb_t x; arb_init(x); arb_mul(u1, b, b, prec); // u1 = b^2 arb_sub(u2, a, d, prec); // u2 = a - d arb_mul_2exp_si(u2, u2, -1); // u2 = (a - d)/2 arb_mul(u2, u2, u2, prec); // u2 = ( (a - d)/2 )^2 arb_add(u1, u1, u2, prec); // u1 = b^2 + ( (a-d)/2 )^2 arb_sqrt(u1, u1, prec); // u1 = sqrt(above) arb_mul_2exp_si(u1, u1, 1); // u1 = 2 (sqrt (above) ) arb_add(u1, u1, d, prec); // u1 += d arb_sub(u1, u1, a, prec); // u1 -= a arb_mul_2exp_si(u1, u1, -1); // u1 = (d - a)/2 + sqrt(b^2 + ( (a-d)/2 )^2) arb_mul(x, u1, u1, prec); arb_addmul(x, b, b, prec); // x = u1^2 + b^2 arb_sqrt(x, x, prec); // x = sqrt(u1^2 + b^2) arb_div(u2, u1, x, prec); arb_div(u1, b, x, prec); arb_neg(u1, u1); arb_clear(x); }
void arb_agm(arb_t z, const arb_t x, const arb_t y, long prec) { arb_t t, u, v, w; if (arb_contains_negative(x) || arb_contains_negative(y)) { arb_indeterminate(z); return; } if (arb_is_zero(x) || arb_is_zero(y)) { arb_zero(z); return; } arb_init(t); arb_init(u); arb_init(v); arb_init(w); arb_set(t, x); arb_set(u, y); while (!arb_overlaps(t, u) && !arb_contains_nonpositive(t) && !arb_contains_nonpositive(u)) { arb_add(v, t, u, prec); arb_mul_2exp_si(v, v, -1); arb_mul(w, t, u, prec); arb_sqrt(w, w, prec); arb_swap(v, t); arb_swap(w, u); } if (!arb_is_finite(t) || !arb_is_finite(u)) { arb_indeterminate(z); } else { arb_union(z, t, u, prec); } arb_clear(t); arb_clear(u); arb_clear(v); arb_clear(w); }
/* Bound for scaled Bessel function: 2/(2 pi x)^(1/2) Bound for tail of integral: 2 N (k / (pi N))^(k / 2) / (k - 2). */ void scaled_bessel_tail_bound(arb_t b, ulong k, const arb_t N, slong prec) { arb_const_pi(b, prec); arb_mul(b, b, N, prec); arb_ui_div(b, k, b, prec); arb_sqrt(b, b, prec); arb_pow_ui(b, b, k, prec); arb_mul(b, b, N, prec); arb_mul_ui(b, b, 2, prec); arb_div_ui(b, b, k - 2, prec); }
void _arb_poly_sqrt_series(arb_ptr g, arb_srcptr h, slong hlen, slong len, slong prec) { hlen = FLINT_MIN(hlen, len); while (hlen > 0 && arb_is_zero(h + hlen - 1)) hlen--; if (hlen <= 1) { arb_sqrt(g, h, prec); _arb_vec_zero(g + 1, len - 1); } else if (len == 2) { arb_sqrt(g, h, prec); arb_div(g + 1, h + 1, h, prec); arb_mul(g + 1, g + 1, g, prec); arb_mul_2exp_si(g + 1, g + 1, -1); } else if (_arb_vec_is_zero(h + 1, hlen - 2)) { arb_t t; arb_init(t); arf_set_si_2exp_si(arb_midref(t), 1, -1); _arb_poly_binomial_pow_arb_series(g, h, hlen, t, len, prec); arb_clear(t); } else { arb_ptr t; t = _arb_vec_init(len); _arb_poly_rsqrt_series(t, h, hlen, len, prec); _arb_poly_mullow(g, t, len, h, hlen, len, prec); _arb_vec_clear(t, len); } }
void arb_mat_cholesky(arb_mat_t out, const arb_mat_t in, slong prec) { int nrows = arb_mat_nrows(in); for(int j = 0; j < nrows; j++) { for(int i = j; i < nrows; i++) { arb_set(arb_mat_entry(out, i, j), arb_mat_entry(in, i, j)); for(int k = 0; k < j; k++) { arb_submul(arb_mat_entry(out, i, j), arb_mat_entry(out, i, k), arb_mat_entry(out, j, k), prec); } if(i == j) { arb_sqrt(arb_mat_entry(out, i, j), arb_mat_entry(out, i, j), prec); } else { arb_div(arb_mat_entry(out, i, j), arb_mat_entry(out, i, j), arb_mat_entry(out, j, j), prec); } } } }
void acb_dirichlet_vec_mellin_arb(acb_ptr res, const dirichlet_group_t G, const dirichlet_char_t chi, slong len, const arb_t t, slong n, slong prec) { slong k; arb_t tk, xt, stk, st; acb_ptr a; mag_t e; a = _acb_vec_init(len); acb_dirichlet_chi_vec(a, G, chi, len, prec); if (dirichlet_parity_char(G, chi)) { for (k = 2; k < len; k++) acb_mul_si(a + k, a + k, k, prec); } arb_init(tk); arb_init(xt); arb_init(st); arb_init(stk); mag_init(e); arb_sqrt(st, t, prec); arb_one(tk); arb_one(stk); for (k = 0; k < n; k++) { _acb_dirichlet_theta_argument_at_arb(xt, G->q, tk, prec); mag_tail_kexpk2_arb(e, xt, len); arb_neg(xt, xt); arb_exp(xt, xt, prec); /* TODO: reduce len */ acb_dirichlet_qseries_arb(res + k, a, xt, len, prec); acb_add_error_mag(res + k, e); acb_mul_arb(res + k, res + k, stk, prec); arb_mul(tk, tk, t, prec); arb_mul(stk, stk, st, prec); } mag_clear(e); arb_clear(xt); arb_clear(tk); arb_clear(stk); arb_clear(st); _acb_vec_clear(a, len); }
void arb_acosh(arb_t z, const arb_t x, slong prec) { if (arb_is_one(x)) { arb_zero(z); } else { arb_t t; arb_init(t); arb_mul(t, x, x, prec + 4); arb_sub_ui(t, t, 1, prec + 4); arb_sqrt(t, t, prec + 4); arb_add(t, t, x, prec + 4); arb_log(z, t, prec); arb_clear(t); } }
int _acb_modular_hilbert_class_poly(fmpz_poly_t res, slong D, const slong * qbf, slong qbf_len, slong prec) { arb_t sqrtD; arb_poly_t pol; int success; arb_init(sqrtD); arb_poly_init(pol); arb_set_si(sqrtD, -D); arb_sqrt(sqrtD, sqrtD, prec); bsplit(pol, sqrtD, qbf, 0, qbf_len, prec); success = arb_poly_get_unique_fmpz_poly(res, pol); arb_clear(sqrtD); arb_poly_clear(pol); return success; }
void arb_sqrtpos(arb_t z, const arb_t x, long prec) { if (!arb_is_finite(x)) { if (mag_is_zero(arb_radref(x)) && arf_is_pos_inf(arb_midref(x))) arb_pos_inf(z); else arb_zero_pm_inf(z); } else if (arb_contains_nonpositive(x)) { arf_t t; arf_init(t); arf_set_mag(t, arb_radref(x)); arf_add(t, arb_midref(x), t, MAG_BITS, ARF_RND_CEIL); if (arf_sgn(t) <= 0) { arb_zero(z); } else { arf_sqrt(t, t, MAG_BITS, ARF_RND_CEIL); arf_mul_2exp_si(t, t, -1); arf_set(arb_midref(z), t); arf_get_mag(arb_radref(z), t); } arf_clear(t); } else { arb_sqrt(z, x, prec); } arb_nonnegative_part(z, z, prec); }
int main() { slong iter; flint_rand_t state; flint_printf("sqrt1pm1...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 20000; iter++) { arb_t a, b, c, d; slong prec0, prec1, prec2; if (iter % 10 == 0) prec0 = 10000; else prec0 = 1000; prec1 = 2 + n_randint(state, prec0); prec2 = 2 + n_randint(state, prec0); arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_randtest_special(a, state, 1 + n_randint(state, prec0), 100); arb_randtest_special(b, state, 1 + n_randint(state, prec0), 100); arb_randtest_special(c, state, 1 + n_randint(state, prec0), 100); arb_sqrt1pm1(b, a, prec1); arb_sqrt1pm1(c, a, prec2); if (!arb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); abort(); } /* compare with sqrt */ arb_add_ui(d, a, 1, prec2); arb_sqrt(d, d, prec2); arb_sub_ui(d, d, 1, prec2); if (!arb_overlaps(c, d)) { flint_printf("FAIL: comparison with log\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); abort(); } arb_sqrt1pm1(a, a, prec1); if (!arb_overlaps(a, b)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
void acb_sqrt(acb_t y, const acb_t x, slong prec) { arb_t r, t, u; slong wp; #define a acb_realref(x) #define b acb_imagref(x) #define c acb_realref(y) #define d acb_imagref(y) if (arb_is_zero(b)) { if (arb_is_nonnegative(a)) { arb_sqrt(c, a, prec); arb_zero(d); return; } else if (arb_is_nonpositive(a)) { arb_neg(d, a); arb_sqrt(d, d, prec); arb_zero(c); return; } } if (arb_is_zero(a)) { if (arb_is_nonnegative(b)) { arb_mul_2exp_si(c, b, -1); arb_sqrt(c, c, prec); arb_set(d, c); return; } else if (arb_is_nonpositive(b)) { arb_mul_2exp_si(c, b, -1); arb_neg(c, c); arb_sqrt(c, c, prec); arb_neg(d, c); return; } } wp = prec + 4; arb_init(r); arb_init(t); arb_init(u); acb_abs(r, x, wp); arb_add(t, r, a, wp); if (arb_rel_accuracy_bits(t) > 8) { /* sqrt(a+bi) = sqrt((r+a)/2) + b/sqrt(2*(r+a))*i, r = |a+bi| */ arb_mul_2exp_si(u, t, 1); arb_sqrt(u, u, wp); arb_div(d, b, u, prec); arb_set_round(c, u, prec); arb_mul_2exp_si(c, c, -1); } else { /* sqrt(a+bi) = sqrt((r+a)/2) + (b/|b|)*sqrt((r-a)/2)*i (sign) */ arb_mul_2exp_si(t, t, -1); arb_sub(u, r, a, wp); arb_mul_2exp_si(u, u, -1); arb_sqrtpos(c, t, prec); if (arb_is_nonnegative(b)) { arb_sqrtpos(d, u, prec); } else if (arb_is_nonpositive(b)) { arb_sqrtpos(d, u, prec); arb_neg(d, d); } else { arb_sqrtpos(t, u, wp); arb_neg(u, t); arb_union(d, t, u, prec); } } arb_clear(r); arb_clear(t); arb_clear(u); #undef a #undef b #undef c #undef d }
int main() { slong iter; flint_rand_t state; flint_printf("frobenius_norm...."); fflush(stdout); flint_randinit(state); /* compare to the exact rational norm */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpq_mat_t Q; fmpq_t q; arb_mat_t A; slong n, qbits, prec; n = n_randint(state, 8); qbits = 1 + n_randint(state, 100); prec = 2 + n_randint(state, 200); fmpq_mat_init(Q, n, n); fmpq_init(q); arb_mat_init(A, n, n); fmpq_mat_randtest(Q, state, qbits); _fmpq_mat_sum_of_squares(q, Q); arb_mat_set_fmpq_mat(A, Q, prec); /* check that the arb interval contains the exact value */ { arb_t a; arb_init(a); arb_mat_frobenius_norm(a, A, prec); arb_mul(a, a, a, prec); if (!arb_contains_fmpq(a, 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("frobenius_norm(Q)^2 = \n"); fmpq_print(q); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("frobenius_norm(A)^2 = \n"); arb_printd(a, 15); flint_printf("\n\n"); flint_printf("frobenius_norm(A)^2 = \n"); arb_print(a); flint_printf("\n\n"); abort(); } arb_clear(a); } /* check that the upper bound is not less than the exact value */ { mag_t b; fmpq_t y; mag_init(b); fmpq_init(y); arb_mat_bound_frobenius_norm(b, A); mag_mul(b, b, b); mag_get_fmpq(y, b); if (fmpq_cmp(q, y) > 0) { flint_printf("FAIL (bound, 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("frobenius_norm(Q)^2 = \n"); fmpq_print(q); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("bound_frobenius_norm(A)^2 = \n"); mag_printd(b, 15); flint_printf("\n\n"); flint_printf("bound_frobenius_norm(A)^2 = \n"); mag_print(b); flint_printf("\n\n"); abort(); } mag_clear(b); fmpq_clear(y); } fmpq_mat_clear(Q); fmpq_clear(q); arb_mat_clear(A); } /* check trace(A^T A) = frobenius_norm(A)^2 */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, prec; arb_mat_t A, AT, ATA; arb_t t; prec = 2 + n_randint(state, 200); m = n_randint(state, 10); n = n_randint(state, 10); arb_mat_init(A, m, n); arb_mat_init(AT, n, m); arb_mat_init(ATA, n, n); arb_init(t); arb_mat_randtest(A, state, 2 + n_randint(state, 100), 10); arb_mat_transpose(AT, A); arb_mat_mul(ATA, AT, A, prec); arb_mat_trace(t, ATA, prec); arb_sqrt(t, t, prec); /* check the norm bound */ { mag_t low, frobenius; mag_init(low); arb_get_mag_lower(low, t); mag_init(frobenius); arb_mat_bound_frobenius_norm(frobenius, A); if (mag_cmp(low, frobenius) > 0) { flint_printf("FAIL (bound)\n", iter); flint_printf("m = %wd, n = %wd, prec = %wd\n", m, n, prec); flint_printf("\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("lower(sqrt(trace(A^T A))) = \n"); mag_printd(low, 15); flint_printf("\n\n"); flint_printf("bound_frobenius_norm(A) = \n"); mag_printd(frobenius, 15); flint_printf("\n\n"); abort(); } mag_clear(low); mag_clear(frobenius); } /* check the norm interval */ { arb_t frobenius; arb_init(frobenius); arb_mat_frobenius_norm(frobenius, A, prec); if (!arb_overlaps(t, frobenius)) { flint_printf("FAIL (overlap)\n", iter); flint_printf("m = %wd, n = %wd, prec = %wd\n", m, n, prec); flint_printf("\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("sqrt(trace(A^T A)) = \n"); arb_printd(t, 15); flint_printf("\n\n"); flint_printf("frobenius_norm(A) = \n"); arb_printd(frobenius, 15); flint_printf("\n\n"); abort(); } arb_clear(frobenius); } arb_mat_clear(A); arb_mat_clear(AT); arb_mat_clear(ATA); arb_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }