Step 2: Detect Orbits From The Converged Attractors

This notebook reads the attractor table generated in Step 1 and groups the converged attractor samples into orbit labels.

Two parquet files are produced:

  • outputs/orbits.parquet with attractor and orbit metadata,

  • outputs/sim_orbit.parquet mapping each simulation to one orbit label.

from pathlib import Path

import polars as pl

from kinamax.integration.core import detect_orbits
from kinamax.integration.models import H46_EM_Problem

problem_class = H46_EM_Problem

Load The Batched Simulation Table

This file is the output of Step 1. The attractor-state labels are the original state names with an a suffix because they correspond to attractor samples rather than initial conditions.

example_dir = Path(__file__).resolve().parent if "__file__" in globals() else Path.cwd()
working_dir = example_dir / "outputs"

simulations = pl.read_parquet(working_dir / "simulations.parquet")
state_vec_labels = problem_class.state_vector_labels
attractor_state_vec_labels = [f"{k}a" for k in state_vec_labels]
ode_params_labels = problem_class.params_labels

Cluster Attractors Into Orbits

detect_orbits(...) groups simulations that converge to the same attractor sequence, up to cyclic permutation along the orbit.

attractors, sim_orbit = detect_orbits(
    problem_class=problem_class,
    simulations=simulations,
    ode_params_labels=ode_params_labels,
    attractor_state_vec_labels=attractor_state_vec_labels,
    state_vec_labels=state_vec_labels,
)

Clean The Energy-Like States And Save

Orbit detection focuses on the dynamical variables. The accumulated energy states are therefore reset to zero before storing the orbit representatives.

attractors = attractors.with_columns(
    Ev=pl.lit(0.0),
    Eh=pl.lit(0.0),
)
attractors.write_parquet(working_dir / "orbits.parquet")
sim_orbit.write_parquet(working_dir / "sim_orbit.parquet")

attractors.head()
shape: (5, 19)
xdotxvEvEhxww0AdQfdalphaC0RLMdetected_subharmonicattractor_labelorbit_labeltarget_frequency
f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64i64i64i64f64
-0.0002650.293995-3.1019330.00.00.0005121.02.587.035.00.0680.0000017830.00.0250.017310035.0
0.0006830.0503240.6229150.00.00.0005121.02.587.044.00.0680.0000017830.00.0250.017331144.0
0.000031-0.068758-0.6517650.00.00.0005121.02.587.044.00.0680.0000017830.00.0250.017332144.0
-0.000750.0447380.0069360.00.00.0005121.02.587.044.00.0680.0000017830.00.0250.017333144.0
-0.000499-0.0093330.0249620.00.00.0005121.02.587.050.00.0680.0000017830.00.0250.017314250.0