Skip to main content

causal-automata

PyPI Version Python Versions License Documentation Status

A blazing-fast, JAX-accelerated Cellular Automaton engine for causal discovery.

v0.3.0 — Corrected V-well / gravity / conditioning physics, JIT-safe run(ticks, k), and Maximum Accuracy Mode (--multihop, Directed F1 0.696 on N=100). See CHANGELOG.md.

Installation

pip install "causal-automata==0.3.0"

With CPU JAX:

pip install "causal-automata[jax]"
# or: uv pip install "causal-automata[jax]"

With NVIDIA CUDA JAX (and the Colab-style stack):

pip install "causal-automata[cuda]"

Or using uv in a project:

uv add "causal-automata[jax]"

Benchmark — N=100

Default stack (Upgrade 2): k=3 if N≤50, k=5 if N>50, binary edges, 1-hop gravity. On N=100 (seed=0, static thresholds, ticks=100) that baseline hits Skeleton 0.937 / Directed 0.619 in about 2.8s.

Maximum Accuracy Mode — pass --multihop (Upgrade 4): 2-hop elevation gravity via A @ A lifts Directed F1 to 0.696 with essentially flat wall time.

Algorithm Skeleton F1 Directed F1 Wall Time (s)
PC (gcastle) 0.968 0.813 528.631
GOLEM (gcastle) 0.577 0.403 251.182
Bayesian CA (JAX, k=5, 1-hop) 0.937 0.619 ~2.9
Bayesian CA (JAX, k=5, --multihop) 0.928 0.696 ~2.9

PC / GOLEM wall times are Colab Tesla T4 (num_iter=20000). CA times are CPU JAX for the Upgrade-2 / Upgrade-4 A/B; at historical k=3 the same CA finished in 0.323s on T4 with Directed F1 0.483.

Opt-in flags (defaults stay fast & binary):

  • --multihop — Maximum Accuracy Mode (2-hop gravity, Directed F1 0.696 on this SEM).
  • --fuzzy — continuous A ∈ [0, 1] soft birth/death (experimental; did not beat binary here).

Conditioning-set sweep (CA-only, 1-hop binary, same SEM):

Algorithm Skeleton F1 Directed F1 Wall Time (s)
Bayesian CA (JAX, k=3) 0.812 0.483 2.314
Bayesian CA (JAX, k=4) 0.915 0.546 2.481
Bayesian CA (JAX, k=5) 0.937 0.619 2.871
Bayesian CA (JAX, k=6) 0.937 0.619 2.454
Bayesian CA (JAX, k=7) 0.937 0.619 3.049
Bayesian CA (JAX, k=8) 0.937 0.627 3.647

Background & Origin

causal-automata evolved from graphnet-automata, a sister project exploring the application of 1D cellular automata rules to dynamic network graphs. While graphnet-automata focuses on generalized structural evolution and terminal-based visualization, this repository specializes those concepts into a high-performance, JAX-accelerated engine specifically designed for causal discovery and DAG generation.

Documentation

Full docs (theory, physics, API, CLI, JAX static ticks / k): https://causal-automata.readthedocs.io/en/latest/

How it works — CA physics + V-well

State is a binary DAG adjacency A, node elevations E ∈ [0,1], and a fixed empirical covariance Cov from continuous observations. Each tick is a local cellular update:

  1. Death / birth — prune weak edges and add strong ones using partial correlations conditioned on the top-k union neighbors ranked by |Cov|, after masking candidates with elevation below both endpoints (blocks collider / M-bias in S_{i,j}). Birth orients by elevation after the |ρ| gate. Optional --fuzzy keeps continuous weights in [0, 1] and binarizes only after the final tick.
  2. V-structure gravity well — unshielded triples (i, k, j) that show explaining-away (Berkson): marginally weak |ρ_{ij}| but stronger |ρ_{ij|k}| mark middle node k as a collider. Collider elevations are pushed below min(E_i, E_j) − 0.15; parents are gently buoyed — the classic V-structure i → k ← j.
  3. Gravity — drift elevations toward the midpoint of parent/child means (roots anchor missing parents at 1.0, leaves missing children at 0.0, isolates hold E), then keep only downhill edges with a tiny index tie-break. With --multihop, that drift also sees 2-hop neighbors from A @ A (discounted pull) to help break Markov-equivalence ties.

The pure functional JAX port (jax_core.step / jax_core.run) is @jax.jit-compiled; run(..., ticks=..., k=...) marks ticks and k as static so jax.lax.scan length and (2+k)×(2+k) partial-corr blocks stay compile-time constants. See the docs page JAX static arguments for functools.partial patterns that avoid ConcretizationTypeError.

Run

# Synthetic DAG harness (NumPy default; use --backend jax for JIT)
python -m causal_automata.bayesian_synth --n 10
python -m causal_automata.bayesian_synth --n 50 --backend jax
python -m causal_automata.bayesian_synth --n 100

# Benchmark vs gCastle PC / GOLEM (default N=100, k=5, 1-hop)
python -m causal_automata.benchmark
python -m causal_automata.benchmark --n 100 --seed 0 --ticks 100

# Maximum Accuracy Mode (Upgrade 4) — Directed F1 0.696 on the N=100 SEM
python -m causal_automata.benchmark --n 100 --ca-only --k 5 --multihop
python -m causal_automata.benchmark --n 100 --ca-only --k 5 --compare-multihop

python -m causal_automata.benchmark --n 100 --ca-only --k-sweep 5,6,7,8
python -m causal_automata.benchmark --smoke   # device checks + GOLEM init only

Smoke the JAX compile:

python -c "from causal_automata import warmup, run; print(warmup())"

Package layout

causal-automata/
├── causal_automata/
│   ├── __init__.py
│   ├── bayesian.py          # NumPy Bayesian CA step
│   ├── bayesian_synth.py    # Synthetic linear-DAG harness
│   ├── jax_core.py          # JAX @jit step / run
│   └── benchmark.py         # vs gCastle PC / GOLEM
├── docs/                    # Sphinx / Read the Docs
├── tests/
├── .readthedocs.yaml        # uv-based docs install (matches CI)
├── pyproject.toml
├── README.md
└── NOTICE

License / notice

See NOTICE. Copyright 2026 Masakazu Yamagiwa.

Metadata

Release files for causal-automata 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for causal-automata 0.3.0
File Size Uploaded Provenance
causal_automata-0.3.0.tar.gz 32.5 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for causal-automata 0.3.0
File Interpreter ABI Platform
causal_automata-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 62.5 kB

Release files / causal_automata-0.3.0.tar.gz

Download URL causal_automata-0.3.0.tar.gz
Size 32.5 kB
Tags Source
SHA-256 checksum
How to use checksums
f71f1c3305df50efc616d02307b8ecb12e600a291c8fc7aca37443628722a0da
BLAKE2b-256 checksum
How to use checksums
2fc0faee8bd323cbb5cb1fad863494e13252429e5c3c40cb209edcf4937d4783
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / causal_automata-0.3.0-py3-none-any.whl

Download URL causal_automata-0.3.0-py3-none-any.whl
Size 30.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
352e3476b46838ed6b10a4bcd71527de0a8b6acdf6aee8f120bc97a94f7204f2
BLAKE2b-256 checksum
How to use checksums
f0160647a85ef6653620bca272fdfda1f1c0646a136a5372881858c260007cae
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for causal-automata 0.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page