1 /*
2     Copyright (C) 2015 Fredrik Johansson
3 
4     This file is part of Arb.
5 
6     Arb is free software: you can redistribute it and/or modify it under
7     the terms of the GNU Lesser General Public License (LGPL) as published
8     by the Free Software Foundation; either version 2.1 of the License, or
9     (at your option) any later version.  See <http://www.gnu.org/licenses/>.
10 */
11 
12 #include "acb.h"
13 #include "acb_poly.h"
14 
15 void
_arb_const_zeta_minus_one_eval(arb_t y,slong prec)16 _arb_const_zeta_minus_one_eval(arb_t y, slong prec)
17 {
18     acb_struct z[2];
19     acb_t s, a;
20     acb_init(z + 0);
21     acb_init(z + 1);
22     acb_init(s);
23     acb_init(a);
24     acb_set_si(s, -1);
25     acb_one(a);
26     _acb_poly_zeta_cpx_series(z, s, a, 0, 2, prec + 20);
27     arb_set(y, acb_realref(z + 1));
28     acb_clear(z + 0);
29     acb_clear(z + 1);
30     acb_clear(s);
31     acb_clear(a);
32 }
33 
ARB_DEF_CACHED_CONSTANT(_arb_const_zeta_minus_one,_arb_const_zeta_minus_one_eval)34 ARB_DEF_CACHED_CONSTANT(_arb_const_zeta_minus_one, _arb_const_zeta_minus_one_eval)
35 
36 /* LogG(z) = (z-1) LogGamma(z) - zeta'(-1,z) + zeta'(-1)
37    LogG'(z) = (1/2)(-2z + 1 + log(2pi)) + (z-1) digamma(z) */
38 
39 void
40 _acb_log_barnes_g_zeta(acb_t res, const acb_t z, slong prec)
41 {
42     acb_struct t[3];
43     acb_init(t + 0);
44     acb_init(t + 1);
45     acb_init(t + 2);
46 
47     acb_set_si(t + 2, -1);
48     _acb_poly_zeta_cpx_series(t, t + 2, z, 0, 2, prec);
49 
50     _arb_const_zeta_minus_one(acb_realref(t), prec);
51     arb_zero(acb_imagref(t));
52     acb_sub(t, t, t + 1, prec);
53 
54     acb_lgamma(t + 1, z, prec);
55     acb_sub_ui(t + 2, z, 1, prec);
56     acb_addmul(t, t + 1, t + 2, prec);
57 
58     acb_set(res, t);
59 
60     acb_clear(t + 0);
61     acb_clear(t + 1);
62     acb_clear(t + 2);
63 }
64 
65 void
_acb_barnes_g_ui_rec(acb_t res,ulong n,slong prec)66 _acb_barnes_g_ui_rec(acb_t res, ulong n, slong prec)
67 {
68     acb_t t;
69     ulong k;
70 
71     acb_init(t);
72 
73     acb_one(res);
74     acb_one(t);
75 
76     for (k = 3; k < n; k++)
77     {
78         acb_mul_ui(t, t, k - 1, prec);
79         acb_mul(res, res, t, prec);
80     }
81 
82     acb_clear(t);
83 }
84 
85 void
acb_log_barnes_g(acb_t res,const acb_t z,slong prec)86 acb_log_barnes_g(acb_t res, const acb_t z, slong prec)
87 {
88     if (acb_is_int(z))
89     {
90         if (arb_is_nonpositive(acb_realref(z)))
91         {
92             acb_indeterminate(res);
93             return;
94         }
95 
96         if (arf_cmpabs_ui(arb_midref(acb_realref(z)), prec) < 0)
97         {
98             _acb_barnes_g_ui_rec(res,
99                 arf_get_si(arb_midref(acb_realref(z)), ARF_RND_DOWN), prec);
100             acb_log(res, res, prec);
101             return;
102         }
103     }
104 
105     _acb_log_barnes_g_zeta(res, z, prec);
106 }
107 
108 void
acb_barnes_g(acb_t res,const acb_t z,slong prec)109 acb_barnes_g(acb_t res, const acb_t z, slong prec)
110 {
111     int real;
112 
113     real = acb_is_real(z);
114 
115     if (acb_is_int(z))
116     {
117         if (arb_is_nonpositive(acb_realref(z)))
118         {
119             acb_zero(res);
120             return;
121         }
122 
123         if (arf_cmpabs_ui(arb_midref(acb_realref(z)), prec) < 0)
124         {
125             _acb_barnes_g_ui_rec(res,
126                 arf_get_si(arb_midref(acb_realref(z)), ARF_RND_DOWN), prec);
127             return;
128         }
129     }
130 
131     _acb_log_barnes_g_zeta(res, z, prec);
132     acb_exp(res, res, prec);
133 
134     if (real)
135         arb_zero(acb_imagref(res));
136 }
137 
138