Skip to content

Discrete data ​

For many functions, discretization of the domain is straightforward. But if the function has singularities close to the domain of approximation, a continuum approach may be more robust.

The approximate function can take a vector of sample points as a domain. The given function is then evaluated only at those points, and the rational approximation is a fully discrete process that uses only the given data.

julia
using RationalFunctionApproximation
x = -1:0.01:1
f(x) = tanh(5 * (x - 0.2))
r = approximate(f, x)
Thiele{Float64, Float64} rational of type (11, 10) constructed from 201 samples
  stopped by converged after 22 iterations with estimated error 1.098e-13

You can alternatively provide just the discrete function values yourself. The domain is always given second:

julia
y = f.(x)
r = approximate(y, x)
Thiele{Float64, Float64} rational of type (11, 10) constructed from 201 samples
  stopped by converged after 22 iterations with estimated error 1.098e-13

As long as there are no singularities as close to the domain as the sample points are to one another, a basic discretization works well.

julia
using ComplexRegions    # to get dist() function
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.3141592653597409 away
[ Info: Max error is 1.10e-13
max error on the given domain: 1.0969003483296547e-13

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 2.7755575615628914e-17 away
[ Info: Max error is 1.24e-13
max error on the given domain: 1.2378986724570495e-13
max error on finer test points: 0.05957532617652128

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

julia
r = approximate(f; 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: 4.4209080840573733e-13