Skip to main content

Modelling autonomy dynamics over the Autonometrics atlas.

Project description

Autodynamics

Layer 2 of 3 in the autonomy research trilogy: Autonometrics (measure) -> Autodynamics (explain) -> Ex-Machina (build / emulate)

Status: Pre-alpha. Recording substrate, algebra of trajectories, generic adapters, and Granger-causal coupling primitives. No theoretical model is claimed.

Vision

Autonometrics quantifies where a system sits on the five autonomy axes (closure, memory, constraint closure, persistence, coherence). This package gives mechanical support for working with how those measurements change over time: record ordered profiles, take differences, and summarise motion in the atlas with explicit primitives. It does not ship a dynamical theory (attractors, phase structure, or predictive claims about autonomy). Interpretation of trajectories as evidence for such a theory is out of scope of the public API as it stands; the code is a reproducible toolkit, not a proof.

What this package contains today

A recording substrate, a small algebra of trajectories, and two generic input adapters. Together they turn "a sequence of autonomy measurements" into "a trajectory in a metric space, queryable axis by axis".

  • ProfileTrajectory stores a sequence of AutonomyProfile values and exposes axis-wise time series, pairwise deltas, total path length, and the algebra primitives below.
  • Algebra primitives: velocities, accelerations, drift, volatility, path_length_per_axis, rolling_mean, rolling_std, and a one-shot per-axis summary.
  • Adapters: CSVTrajectoryAdapter (load from a CSV with canonical axis columns) and BatchTrajectoryAdapter (build several parallel trajectories from grouped profiles, with cross-group mean_summary).
  • Granger-causal coupling: granger_graph (directed pairwise Granger graph over admitted axes), CausalCouplingGraph, and four scalar diagnostics (symmetry_ratio, density, max_in_strength, max_out_strength).
  • Pre-registered boundary regimes and a saturation theorem documented in docs/TRAJECTORY_DIAGNOSTICS.md; the coupling protocol is pre-registered in docs/COUPLING_DIAGNOSTICS.md.

Install with: pip install autodynamics Import as: import autodynamics

Quick run

pip install autodynamics
autodynamics-demo --n-states-list 3 4 5 6 8 --n-steps 600
autodynamics-demo --n-states-list 3 4 5 6 8 --n-steps 600 --report summary

The first command prints a small table of (closure, memory) profiles measured over a sweep of SimpleAutomaton configurations, the consecutive deltas between them, and the total path length. The second prints a per-axis summary instead of the deltas.

Toy demo: ProfileTrajectory

Disclaimer. This is the recording substrate of Autodynamics, not its theory. The trajectory class lets you collect, traverse, and compute simple geometric quantities over a sequence of AutonomyProfiles. It does not interpret what those movements mean — assigning meaning is outside the scope of the public API. Treat the code as a reproducible toolkit or template, not as evidence for a larger claim.

import autonometrics as anm
from autodynamics import ProfileTrajectory

trajectory = ProfileTrajectory(axes=("closure", "memory"))

for n_states in [3, 4, 5, 6, 8]:
    sys = anm.SimpleAutomaton.demo(n_states=n_states, n_steps=600)
    sys.run()
    profile = anm.measure(sys, axes=["closure", "memory"])
    trajectory.append(profile)

print(trajectory.axis_series("closure"))    # time series of one axis
print(trajectory.deltas())                  # pairwise consecutive movements
print(trajectory.total_path_length())       # sum of delta magnitudes

Trajectory algebra

Beyond the substrate, the package exposes an algebra of trajectories (velocity-style differences, rolling statistics, per-axis summary). Every primitive is mosaic-dropout fielty: None propagates through differences, but never aborts aggregations.

from autodynamics import ProfileTrajectory

trajectory = ProfileTrajectory(axes=("closure", "memory"))
# ... append profiles as above ...

trajectory.velocities("closure")        # first differences, axis by axis
trajectory.accelerations("closure")     # second differences
trajectory.drift("closure")             # net change between first and last defined values
trajectory.volatility("closure")        # sample std of the velocities
trajectory.path_length_per_axis()       # sum of |velocity| per axis
trajectory.rolling_mean("closure", window=10)  # right-aligned rolling mean
trajectory.rolling_std("closure", window=10)   # right-aligned rolling sample std
trajectory.summary()                    # per-axis report: n_total, n_defined, mean, std, drift, volatility, path_length

Calling a primitive without an axis argument returns a dict over every axis configured on the trajectory; calling it with a canonical axis name returns the value for that axis directly. The full list of boundary regimes and the saturation theorem are pre-registered in docs/TRAJECTORY_DIAGNOSTICS.md.

Adapters

Two generic adapters open input paths into ProfileTrajectory without introducing calibration or threshold tuning of their own.

CSV adapter

from autodynamics import CSVTrajectoryAdapter

adapter = CSVTrajectoryAdapter()
trajectory = adapter.load_path("path/to/profiles.csv")
print(trajectory.summary())

The adapter reads columns closure, memory, constraint, persistence, coherence (any subset is fine; missing columns yield fully-undefined axes). Empty or whitespace-only cells become None. Extra columns (class, params, seed, notes, ...) are ignored. Pass order_column="step" (or any integer-valued column name) to sort rows numerically before constructing snapshots.

Batch adapter

from autodynamics import BatchTrajectoryAdapter
import autonometrics as anm

