Skip to content

Discrete data

The original AAA algorithm (Nakatsukasa, Sète, Trefethen 2018) works with a fixed set of points on the domain of approximation. There is a legacy aaa function that can work with this type of data:

julia
using RationalFunctionApproximation, ComplexRegions
x = -1:0.01:1
f = x -> tanh(5 * (x - 0.2))
r = aaa(x, f.(x))
Barycentric{Float64, Float64} rational interpolant of type (35, 35):
    -0.999988=>-1.0,  0.999329=>1.0,  -0.99186=>-0.35,  …  -0.999727=>-0.69

However, it's preferable to use the approximate function for this purpose, as the result type is more useful within the package. Simply pass the function and, in the form of a vector, the domain.

julia
r = approximate(f, x)
Barycentric{Float64, Float64} rational interpolant of type (11, 11) on the domain: -1.0:0.01:1.0

As long as there are no singularities as close to the domain as the sample points are to one another, this fully discrete approach should be fine:

julia
I = unit_interval
println("nearest pole is $(minimum(dist(z, I) for z in poles(r))) away")
_, err = check(r);
println("max error on the given domain: ", maximum(abs, err))
nearest pole is 0.31415926535638594 away
[ Info: Max error is 2.24e-14
max error on the given domain: 2.2426505097428162e-14

But if the distance to a singularity is comparable to the sample spacing, the quality of the approximation may suffer. Even worse, the method may not be aware that it has failed.

julia
f = x -> tanh(400 * (x - 0.2))
r = approximate(f, x)
println("nearest pole is $(minimum(dist(z, I) for z in poles(r))) away")
_, err = check(r);
println("max error on the given domain: ", maximum(abs, err))
err = maximum(abs(f(x)- r(x)) for x in range(-1, 1, 3000))
println("max error on finer test points: ", err)
nearest pole is 0.004569419284272946 away
[ Info: Max error is 7.84e-14
max error on the given domain: 7.838174553853605e-14
max error on finer test points: 0.058457305710306495

In the continuous mode, the adaptive sampling of the domain attempts to ensure that the approximation is accurate everywhere.

julia
r = approximate(f, I; tol=1e-12)
err = maximum(abs(f(x)- r(x)) for x in range(-1, 1, 3000))
println("max error on finer test points: ", err)
max error on finer test points: 2.057243264630415e-13