chaotic_pfc.config

config.py

Centralised configuration for all experiments.

The module exposes a single DEFAULT_CONFIG object of type ExperimentConfig that aggregates the per-subsystem settings (comm, channel, lyapunov, sweep, …). Every experiment script imports it to obtain its default parameters, and CLI flags selectively override individual fields without having to thread a full config through the call chain.

All configs are plain dataclasses, so they can be cheaply copied, mutated in tests, or serialised with dataclasses.asdict().

Module Attributes

DEFAULT_CONFIG

The project-wide singleton.

Classes

ChannelConfig([cutoff, num_taps])

External FIR-channel parameters (fir_channel()).

CommConfig([N, mu, message_period, ...])

Top-level parameters of the communication pipeline.

ExperimentConfig([comm, channel, ...])

Aggregate configuration used by every experiment script.

HenonConfig([a, b])

Parameters of the base Hénon map.

InternalFIRConfig([cutoff, num_taps])

FIR filter used inside the N-th order Hénon oscillator.

LyapunovConfig([Nitera, Ndiscard, ...])

Parameters for Lyapunov exponent computation.

PlotConfig([time_window_start, ...])

Global plotting defaults used by the experiment scripts.

SpectralConfig([nfft, window_length, fs, ...])

Defaults for psd_normalised().

SweepConfig([Nitera, Nmap, n_initial, ...])

Parameters for the 2-D (order, cutoff) Lyapunov sweep.

class chaotic_pfc.config.HenonConfig(a=1.4, b=0.3)[source]

Bases: object

Parameters of the base Hénon map.

The default (a, b) = (1.4, 0.3) is the canonical chaotic regime. Deviating from these requires care — the communication pipeline assumes a strange attractor.

Parameters:
a: float = 1.4
b: float = 0.3
class chaotic_pfc.config.CommConfig(N=1000000, mu=0.01, message_period=20, transient=200, henon=<factory>)[source]

Bases: object

Top-level parameters of the communication pipeline.

Parameters:
N

Default number of samples in a transmitted sequence.

Type:

int

mu

Modulation depth used by the transmitter and receiver. Must match on both ends.

Type:

float

message_period

Period of the default binary message, in samples.

Type:

int

transient

Number of samples discarded at the start of each run before computing the MSE metric. Lets the local oscillator lock into synchronisation.

Type:

int

henon

Nested Hénon parameters (a, b).

Type:

chaotic_pfc.config.HenonConfig

N: int = 1000000
mu: float = 0.01
message_period: int = 20
transient: int = 200
henon: HenonConfig
class chaotic_pfc.config.ChannelConfig(cutoff=0.99, num_taps=201)[source]

Bases: object

External FIR-channel parameters (fir_channel()).

Parameters:
cutoff: float = 0.99
num_taps: int = 201
class chaotic_pfc.config.InternalFIRConfig(cutoff=0.5, num_taps=9)[source]

Bases: object

FIR filter used inside the N-th order Hénon oscillator.

Differs from ChannelConfig in that this filter sits inside the chaos generator (it shapes the feedback loop), not on the transmission path. Used primarily by the order-N transmitter/receiver pair.

Parameters:
cutoff: float = 0.5
num_taps: int = 9
fir_coeffs()[source]

Build the FIR coefficients for the configured cutoff and length.

Uses a Hamming window with pass_zero=True and the usual fs=2.0 normalisation so that cutoff is interpreted directly as ω_c / π.

Returns:

Filter coefficients.

Return type:

ndarray, shape (num_taps,)

class chaotic_pfc.config.SpectralConfig(nfft=4096, window_length=1024, fs=1.0, window='hamming', kaiser_beta=5.0)[source]

Bases: object

Defaults for psd_normalised().

Parameters:
nfft, window_length, fs

Standard Welch parameters.

window

FIR window applied to each Welch segment. Currently "hamming" (the historical default) and "kaiser" are supported.

Type:

str

kaiser_beta

Shape parameter of the Kaiser window. Ignored unless window == "kaiser". Larger values give higher stop-band attenuation at the cost of a wider main lobe; β ≈ 5 is a common ~50 dB compromise.

Type:

float

nfft: int = 4096
window_length: int = 1024
fs: float = 1.0
window: str = 'hamming'
kaiser_beta: float = 5.0
class chaotic_pfc.config.LyapunovConfig(Nitera=2000, Ndiscard=1000, perturbation=0.1, n_ci=20, data_dir='data/lyapunov', Gz=1.0, pole_radius=0.975, w0=0.0)[source]

Bases: object

Parameters for Lyapunov exponent computation.

Parameters:
Nitera, Ndiscard

Iterations used for the estimate and the transient to discard before starting to accumulate.

perturbation

Half-width of the IC sampling box around the fixed point, as a fraction of the coordinate (±10% by default).

Type:

float

Gz

Filter gain term used in the 4-D pole-filtered system.

Type:

float

pole_radius

Pole radius r (0, 1). Larger values make the filter sharper and the dynamics more dissipative.

Type:

float

w0

Normalised angular frequency of the pole pair (× π).

Type:

float

n_ci

Number of initial conditions for the ensemble protocol.

Type:

int

data_dir

Directory for ensemble CSV output.

Type:

str

