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:
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.
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:
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.
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.
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