Lyapunov Exponents
The Finite Time Lyapunov Spectrum (FTLS) for a 2D billiard system consists of a set of 4 numbers $\lambda_i \, , \{ i = 1, ...,4 \}$ that characterize how fast the separation of initially close initial conditions grows.
It can be shown theoretically that two of these exponents must be zero ($\lambda_2$ =$\lambda_3$ = 0) and the other two are paired in such a way that they sum up to zero, i.e. $\lambda_1 = -\lambda_4$).
The function provided to calculate the FTLS is
DynamicalBilliards.lyapunovspectrum — Functionlyapunovspectrum([p::AbstractParticle,] bd::Billiard, t)Returns the finite time lyapunov exponents (averaged over time t) for a given particle in a billiard table using the method outlined in [1]. t can be either Float or Int, meaning total time or total amount of collisions.
Returns zeros for pinned particles.
If a particle is not given, a random one is picked through randominside. See parallelize for a parallelized version.
[1] : Ch. Dellago et al, Phys. Rev. E 53 (1996)
Here its basic use is illustrated
using DynamicalBilliards
radius = 1.0
l = 2.0
bd = Billiard(billiard_polygon(6, l; setting = "periodic")..., Disk([0., 0.], radius))
par = randominside(bd)
t = 1000.0
exps = lyapunovspectrum(par, bd, t)4-element Vector{Float64}:
0.64789569519552
0.0015805439766546864
-2.16017524882894e-5
-0.6494546374196865In the following example we compute the change of $\lambda_1\$ versus the distance between the disks in a hexagonal periodic billiard.
using DynamicalBilliards, CairoMakie
t = 5000.0
radius = 1.0
spaces = 2.0:0.1:4.4 #Distances between adjacent disks
lyap_time = zero(spaces) #Array where the exponents will be stored
for (i, space) in enumerate(spaces)
bd = billiard_polygon(6, space/(sqrt(3)); setting = "periodic")
disc = Disk([0., 0.], radius)
billiard = Billiard(bd.obstacles..., disc)
p = randominside(billiard)
lyap_time[i] = lyapunovspectrum(p, billiard, t)[1]
end
fig = Figure(); ax = Axis(fig[1,1]; xlabel = L"w", ylabel = L"\lambda_1")
lines!(ax,spaces, lyap_time)
fig
The plot of the maximum exponent can be compared with the results reported by Gaspard et. al (see figure 7), showing that using just t = 5000.0 is already enough of a statistical averaging.
Perturbation Growth
To be able to inspect the dynamics of perturbation growth in more detail, we also provide the following function:
DynamicalBilliards.perturbationgrowth — Functionperturbationgrowth([p,] bd, t) -> ts, Rs, isCalculate the evolution of the perturbation vector Δ along the trajectory of p in bd for total time t. Δ is initialised as [1,1,1,1].
If a particle is not given, a random one is picked through randominside. Returns empty lists for pinned particles.
Description
This function safely computes the time evolution of a perturbation vector using the linearized dynamics of the system, as outlined by [1]. Because the dynamics are linear, we can safely re-normalize the perturbation vector after every collision (otherwise the perturbations grow to infinity).
Immediately before and after every collison, this function computes
- the current time.
- the element-wise ratio of Δ with its previous value
- the obstacle index of the current obstacle
and returns these in three vectors ts, Rs, is.
To obtain the actual evolution of the perturbation vector you can use the function perturbationevolution(Rs) which simply does
Δ = Vector{SVector{4,Float64}}(undef, length(R))
Δ[1] = R[1]
for i in 2:length(R)
Δ[i] = R[i] .* Δ[i-1]
end[1] : Ch. Dellago et al, Phys. Rev. E 53 (1996)
For example, lets plot the evolution of the perturbation growth using different colors for collisions with walls and disks in the Sinai billiard:
using DynamicalBilliards, CairoMakie, LinearAlgebra
bd = billiard_sinai()
ts, Rs, is = perturbationgrowth(Particle(0.1, 0.1, 0.1), bd, 10.0)
Δ = perturbationevolution(Rs)
fig = Figure()
ax = Axis(fig[1,1]; xlabel = L"t", ylabel = L"\log(||\Delta ||)")
lines!(ts, log.(norm.(Δ)))
scatter!(ts, log.(norm.(Δ)); color = [j == 1 ? :black : :red for j in is])
fig