Wrapper library for Baobzi interpolator library
TLDR: Baobzi takes a function and represents adatively it as a tree of polynomial
interpolants. This is very fast and very accurate. Basically it allows you to precompute a
"heavy" function into a very good approximation of that function that can be orders of
magnitude faster. Operations on 1D functions are typically ~100-200 million evaluations per
second, depending on hardware. I.e. functions can often evaluate faster than some fancy
implementations of functions like log
, and can be orders of magnitude faster than special function evaluations.
Unfortunately, Baobzi is not a pure Julia implementation. The core library is written in c++
and has with c
bindings as a public API. Since Baobzi
needs to call the function you want
to approximate, this presents some limitations with Julia due to mutability and type
constraints. Basically you need to make your "callback" function C callable (double myfunc(double* x))
. That or generate the function object in another language and call it in
julia. This is probably best shown by example. All functions you want to fit need a signature
identical to the testfunc
below.
Simple 2d example for the function z = x*y
import Baobzi
function testfunc(xp::Ptr{Float64})::Cdouble
x = unsafe_load(xp, 1)
y = unsafe_load(xp, 2)
return x * y
end
center = [0.0, 0.0] # center of our function's rectangular domain
hl = [1.0, 1.0] # half widths of the functions rectangular domain
test_point = [0.25, 0.25] # just a point we want to evaluate at
dim = 2 # number of independent variables in our function (x, y)
order = 6 # order of polynomial fit
tol = 1E-10 # requested precision of fit
output_file = "simple2d.baobzi" # place to store the file
split_multi_eval = 0 # Whether to split evaluation into two steps or not. Has mild performance implications
# Fit our function
func_approx = Baobzi.init(testfunc, dim, order, center, hl, tol, 0)
# Print some stats about the fit procedure
Baobzi.stats(func_approx)
# Compare result
println(Baobzi.eval(func_approx, test_point) - testfunc(pointer(test_point)))
# Save our function and then delete it
Baobzi.save(func_approx, output_file)
Baobzi.free(func_approx)
# Restore function and compare
func_approx = Baobzi.restore(output_file)
println(Baobzi.eval(func_approx, test_point) - testfunc(pointer(test_point)))
# Evaluate function at many points in our domain
points = 2.0 * (rand(Float64, 2000000)) .- 1.0
z = Baobzi.eval_multi(func_approx, points)