Skip to content

Rössler Network

System Description

Network of 100 coupled Rössler oscillators studying synchronization dynamics:

\[ \begin{aligned} \dot{x}_i &= -y_i - z_i + K \sum_{j \in \mathcal{N}_i} (x_j - x_i) \\ \dot{y}_i &= x_i + ay_i \\ \dot{z}_i &= b + z_i(x_i - c) \end{aligned} \]

where \(i = 1, \ldots, 100\) and \(\mathcal{N}_i\) denotes the neighbors of node \(i\) in the network.

System Parameters

Parameter Symbol Value
Rössler parameter \(a\) 0.2
Rössler parameter \(b\) 0.2
Rössler parameter \(c\) 7.0
Coupling strength \(K\) 0.218 (baseline)
Network topology Scale-free, 100 nodes

Sampling

  • Dimension: \(D = 300\) (3 states \(\times\) 100 nodes)
  • Sample size: \(N = 500\)
  • Distribution: \(\rho\) = Uniform
  • Region of interest: \(\mathcal{Q}(x_i, y_i, z_i) : [-15, 15] \times [-15, 15] \times [-5, 35]\) per node

Solver

Setting Value
Method Dopri5 (Diffrax)
Time span \([0, 1000]\)
Steps 1000 (\(f_s\) = 1 Hz)
Relative tolerance 1e-03
Absolute tolerance 1e-06
Event function Divergence at \(\lvert y \rvert > 400\)

Feature Extraction

Maximum pairwise deviation at final time step:

  • States: all \(x_i, y_i, z_i\)
  • Formula: \(\Delta_x = \max_i(x_i) - \min_i(x_i)\), similarly for \(y\), \(z\); plus \(\Delta_{\text{all}} = \max(\Delta_x, \Delta_y, \Delta_z)\)
  • Transient cutoff: \(t^* = 950.0\)

Clustering

  • Method: Threshold classifier (SynchronizationClassifier)
  • Threshold: \(\epsilon = 1.5\)
  • Rule: Synchronized if \(\Delta_{\text{all}} < \epsilon\), desynchronized otherwise

Attractors

The system exhibits three types of behavior:

  • Synchronized: All oscillators converge to a common trajectory
  • Desynchronized: Oscillators remain coupled but do not synchronize
  • Unbounded: Some trajectories diverge to infinity (detected by event function)

Basin stability is computed for non-unbounded states (synchronized + desynchronized).

Reproduction Code

Setup

def setup_rossler_network_system() -> SetupProperties:
    """Setup the Rössler network system for basin stability estimation.

    Uses coupling strength K=0.218 (expected S_B ≈ 0.496 from paper).

    :return: Configuration dictionary for BasinStabilityEstimator.
    """
    k = 0.218
    n = 500

    device = "cuda" if torch.cuda.is_available() else "cpu"
    print(f"Setting up Rössler network system on device: {device}")
    print(f"  N = {N_NODES} nodes, k = {k}")

    params: RosslerNetworkParams = {
        "a": 0.2,
        "b": 0.2,
        "c": 7.0,
        "K": k,
    }

    ode_system = RosslerNetworkJaxODE(params, n=N_NODES, edges_i=EDGES_I, edges_j=EDGES_J)

    min_limits = (
        [-15.0] * N_NODES  # x_i in [-15, 15]
        + [-15.0] * N_NODES  # y_i in [-15, 15]
        + [-5.0] * N_NODES  # z_i in [-5, 35]
    )
    max_limits = (
        [15.0] * N_NODES  # x_i
        + [15.0] * N_NODES  # y_i
        + [35.0] * N_NODES  # z_i
    )

    sampler = UniformRandomSampler(
        min_limits=min_limits,
        max_limits=max_limits,
        device=device,
    )

    solver = JaxSolver(
        t_span=(0, 1000),
        t_steps=200,
        t_eval=(980.0, 1000.0),
        device=device,
        rtol=1e-3,
        atol=1e-6,
        cache_dir=".pybasin_cache/rossler_network",
        event_fn=rossler_stop_event,
    )

    feature_extractor = SynchronizationFeatureExtractor(
        n_nodes=N_NODES,
        time_steady=950,
        device=device,
    )

    sync_classifier = SynchronizationClassifier(
        epsilon=1.5,
    )

    return {
        "n": n,
        "ode_system": ode_system,
        "sampler": sampler,
        "solver": solver,
        "feature_extractor": feature_extractor,
        "estimator": sync_classifier,
    }

Single K Value