Nitera: int = 2000
Ndiscard: int = 1000
perturbation: float = 0.1
n_ci: int = 20
data_dir: str = 'data/lyapunov'
Gz: float = 1.0
pole_radius: float = 0.975
w0: float = 0.0
class chaotic_pfc.config.PlotConfig(time_window_start=0, time_window_end=300, dpi=150, figures_dir='figures', fmt='svg')[source]

Bases: object

Global plotting defaults used by the experiment scripts.

Parameters:
  • time_window_start (int)

  • time_window_end (int)

  • dpi (int)

  • figures_dir (str)

  • fmt (str)

time_window_start: int = 0
time_window_end: int = 300
dpi: int = 150
figures_dir: str = 'figures'
fmt: str = 'svg'
class chaotic_pfc.config.SweepConfig(Nitera=500, Nmap=3000, n_initial=25, order_lo=2, order_hi=42, n_cutoffs=100, default_window='hamming', default_filter_type='lowpass', bandwidth=0.05, data_dir='data/sweeps', figures_dir='figures/sweeps', fig_fmts=('svg',))[source]

Bases: object

Parameters for the 2-D (order, cutoff) Lyapunov sweep.

Used by chaotic_pfc.sweep. The full grid is len(orders) × n_cutoffs points; at the defaults this is 4 000.

Parameters:
Nitera

Burn-in iterations applied before computing the estimator.

Type:

int

Nmap

Iterations accumulated into the Lyapunov estimator.

Type:

int

n_initial

Number of random initial conditions averaged per grid point.

Type:

int

order_lo, order_hi

Filter-order range, order_hi exclusive. Defaults to range(2, 42) → 40 orders.

n_cutoffs

Number of cutoff frequencies sampled linearly in (0, 1).

Type:

int

default_window, default_filter_type

Default selections when no CLI override is given.

data_dir, figures_dir

Output locations. The .npz checkpoints live under data/sweeps and are versioned; the figures under figures/sweeps are derived from those checkpoints.

fig_fmts

Output formats produced by the plot script. Tuple because both PNG (quick preview, GitHub render) and SVG (paper-grade) are useful to have in parallel.

Type:

tuple[str, …]

bandwidth

Pass-band width as a fraction of the Nyquist frequency (used for bandpass/bandstop filter types).

Type:

float

Nitera: int = 500
Nmap: int = 3000
n_initial: int = 25
order_lo: int = 2
order_hi: int = 42
n_cutoffs: int = 100
default_window: str = 'hamming'
default_filter_type: str = 'lowpass'
bandwidth: float = 0.05
data_dir: str = 'data/sweeps'
figures_dir: str = 'figures/sweeps'
fig_fmts: tuple[str, ...] = ('svg',)
class chaotic_pfc.config.ExperimentConfig(comm=<factory>, channel=<factory>, internal_fir=<factory>, spectral=<factory>, lyapunov=<factory>, plot=<factory>, sweep=<factory>, seed=42, lang='pt')[source]

Bases: object

Aggregate configuration used by every experiment script.

Composing the individual subsystem configs into a single object keeps the CLI scripts simple: they import DEFAULT_CONFIG, pick out the branches they need (e.g. cfg.comm, cfg.lyapunov) and only expose flags for the handful of fields that actually vary across experiments.

Parameters:
comm: CommConfig
channel: ChannelConfig
internal_fir: InternalFIRConfig
spectral: SpectralConfig
lyapunov: LyapunovConfig
plot: PlotConfig
sweep: SweepConfig
seed: int = 42
lang: str = 'pt'
to_namespace()[source]

Build an argparse.Namespace with defaults for every CLI subcommand.

Useful for run all, which forwards a single namespace to all sub-experiments.

Note: PlotConfig, SpectralConfig, and SweepConfig fields are intentionally omitted; CLI modules that need them read directly from DEFAULT_CONFIG.

Return type:

Namespace

chaotic_pfc.config.DEFAULT_CONFIG = ExperimentConfig(comm=CommConfig(N=1000000, mu=0.01, message_period=20, transient=200, henon=HenonConfig(a=1.4, b=0.3)), channel=ChannelConfig(cutoff=0.99, num_taps=201), internal_fir=InternalFIRConfig(cutoff=0.5, num_taps=9), spectral=SpectralConfig(nfft=4096, window_length=1024, fs=1.0, window='hamming', kaiser_beta=5.0), lyapunov=LyapunovConfig(Nitera=2000, Ndiscard=1000, perturbation=0.1, n_ci=20, data_dir='data/lyapunov', Gz=1.0, pole_radius=0.975, w0=0.0), plot=PlotConfig(time_window_start=0, time_window_end=300, dpi=150, figures_dir='figures', fmt='svg'), sweep=SweepConfig(Nitera=500, Nmap=3000, n_initial=25, order_lo=2, order_hi=42, n_cutoffs=100, default_window='hamming', default_filter_type='lowpass', bandwidth=0.05, data_dir='data/sweeps', figures_dir='figures/sweeps', fig_fmts=('svg',)), seed=42, lang='pt')

The project-wide singleton.

Import this, do not instantiate a new one. Treat as read-only at runtime; mutating a sub-config field (e.g. cfg.comm.N = 100) will affect all subsequent experiments in the same process. If a test needs a modified copy, use dataclasses.replace() on the relevant sub-dataclass.