-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfdist.C
117 lines (96 loc) · 2.31 KB
/
fdist.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
/*
* fdist.C
*
* Distribution of the Farey Numbers on the unit interval
* AKA the Minkowski measure or multi-fractal measure.
*
* Show the Mellin transform.
* See also hardy.C for the singular Poisson kernel.
*
* Linas October 2004
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "Farey.h"
#include "FareyTree.h"
#include "brat.h"
static int nbins = 0;
static double * bin = NULL;
static double * logs = NULL;
static void make_bins(int _nbins, int depth)
{
int i;
nbins = _nbins;
int max = 1 << depth;
FareyIterator fi;
bin = (double *) malloc (nbins * sizeof (double));
for (i=0; i<nbins; i++)
{
bin[i] = 0.0;
}
bin[0] = 1.0;
bin[nbins-1] = 1.0;
/* Compute the distribution by bining */
int cnt = 2;
for (i=0; i<max; i++)
{
int n,d;
fi.GetNextFarey (&n, &d);
// GetNextDyadic (&n, &d);
double x = ((double) n)/ ((double) d);
x *= nbins;
int ib = (int) x;
bin [ib] += 1.0;
cnt ++;
}
/* now, renormalize */
for (i=0; i<nbins; i++)
{
bin[i] /= ((double) cnt);
}
ContinuedFraction f;
/* Cache of precomputed values */
logs = (double *) malloc (nbins * sizeof (double));
for (int i=0; i<nbins; i++)
{
/* x is the midpoint of the bin */
double x = ((double) 2*i+1) / ((double) 2*nbins);
/* Likewise, the midpoint */
f.SetRatio (2*i+1, 2*nbins);
double far = f.ToFarey ();
logs[i] = log(far);
if (far < 1.0e10) logs[i] = log(0.5) / x;
}
}
// Compute the Mellin transform
static void mellin_c (double re_q, double im_q, double *prep, double *pimp)
{
/* Compute the integral of the distribution */
double re_gral = 0.0;
double im_gral = 0.0;
for (int i=1; i<nbins; i++)
{
// double x = ((double) i) / ((double) nbins);
// double lgx = log(x);
double lgx = logs[i];
double r = exp (re_q * lgx);
double re = r * cos(im_q * lgx);
double im = r * sin(im_q * lgx);
re_gral += re * bin[i];
im_gral += im * bin[i];
}
*prep = re_gral;
*pimp = im_gral;
}
static double bincount_series (double re_q, double im_q, int itermax, double param)
{
if (0 == nbins) make_bins (itermax, 20);
double rep, imp;
mellin_c (re_q, im_q, &rep, &imp);
// return sqrt (rep*rep+imp*imp);
// return rep;
return (atan2 (imp,rep)+M_PI)/(2.0*M_PI);
}
DECL_MAKE_HEIGHT(bincount_series);
/* --------------------------- END OF LIFE ------------------------- */