int main() { slong iter; flint_rand_t state; flint_printf("rsqrt...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000; iter++) { fmprb_t a, b, c; slong prec = 2 + n_randint(state, 200); fmprb_init(a); fmprb_init(b); fmprb_init(c); fmprb_randtest(a, state, 1 + n_randint(state, 200), 10); fmprb_rsqrt(b, a, prec); fmprb_inv(c, b, prec); fmprb_mul(c, c, c, prec); if (!fmprb_contains(c, a)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); fmprb_print(a); flint_printf("\n\n"); flint_printf("b = "); fmprb_print(b); flint_printf("\n\n"); flint_printf("c = "); fmprb_print(c); flint_printf("\n\n"); abort(); } fmprb_rsqrt(a, a, prec); if (!fmprb_equal(a, b)) { flint_printf("FAIL: aliasing\n\n"); abort(); } fmprb_clear(a); fmprb_clear(b); fmprb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
void bound_I(fmprb_ptr I, const fmprb_t A, const fmprb_t B, const fmprb_t C, long len, long wp) { long k; fmprb_t D, Dk, L, T, Bm1; fmprb_init(D); fmprb_init(Dk); fmprb_init(Bm1); fmprb_init(T); fmprb_init(L); fmprb_sub_ui(Bm1, B, 1, wp); fmprb_one(L); /* T = 1 / (A^Bm1 * Bm1) */ fmprb_inv(T, A, wp); fmprb_pow(T, T, Bm1, wp); fmprb_div(T, T, Bm1, wp); if (len > 1) { fmprb_log(D, A, wp); fmprb_add(D, D, C, wp); fmprb_mul(D, D, Bm1, wp); fmprb_set(Dk, D); } for (k = 0; k < len; k++) { if (k > 0) { fmprb_mul_ui(L, L, k, wp); fmprb_add(L, L, Dk, wp); fmprb_mul(Dk, Dk, D, wp); } fmprb_mul(I + k, L, T, wp); fmprb_div(T, T, Bm1, wp); } fmprb_clear(D); fmprb_clear(Dk); fmprb_clear(Bm1); fmprb_clear(T); fmprb_clear(L); }
void gamma_stirling_eval_fmprb(fmprb_t s, const fmprb_t z, long nterms, int digamma, long prec) { fmprb_t b, t, logz, zinv, zinv2; fmpr_t err; long k, term_prec; double z_mag, term_mag; fmprb_init(b); fmprb_init(t); fmprb_init(logz); fmprb_init(zinv); fmprb_init(zinv2); fmprb_log(logz, z, prec); fmprb_inv(zinv, z, prec); nterms = FLINT_MAX(nterms, 1); fmprb_zero(s); if (nterms > 1) { fmprb_mul(zinv2, zinv, zinv, prec); z_mag = fmpr_get_d(fmprb_midref(logz), FMPR_RND_UP) * 1.44269504088896; for (k = nterms - 1; k >= 1; k--) { term_mag = bernoulli_bound_2exp_si(2 * k); term_mag -= (2 * k - 1) * z_mag; term_prec = prec + term_mag; term_prec = FLINT_MIN(term_prec, prec); term_prec = FLINT_MAX(term_prec, 10); if (prec > 2000) { fmprb_set_round(t, zinv2, term_prec); fmprb_mul(s, s, t, term_prec); } else fmprb_mul(s, s, zinv2, term_prec); gamma_stirling_coeff(b, k, digamma, term_prec); fmprb_add(s, s, b, term_prec); } if (digamma) fmprb_mul(s, s, zinv2, prec); else fmprb_mul(s, s, zinv, prec); } /* remainder bound */ fmpr_init(err); gamma_stirling_bound_fmprb(err, z, digamma ? 1 : 0, 1, nterms); fmprb_add_error_fmpr(s, err); fmpr_clear(err); if (digamma) { fmprb_neg(s, s); fmprb_mul_2exp_si(zinv, zinv, -1); fmprb_sub(s, s, zinv, prec); fmprb_add(s, s, logz, prec); } else { /* (z-0.5)*log(z) - z + log(2*pi)/2 */ fmprb_one(t); fmprb_mul_2exp_si(t, t, -1); fmprb_sub(t, z, t, prec); fmprb_mul(t, logz, t, prec); fmprb_add(s, s, t, prec); fmprb_sub(s, s, z, prec); fmprb_const_log_sqrt2pi(t, prec); fmprb_add(s, s, t, prec); } fmprb_clear(t); fmprb_clear(b); fmprb_clear(zinv); fmprb_clear(zinv2); fmprb_clear(logz); }
int main() { long iter; flint_rand_t state; printf("digamma...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000; iter++) { fmprb_t a, b, c; long prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; fmprb_init(a); fmprb_init(b); fmprb_init(c); fmprb_randtest_precise(a, state, 1 + n_randint(state, 1000), 10); fmprb_digamma(b, a, prec1); fmprb_digamma(c, a, prec2); if (!fmprb_overlaps(b, c)) { printf("FAIL: overlap\n\n"); printf("a = "); fmprb_print(a); printf("\n\n"); printf("b = "); fmprb_print(b); printf("\n\n"); printf("c = "); fmprb_print(c); printf("\n\n"); abort(); } fmprb_set(c, a); fmprb_digamma(c, c, prec2); if (!fmprb_overlaps(b, c)) { printf("FAIL: aliasing\n\n"); printf("a = "); fmprb_print(a); printf("\n\n"); printf("b = "); fmprb_print(b); printf("\n\n"); printf("c = "); fmprb_print(c); printf("\n\n"); abort(); } /* check digamma(z+1) = digamma(z) + 1/z */ fmprb_inv(c, a, prec1); fmprb_add(b, b, c, prec1); fmprb_add_ui(c, a, 1, prec1); fmprb_digamma(c, c, prec1); if (!fmprb_overlaps(b, c)) { printf("FAIL: functional equation\n\n"); printf("a = "); fmprb_print(a); printf("\n\n"); printf("b = "); fmprb_print(b); printf("\n\n"); printf("c = "); fmprb_print(c); printf("\n\n"); abort(); } fmprb_clear(a); fmprb_clear(b); fmprb_clear(c); } flint_randclear(state); flint_cleanup(); printf("PASS\n"); return EXIT_SUCCESS; }