-
Notifications
You must be signed in to change notification settings - Fork 0
/
prob_saveas_tikz.m
118 lines (112 loc) · 4.07 KB
/
prob_saveas_tikz.m
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
% Copyright 2021, C. Minz. BSD 3-Clause License.
function prob_saveas_tikz( filename, hits, runs, eps, constraints )
% calculate probabilities:
posetcount = length( hits ) - 1;
prob = double( hits( 1 : posetcount ) ) / double( runs );
if nargin < 5
constraints = [];
end
% approximate by fractions:
if eps <= 0
% use RAT function:
threshold = 0.105;
nom_limit = 6 * posetcount;
minprob = min( prob );
[ nom, denom ] = rat( prob / minprob, threshold );
nom_oor = find( nom > nom_limit );
if ~isempty( nom_oor )
nom2 = round( prob / minprob );
nom( nom_oor ) = nom2( nom_oor );
denom( nom_oor ) = 1;
end
[ sorted_nom, I ] = sort( nom, 'descend' );
sorted_denom = denom( I );
denomprod = 1;
for i = 1 : posetcount
f_last = 1;
f_power = 1;
for f = factor( sorted_denom( i ) )
if f_last ~= f
f_power = f;
else
f_power = f_power * f;
end
if mod( denomprod, f_power ) ~= 0
maxnom = max( denomprod * f * ( sorted_nom ./ sorted_denom ) );
if maxnom < nom_limit
denomprod = denomprod * f;
end
end
f_last = f;
end
end
nom = round( denomprod * ( nom ./ denom ) );
else
% use denominator sequence:
cdenom = posetcount;
cdenom_max = posetcount * 1000000;
factors = [ 1000, 100, 10, 5, 2, 1.5, 1.1, 1 ];
fi = 1;
h = waitbar( 0, sprintf( 'Denominator: %d', cdenom ) );
j = 1;
while 1
cdenom = factors( fi ) * cdenom + 1; % increase denominator
nom = round( cdenom * prob );
j = j + 1;
if mod( j, 10 )
waitbar( 0, h, sprintf( 'Denominator: %d, Approx: %f', ...
cdenom, max( abs( prob - nom / cdenom ) ) ) );
end
if ( sum( abs( prob - nom / cdenom ) >= eps ) == 0 ) && ( sum( nom == 0 ) == 0 )
if fi < length( factors )
cdenom_max = cdenom;
cdenom = round( cdenom / factors( fi ) );
fi = fi + 1;
else
% test constraints:
if ~isempty( constraints )
nom = nom * transpose( constraints );
end
% get correct approximation and quit if still good enough:
if cdenom >= cdenom_max
break
elseif nom ~= round( nom )
continue
elseif abs( prob - nom / sum( nom ) ) < eps
break
end
end
end
end
close( h );
end
% apply constraints and cancel fractions:
if ~isempty( constraints )
nom = round( nom * transpose( constraints ) );
end
for c = factor( min( nom( 1 ), 27720 ) )
if sum( mod( nom, c ) ) == 0
nom = nom / c;
end
end
cdenom = sum( nom );
% save to tikz lines:
fileID = fopen( filename, 'w' );
for i = 1 : posetcount
fprintf( fileID, '\\node[prob] at (poset%02d) {%0.4f};\n', ...
i, prob( i ) );
end
for i = 1 : posetcount
fprintf( fileID, '\\node[probratio] at (poset%02d) {%d};\n', ...
i, nom( i ) );
end
for i = 1 : posetcount
fprintf( fileID, '\\node[probapprox] at (poset%02d) {%0.4f};\n', ...
i, nom( i ) / cdenom );
end
fprintf( fileID, replace( sprintf( '\\\\node[samplesize] at (posetsummary) {\\\\num{%0.1E}};\\n', ...
runs ), '+0', '' ) );
fprintf( fileID, '\\node[denom] at (posetsummary) {%d};\n', ...
cdenom );
fclose( fileID );
end