void arb_fib_fmpz(arb_t f, const fmpz_t n, slong prec) { arb_t t, u; slong wp, sign, i; if (fmpz_sgn(n) < 0) { fmpz_t m; fmpz_init(m); fmpz_neg(m, n); arb_fib_fmpz(f, m, prec); if (fmpz_is_even(m)) arb_neg(f, f); fmpz_clear(m); return; } if (fmpz_cmp_ui(n, 4) <= 0) { ulong x = fmpz_get_ui(n); arb_set_ui(f, x - (x > 1)); return; } wp = ARF_PREC_ADD(prec, 3 * fmpz_bits(n)); arb_init(u); arb_init(t); arb_set_ui(f, UWORD(1)); arb_set_ui(u, UWORD(1)); sign = -1; for (i = fmpz_flog_ui(n, UWORD(2)) - 1; i > 0; i--) { arb_mul(t, f, f, wp); arb_add(f, f, u, wp); arb_mul_2exp_si(f, f, -1); arb_mul(f, f, f, wp); arb_mul_2exp_si(f, f, 1); arb_submul_ui(f, t, 3, wp); arb_sub_si(f, f, 2 * sign, wp); arb_mul_ui(u, t, 5, wp); arb_add_si(u, u, 2 * sign, wp); sign = 1; if (fmpz_tstbit(n, i)) { arb_set(t, f); arb_add(f, f, u, wp); arb_mul_2exp_si(f, f, -1); arb_mul_2exp_si(t, t, 1); arb_add(u, f, t, wp); sign = -1; } } if (fmpz_tstbit(n, 0)) { arb_add(f, f, u, wp); arb_mul_2exp_si(f, f, -1); arb_mul(f, f, u, wp); arb_sub_si(f, f, sign, prec); } else { arb_mul(f, f, u, prec); } arb_clear(u); arb_clear(t); }
int main() { slong iter; flint_rand_t state; flint_printf("sub_si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000; iter++) { arb_t a, b, c, d; slong x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); x = z_randtest(state); prec = 2 + n_randint(state, 2000); arb_set_si(b, x); arb_sub_si(c, a, x, prec); arb_sub(d, a, b, prec); if (!arb_equal(c, d)) { flint_printf("FAIL\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_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); } /* aliasing */ for (iter = 0; iter < 10000; iter++) { arb_t a, b, c; slong x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); x = z_randtest(state); prec = 2 + n_randint(state, 2000); arb_set_si(b, x); arb_sub_si(c, a, x, prec); arb_sub_si(a, a, x, prec); if (!arb_equal(a, c)) { 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"); flint_printf("c = "); arb_print(c); flint_printf("\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 gamma_rate_mixture_summarize( arb_ptr rate_mix_prior, arb_ptr rate_mix_rates, arb_ptr rate_mix_expect, const gamma_rate_mixture_t x, enum rate_mixture_mode mode, slong prec) { slong i; arb_ptr r; arb_t p, q; arb_init(p); arb_init(q); arb_set_d(p, x->invariable_prior); arb_sub_si(q, p, 1, prec); arb_neg(q, q); /* the expectation is designed to be 1 */ arb_one(rate_mix_expect); /* probabilities corresponding to gamma rate categories */ for (i = 0; i < x->gamma_categories; i++) { r = rate_mix_prior + i; arb_div_si(r, q, x->gamma_categories, prec); } /* optional probability corresponding to the invariable category */ if (x->invariable_prior) { r = rate_mix_prior + x->gamma_categories; arb_set(r, p); } /* set the discretized gamma rates */ { arb_t s; arb_init(s); arb_set_d(s, x->gamma_shape); if (mode == RATE_MIXTURE_GAMMA) { gamma_rates( rate_mix_rates, x->gamma_categories, s, prec); } else if (mode == RATE_MIXTURE_GAMMA_MEDIAN) { normalized_median_gamma_rates( rate_mix_rates, x->gamma_categories, s, prec); } else { abort(); /* assert */ } arb_clear(s); } /* normalize the rates to account for a possible invariable category */ for (i = 0; i < x->gamma_categories; i++) { r = rate_mix_rates + i; arb_div(r, r, q, prec); } arb_clear(p); arb_clear(q); }