-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathtest_roundit.m
137 lines (118 loc) · 3.38 KB
/
test_roundit.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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
function test_roundit
%TEST_ROUNDIT Test the roundit function.
clear roundit options assert_eq
n = 0;
rng(1)
y = roundit(pi); % Check no options case.
assert_eq(y,3)
y = roundit(pi,[]); % Check empty options case.
assert_eq(y,3)
options.flip = 0;
options.round = 1;
A = [0 1.1 1.5; 1.9 2.4 0.5];
y = roundit(A,options);
assert_eq(y,[0 1 2; 2 2 0])
y = roundit(A',options);
assert_eq(y,[0 1 2; 2 2 0]')
A = [0 -1.1 -1.5; -1.9 -2.4 -0.5];
y = roundit(A,options);
assert_eq(y,[0 -1 -2; -2 -2 0])
options.round = 2;
A = [0 1.1 1.5; 1.9 2.4 0.5];
y = roundit(A,options);
assert_eq(y,[0 2 2; 2 3 1])
A = [0 -1.1 -1.5; -1.9 -2.4 -0.5];
options.round = 2;
y = roundit(A,options);
assert_eq(y,[0 -1 -1; -1 -2 0])
options.round = 3;
A = [0 1.1 1.5; 1.9 2.4 0.5];
y = roundit(A,options);
assert_eq(y,[0 1 1; 1 2 0])
options.round = 3;
A = [0 -1.1 -1.5; -1.9 -2.4 -0.5];
y = roundit(A,options);
assert_eq(y,[0 -2 -2; -2 -3 -1])
options.round = 4;
A = [0 -1.1 -1.5; -2.9 -2 -0.5; 0.5 1.5 3];
y = roundit(A,options);
assert_eq(y,[0 -1 -1; -2 -2 0; 0 1 3])
options.round = 5;
tol = 1e-6;
A = [0 1+tol 1-tol; -tol -1-tol -1+tol];
y = roundit(A,options);
assert_eq(y,[0 1 1; 0 -1 -1]) % Test succeeds with high probability.
options.round = 5;
A = [-0.5 0.5]; Y = [];
for i = 1:1e3
Y = [Y; roundit(A,options)];
end
assert_eq(true, norm(mean(Y) - 0.5*[-1 1]) <= 5e-2)
z = 2; nsamp = 1e4;
options.round = 5;
for h = [0.1 0.2 0.3 0.4 0.6 0.7 0.8 0.9]
x = z + h;
a = 0; b = 0;
for i = 1:nsamp
y = roundit(x,options);
if y == z
a = a + 1;
elseif y == z + 1
b = b + 1;
else
error('Unknown rounding.')
end
end
assert_eq(true, (abs( a/nsamp-(1-h) ) <= 5e-2));
assert_eq(true, (abs( b/nsamp - h ) <= 5e-2));
end
options.round = 6;
A = [0.2 0.5 0.9]; Y = [];
for i = 1:1e4
Y = [Y; roundit(A,options)];
end
ratio = sum(Y(:) == 1)/ sum(Y(:) == 0);
assert_eq(true, abs(ratio-1) < 0.1) % Heuristic test.
% Test bit flip case.
options.round = 1;
m = 500;
A = 15*rand(m);
y1 = roundit(A,options); % Now y1 is an integer matrix.
options.flip = 1;
options.params(1) = 4; % Integers with modulus on [0,15].
y2 = roundit(y1,options); % No rounding, but bits flipped.
prop_changed = sum(sum(y1 ~= y2)) / m^2;
assert_eq(true, abs(prop_changed - 0.5) < 5e-2) % Heuristic test.
options.p = 0.1;
y2 = roundit(y1,options); % No rounding, but bits flipped.
prop_changed = sum(sum(y1 ~= y2)) / m^2;
assert_eq(true, abs(prop_changed - options.p) < 5e-2) % Heuristic test.
% Make sure zero is bit-flipped correctly.
options = rmfield(options,'p');
options.flip = 1; nsamp = 1e4;
j = 0; options.params(1) = 3; options.p = 0.5;
for i = 1:nsamp
y = roundit(0,options);
if y ~= 0, j = j +1; end
end
assert_eq(true, abs(j / nsamp - options.p) <= 1e-2)
% Test custom random number generator function
% Force round up behavior by biasing generator
options = rmfield(options,'p');
options = rmfield(options,'flip');
options.round = 6;
options.randfunc = @(n) rand(n,1) + 0.6;
A = [0 -1.1 -1.5; -1.9 -2.4 -0.5];
y = roundit(A,options);
assert_eq(y,[0 -1 -1; -1 -2 0])
fprintf('All tests successful!\n')
%%%%%%%%%%%%%%%%%%%%%%%
function assert_eq(a,b)
n = n+1;
if ~isequal(a,b)
a, b
error('Failure')
end
fprintf('Test %g succeeded.\n', n )
end
end