-
Notifications
You must be signed in to change notification settings - Fork 36
/
Copy pathflops_pow.m
63 lines (56 loc) · 1.34 KB
/
flops_pow.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
function f = flops_pow(a)
% FLOPS_POW Flops for raising to real power.
% FLOPS_POW(A) returns the number of flops for (X .^ A) where X is scalar.
% Powers like 0, 1, 2, and 1/2 are handled specially.
flops_div = 8;
flops_sqrt = 8;
if nargin < 1
a = 0.1;
end
f = 0;
if a < 0
f = f + flops_div;
a = -a;
end
if a == 0 || a == 1
return;
end
if fix(a) == a
% number of multiplications to raise to integer power
f = f + floor(log2(a)) + num_bits(a)-1;
elseif a == 1/2
% sqrt is built-in function
f = f + flops_sqrt;
elseif fix(2*a) == 2*a
% this handles flops_pow(1/2+1)
f = f + flops_pow(2*a) - 1 + flops_sqrt;
elseif a == 1/4
f = f + 2*flops_sqrt;
elseif a == 3/4
f = f + 2*flops_sqrt+1;
elseif fix(4*a) == 4*a
% this handles flops_pow(1/4+1)
f = f + flops_pow(2*a) - 1 + flops_sqrt;
else
f = Inf;
end
% The identities
% exp(a) = e^a
% a^b = exp(b*log(a))
% require that
% flops_exp < flops_pow < flops_exp+flops_log+1.
% But in practice, I find that the runtime exceeds this upper bound.
f_upper = 61; % flops_exp+flops_log+1
if f > f_upper
f = f_upper;
end
function b = num_bits(x)
% Returns the number of 1 bits in the binary representation of x.
% x must be a non-negative integer.
% lookup table for 0-15
bits = [0 1 1 2 1 2 2 3 1 2 2 3 2 3 3 4];
b = 0;
while(x > 0)
b = b + bits(mod(x,16)+1);
x = floor(x/16);
end