In this tutorial we will now set up the computation of LDs for a system that blows up in finite time, that is, trajectories when simulated will escape to infinity so fast that the numerically cannot be resolved after some finite simulation time.
The solution to this problem by LDDS is to use Variable Time integration , which given a bounding box of the domain, will turn the vector field off (equal to zero), only for those trajectories escpaing beyond the box_boundaries. This is equivalent to stopping integration only for escaping trajectories, such that LD values stop being updated for them.
To illustrate how to set up LDDS for LD calculations to deal with such situations, we study two systems: the Hamilton-Saddle Node and the Inverse Duffing oscillator. Both 1DoF autonomous Hamiltonian system, for which trajectories can escape to infinity within the finite time-interval of simulation.
Energy
\begin{equation*} H(x, p_x) = \frac{1}{2} p_x^2 + \frac{1}{2}x^2 + \frac{1}{3} x^3 \end{equation*}Vector field
\begin{align*} \dot{x} &= \frac{\partial H}{\partial p_x} = f_1(x, p_x) = p_x \\ \dot{p}_x &= -\frac{\partial H}{\partial x} = f_2(x, p_x) = - x - x^2 \end{align*}The setup is initialised as before
import os, sys
import numpy as np
sys.path.insert(1, os.pardir)
from ldds.base import compute_lagrangian_descriptor
from ldds.tools import draw_all_lds
from ldds.vector_fields import HamSN1D
# Integration parameters
tau = 8
# Lp-norm, p-value
p_value = 1/2
# Mesh parameters
x_min,x_max = [-1.5, 1]
y_min,y_max = [-1, 1]
Nx, Ny = [300, 300]
grid_parameters = [(x_min, x_max, Nx), (y_min, y_max, Ny)]
vector_field = HamSN1D
BUT now, we need a new variable called box_boundaries, defined as below
# Box boundaries for Variable Time Integration
box_x_min, box_x_max = [-6, 6] # defined only for configuration space - x axis
box_boundaries = [(box_x_min, box_x_max)]
# box_boundaries = False
which then, it's passed to compute_lagrangian_descriptor as an additional argument, to compute the forward and backward LDs for visualisation, as usual.
LD_forward = compute_lagrangian_descriptor(grid_parameters, vector_field, tau, p_value, box_boundaries)
LD_backward = compute_lagrangian_descriptor(grid_parameters, vector_field, -tau, p_value, box_boundaries)
figs = draw_all_lds(LD_forward, LD_backward, grid_parameters, tau, p_value)
NOTE As an exercise, one can see that if
box_boundariesare equal toFalse, which is set by default, the execution ofcompute_lagrangian_descriptorwill throw an error messageValueError: need at least one array to concatenateThis is the result of the integrator breaking after failing to numerically integrate
vector_field, resulting in an empty solution array.
from ldds.vector_fields import Duffing1D
Energy
\begin{equation*} H(x, p_x) = \frac{1}{2} p_x^2 + \frac{1}{2} x^2 - \frac{1}{4} x^4 \end{equation*}Vector field
\begin{align*} \dot{x} &= \frac{\partial H}{\partial p_x} = f_1(x, p_x) = p_x \\ \dot{p}_x &= -\frac{\partial H}{\partial x} = f_2(x, p_x) = -x + x^3 \end{align*}# Integration parameters
tau = 10
# Lp-norm, p-value
p_norm = 1/2
# Mesh parameters
x_min,x_max = [-1.5, 1.5]
y_min,y_max = [-1, 1]
Nx, Ny = [300, 300]
# Box boundaries for Variable Time Integration
box_x_min, box_x_max = [-6, 6]
grid_parameters = [(x_min, x_max, Nx), (y_min, y_max, Ny)]
# define inverted oscillator from redefining parameters of Duffing
alpha, beta = [-1, -1]
vector_field = lambda t,u: Duffing1D(t, u, PARAMETERS = [alpha, beta])
box_boundaries = [(box_x_min, box_x_max)]
LD_forward = compute_lagrangian_descriptor(grid_parameters, vector_field, tau, p_value, box_boundaries)
LD_backward = compute_lagrangian_descriptor(grid_parameters, vector_field, -tau, p_value, box_boundaries)
figs = draw_all_lds(LD_forward, LD_backward, grid_parameters, tau, p_value)