def main() -> tuple[BasinStabilityEstimator, StudyResult]:
    """Run basin stability estimation for Rössler network.

    Uses coupling strength K=0.218 (expected S_B ≈ 0.496 from paper).

    :return: Basin stability estimator with results.
    """
    props = setup_rossler_network_system()

    bse = BasinStabilityEstimator(
        n=props["n"],
        ode_system=props["ode_system"],
        sampler=props["sampler"],
        solver=props.get("solver"),
        feature_extractor=props.get("feature_extractor"),
        predictor=props.get("estimator"),
        template_integrator=props.get("template_integrator"),
        output_dir="results",
        feature_selector=None,
        detect_unbounded=False,
    )

    result = bse.run()

    return bse, result

K Parameter Sweep

def main() -> BasinStabilityStudy:
    """Run parameter study for Rössler network coupling strength.

    Sweeps through K values from paper to analyze basin stability variation.

    :return: Basin stability study with results.
    """
    props = setup_rossler_network_system()

    study_params = SweepStudyParams(
        **{'ode_system.params["K"]': K_VALUES_FROM_PAPER.tolist()},
    )

    solver = props.get("solver")
    feature_extractor = props.get("feature_extractor")
    estimator = props.get("estimator")
    template_integrator = props.get("template_integrator")
    assert solver is not None
    assert feature_extractor is not None
    assert estimator is not None

    bse = BasinStabilityStudy(
        n=props["n"],
        ode_system=props["ode_system"],
        sampler=props["sampler"],
        solver=solver,
        feature_extractor=feature_extractor,
        estimator=estimator,
        study_params=study_params,
        template_integrator=template_integrator,
        output_dir="results_k_study",
    )

    bse.run()

    return bse

Baseline Results (K=0.218)

Comparison with Paper Results

Attractor pybasin BS ± SE Paper BS ± SE Difference 95% CI Status
synchronized 0.48400 ± 0.02235 0.49600 ± 0.02236 -0.0120 ±0.0620
unbounded 0.51600 ± 0.02235 0.50400 ± 0.02236 +0.0120 ±0.0620

Visualizations

Basin Stability

Basin Stability

State Space

State Space

Feature Space

Feature Space

K Parameter Sweep

Comparison with Paper Results

Parameter Attractor pybasin BS ± SE Paper BS ± SE Difference 95% CI Status
0.119 synchronized 0.09200 ± 0.01293 0.22600 ± 0.01870 -0.13400 ±0.04456
unbounded 0.79800 ± 0.01796 0.77400 ± 0.01870 +0.02400 ±0.05082
0.139 synchronized 0.21600 ± 0.01840 0.27400 ± 0.01995 -0.05800 ±0.05319
unbounded 0.75200 ± 0.01931 0.72600 ± 0.01995 +0.02600 ±0.05442
0.159 synchronized 0.30400 ± 0.02057 0.33000 ± 0.02103 -0.02600 ±0.05766
unbounded 0.69200 ± 0.02065 0.67000 ± 0.02103 +0.02200 ±0.05776
0.179 synchronized 0.36000 ± 0.02147 0.34600 ± 0.02127 +0.01400 ±0.05924
unbounded 0.63800 ± 0.02149 0.65400 ± 0.02127 -0.01600 ±0.05927
0.198 synchronized 0.42000 ± 0.02207 0.47200 ± 0.02233 -0.05200 ±0.06153
unbounded 0.58000 ± 0.02207 0.52800 ± 0.02233 +0.05200 ±0.06153
0.218 synchronized 0.48400 ± 0.02235 0.49600 ± 0.02236 -0.01200 ±0.06196
unbounded 0.51600 ± 0.02235 0.50400 ± 0.02236 +0.01200 ±0.06196
0.238 synchronized 0.55000 ± 0.02225 0.59400 ± 0.02196 -0.04400 ±0.06127
unbounded 0.45000 ± 0.02225 0.40600 ± 0.02196 +0.04400 ±0.06127
0.258 synchronized 0.60800 ± 0.02183 0.62800 ± 0.02162 -0.02000 ±0.06022
unbounded 0.39200 ± 0.02183 0.37200 ± 0.02162 +0.02000 ±0.06022
0.278 synchronized 0.65600 ± 0.02124 0.65600 ± 0.02124 +0.00000 ±0.05889
unbounded 0.34400 ± 0.02124 0.34400 ± 0.02124 +0.00000 ±0.05889
0.297 synchronized 0.71200 ± 0.02025 0.69400 ± 0.02061 +0.01800 ±0.05663
unbounded 0.28800 ± 0.02025 0.30600 ± 0.02061 -0.01800 ±0.05663
0.317 synchronized 0.68000 ± 0.02086 0.69000 ± 0.02068 -0.01000 ±0.05758
unbounded 0.28400 ± 0.02017 0.31000 ± 0.02068 -0.02600 ±0.05662

Visualizations

Basin Stability Variation

Basin Stability Variation

References

Menck, P. J., Heitzig, J., Marwan, N., & Kurths, J. (2013). How basin stability complements the linear-stability paradigm. Nature Physics, 9(2), 89-92.