-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathzeta.C
118 lines (100 loc) · 2.09 KB
/
zeta.C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*
* zeta.C
*
* FUNCTION:
* display binomial sums over the Riemann zeta
*
* HISTORY:
* quick hack -- Linas Vepstas October 1989
* modernize -- Linas Vepstas March 1996
* more stuff -- January 2000
* more stuff -- October 2004
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <gsl/gsl_sf_zeta.h>
#include <gsl/gsl_sf_psi.h>
#include "brat.h"
// ======================================================
// brute-force factorial function
inline long double factorial (int n)
{
int k;
long double fac = 1.0L;
for (k=2; k<=n; k++)
{
fac *= (long double) k;
}
if (0>n) fac = 0.0L;
return fac;
}
// ======================================================
// complex-valued binomial coefficent
// must have m>=0
// returns z*(z-1)*(z-2)...*(z-m+1) / m!
//
void cbinomial (double zre, double zim, int m, double *pbre, double *pbim)
{
if(0>m) return;
int k;
double bre = 1.0;
double bim = 0.0;
long double fac = 1.0L;
for (k=1; k<=m; k++)
{
double tmp = zre * bre - zim*bim;
bim = zre * bim + zim * bre;
bre = tmp;
zre -= 1.0;
fac *= (long double) k;
}
bre /= fac;
bim /= fac;
*pbre = bre;
*pbim = bim;
}
static void zeta_series_c (double re_q, double im_q, double *prep, double *pimp)
{
int i;
*prep = 0.0;
*pimp = 0.0;
double rep = 0.0;
double imp = 0.0;
for (i=2; i<40; i++)
{
double bre, bim;
cbinomial (re_q, im_q, i, &bre, &bim);
double zetam1 = gsl_sf_zetam1 (i);
if (i%2)
{
rep -= bre * zetam1;
imp -= bim * zetam1;
}
else
{
rep += bre * zetam1;
imp += bim * zetam1;
}
}
*prep = rep;
*pimp = imp;
}
static double zeta_series (double re_q, double im_q, int itermax, double param)
{
double rep, imp;
double re_z, im_z;
double deno = re_q - 1.0;
deno = deno*deno + im_q*im_q;
deno = 1.0/deno;
re_z = 2.0*im_q* deno;
im_z = re_q*re_q + im_q*im_q - 1.0;
im_z *= deno;
zeta_series_c (re_z, im_z, &rep, &imp);
// return sqrt (rep*rep+imp*imp);
// return rep;
// return imp;
return (atan2 (imp,rep)+M_PI)/(2.0*M_PI);
}
DECL_MAKE_HEIGHT(zeta_series);
/* --------------------------- END OF LIFE ------------------------- */