A lookup table based method to calculate
julia> import Pkg;
julia> Pkg.add("ApproxLogFunction");The exposed constructor :
Approxlog(base::Real; abserror::Real, dtype::Type{<:AbstractFloat})where base is the radix of logarithm operation, abserror is the maximum absolute error of the output and dtype is the data type of input and output value, for example :
alog₂ = Approxlog(2, abserror=0.1, dtype=Float32);
input = 5.20f2;
output = alog₂(input);using Plots, ApproxLogFunction
figs = []
base = 2
t = -2f-0 : 1f-4 : 5f0;
x = 2 .^ t;
y₁ = log.(base, x)
for Δout in [0.6, 0.3]
alog = Approxlog(base, abserror=Δout, dtype=Float32)
y₂ = alog.(x)
fg = plot(x, y₁, linewidth=1.1, xscale=:log10);
plot!(x, y₂, linewidth=1.1, titlefontsize=10)
title!("abserror=$Δout")
push!(figs, fg)
end
plot(figs..., layout=(1,2), leg=nothing, size=(999,666))Some unimportant information was omitted when benchmarking.
julia> using ApproxLogFunction, BenchmarkTools;
julia> begin
type = Float32;
base = type(2.0);
Δout = 0.1;
alog = Approxlog(base, abserror=Δout, dtype=type);
end;
julia> x = 1.23456f0;
julia> @benchmark y₁ = log($base, $x)
Time (median): 21.643 ns
julia> @benchmark y₁ = log2($x)
Time (median): 14.800 ns
julia> @benchmark y₂ = alog($x)
Time (median): 74.129 nsjulia> using ApproxLogFunction, BenchmarkTools;
julia> begin
type = Float32;
base = type(2.0);
Δout = 0.1;
alog = Approxlog(base, abserror=Δout, dtype=type);
end;
julia> x = rand(type, 1024, 1024);
julia> @benchmark y₁ = log.($base, $x)
Time (median): 21.422 ms
julia> @benchmark y₁ = log2.($x)
Time (median): 11.626 ms
julia> @benchmark y₂ = alog.($x)
Time (median): 5.207 msCalculating scaler input is slower, but why calculating array input is faster ? 😂😂😂
Error is well controlled when using IEEE754 floating-point positive normal numbers, which is represented as :
where Approxlog object's input is
In short, for Float16 input, its range is :
for Float32 input :
and for Float64 input :
As to positive subnormal numbers, the result is not reliable.
We have mentioned
Interface function :
toclang(dir::String, filename::String, funcname::String, f::Approxlog)dir is the directory to save the C language files (dir would be made if it doesn't exist before), filename is the name of the generated .c and .h files, funcname is the name of the generated approximate function and f is the approximate log functor, for example :
alog₂ = Approxlog(2, abserror=0.12, dtype=Float32)
toclang("./cfolder/", "approxlog", "alog", alog₂)this would generate approxlog.c and approxlog.h files in ./cfolder/, the function is named as alog .
