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 ns
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 = 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 ms
Calculating 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
.