batch = BatchTrajectoryAdapter()
for params in benchmark_configurations:
    for seed in range(K):
        system = build_system(params, seed)
        system.run()
        profile = anm.measure(system)
        batch.add(params, profile)

trajectories = batch.trajectories()        # one ProfileTrajectory per group key
mean_summary = batch.mean_summary()        # per-axis cross-group means of summary metrics

A reproducible end-to-end example using both adapters over a public fixture is shipped at examples/trajectory_demo.py.

Coupling analysis

Beyond intra-axis algebra, the package exposes a cross-axis primitive: a directed Granger-causal coupling graph between every pair of admitted axes of a ProfileTrajectory, with a stationarity gate (Augmented Dickey-Fuller), mosaic-dropout-fielty axis admission, and four scalar diagnostics. The implementation is the standard pairwise Granger test (Granger 1969; Sims 1980; Lütkepohl 2005) applied uniformly to the axes of the autonomy atlas, packaged so it composes with the rest of the algebra without bespoke calibration.

from autodynamics import (
    granger_graph, density, symmetry_ratio,
    max_in_strength, max_out_strength,
)

graph = granger_graph(trajectory)
# Also accepts a Mapping[str, Sequence[float | None]]:
# graph = granger_graph({"closure": [...], "memory": [...]})

graph.axes_used                                # admitted axes
graph.excluded_axes                            # axis -> rejection reason
graph.edge("closure", "memory").f_stat         # F-stat, lag, p-value, status

symmetry_ratio(graph)                          # average min/max F over pairs
density(graph)                                 # fraction of edges above F critical
max_in_strength(graph, "memory")               # max incoming F-stat
max_out_strength(graph, "closure")             # max outgoing F-stat

The protocol (length gate, ADF + up to two differences, AIC-selected VAR up to max_lag, F-test, mosaic-dropout-fielty axis admission) is pre-registered in docs/COUPLING_DIAGNOSTICS.md. It is not a claim that any axis Granger-causes any other axis on any specific Autonometrics zoo; it is a composable primitive that can be fed real or synthetic trajectories without bespoke threshold tuning.

Public validation track

Pre-registered, falsifiable experiments that stress the algebra primitives against the public Autonometrics benchmarks. Each experiment locks its hypothesis in docs/ before any output is generated, and records both confirmations and rejections verbatim. Recent public runs include negative results: they narrow what the current primitives can support and are not written as motivation for a new public release cycle.

Roadmap

  • v0.1.0a0 / v0.1.0a1: Toy trajectory recorder. Reserves name, declares vision, ships demo.
  • v0.2.0a0: Trajectory algebra (velocities, accelerations, drift, volatility, rolling statistics, summary), generic CSV / batch adapters, pre-registered diagnostics, public validation track.
  • v0.2.1a0: Documentation cleanup; PyPI summary description shortened.
  • v0.3.0a0 (current): Granger-causal coupling primitives (granger_graph, CausalCouplingGraph, four scalar diagnostics), with pre-registered diagnostics (docs/COUPLING_DIAGNOSTICS.md) and public validation track (docs/COUPLING_VALIDATION.md, verdict: REJECTED).
  • v0.4.0a0 (planned): Generic envelope primitives (Envelope, trinary ContainmentVerdict) with the same pre-registration / public-validation discipline.

Beyond v0.4.0a0, no further cycle is pre-declared. Future work will be opened only when motivated by a concrete pre-registered design document or external collaboration.

Position in the trilogy

Layer Project Question it answers
1 Autonometrics Where does a system sit on the autonomy atlas?
2 Autodynamics How do successive profiles differ, and how do their axes couple (recorded motion plus pairwise Granger coupling, not a dynamical model)?
3 Ex-Machina Can we build a system that occupies a chosen region?

License

Apache License 2.0 — see LICENSE.

Citation

If you reference this work, please cite Autodynamics directly. A formal citation block will be added when the API stabilises.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

autodynamics-0.3.0a0.tar.gz (82.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

autodynamics-0.3.0a0-py3-none-any.whl (32.6 kB view details)

Uploaded Python 3

File details

Details for the file autodynamics-0.3.0a0.tar.gz.

File metadata

  • Download URL: autodynamics-0.3.0a0.tar.gz
  • Upload date:
  • Size: 82.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for autodynamics-0.3.0a0.tar.gz
Algorithm Hash digest
SHA256 9dcbbca9cbc204c3f45ef39e98c2ccbad7cd515b7c56ed1cb55d9e536bf8504c
MD5 9bae21944825cd4600d940cd1d51066f
BLAKE2b-256 219f1d226ee68eb1631c4a7992c3b3a407b7cd63df2aff05fa5ebfef0a2b55ec

See more details on using hashes here.

File details

Details for the file autodynamics-0.3.0a0-py3-none-any.whl.

File metadata

  • Download URL: autodynamics-0.3.0a0-py3-none-any.whl
  • Upload date:
  • Size: 32.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for autodynamics-0.3.0a0-py3-none-any.whl
Algorithm Hash digest
SHA256 db7c19b909eeb3bd31335acaab83b9980651bcac7b29d95cea6cc70c7d10effb
MD5 f0a4d6009b49e920ef1547c3d2e788f1
BLAKE2b-256 d1083e41b4aecb4b92ba0eec70ce0b267a49465aa0061c70905cd12d4a36ba87

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page