Metadata-Version: 2.4
Name: avoidance-cascade
Version: 0.1.0
Summary: Python implementation of avoidance cascade detection for ternary agents
Author: SuperInstance
License-Expression: MIT
License-File: LICENSE
Keywords: avoidance,cascade,contagion,simulation,tipping-point
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering
Requires-Python: >=3.10
Provides-Extra: dev
Requires-Dist: pytest-cov; extra == 'dev'
Requires-Dist: pytest>=7; extra == 'dev'
Description-Content-Type: text/markdown

# avoidance-cascade-python

Python implementation of **avoidance cascade detection for ternary agents**.

Agents hold one of three states: **+1** (engaged), **0** (neutral), **−1** (avoiding). The library detects when avoidance begins to cascade through a population, models how it spreads, identifies tipping points, and simulates interventions.

## Installation

```bash
pip install avoidance-cascade
```

For development:

```bash
git clone https://github.com/SuperInstance/avoidance-cascade-python.git
cd avoidance-cascade-python
pip install -e ".[dev]"
```

## Quick Start

### Detect a cascade

```python
from avoidance_cascade import CascadeDetector

det = CascadeDetector(window_size=10, threshold=0.5)

# Each call is one time-step; pass a list of agent states
det.observe([1, 0, -1, -1, -1, 0, -1, 1, -1, -1])  # 6/10 avoiding → alert!

print(det.avoidance_ratio)  # 0.6
print(len(det.alerts))      # 1
```

### Model contagion spread

```python
from avoidance_cascade import SpreadModel

model = SpreadModel(population_size=200, contagion_rate=0.35, contact_degree=5, seed=42)
model.seed_avoiders([0, 1, 2])

result = model.simulate(steps=50)
print(f"Peak avoidance: {result.peak_avoidance_ratio:.2%} at step {result.peak_avoidance_step}")
print(f"Estimated R0:   {result.r0_estimate:.3f}")
```

### Detect tipping points

```python
from avoidance_cascade import TippingPointDetector

tp = TippingPointDetector(method="combined", threshold=0.5)
events = tp.analyze([0.05, 0.10, 0.20, 0.45, 0.55, 0.80])

for e in events:
    print(f"Step {e.step}: {e.method} — {e.metric_before:.2f} → {e.metric_after:.2f}")
```

### Simulate interventions

```python
from avoidance_cascade import SpreadModel, InterventionSimulator, Strategy

model = SpreadModel(population_size=100, contagion_rate=0.4, contact_degree=4, seed=42)
model.seed_avoiders([0, 1])

sim = InterventionSimulator(model, seed=42)

# Compare all strategies
results = sim.compare_all(apply_at_step=10, steps=50)
for r in results:
    print(f"{r.strategy.value:15s}  reduction={r.reduction:+.2%}  final={r.final_avoidance_ratio:.2%}")
```

## API Reference

### `CascadeDetector`

| Parameter | Type | Default | Description |
|---|---|---|---|
| `window_size` | `int` | 10 | Rolling window length |
| `threshold` | `float` | 0.5 | Avoidance ratio trigger |
| `alert_handler` | `Callable` | `None` | Callback for alerts |

**Methods:** `observe(population)`, `run(history)`, `reset()`

**Properties:** `avoidance_ratio`, `engaged_ratio`, `neutral_ratio`, `alerts`, `step`

### `SpreadModel`

| Parameter | Type | Default | Description |
|---|---|---|---|
| `population_size` | `int` | 100 | Number of agents |
| `contagion_rate` | `float` | 0.3 | Per-contact transmission probability |
| `contact_degree` | `int` | 4 | Neighbours per step |
| `recovery_rate` | `float` | 0.05 | Spontaneous recovery probability |
| `seed` | `int \| None` | `None` | RNG seed |

**Methods:** `seed_avoiders(indices)`, `seed_engaged(indices)`, `step()`, `simulate(steps)`, `reset()`

### `TippingPointDetector`

| Parameter | Type | Default | Description |
|---|---|---|---|
| `method` | `str` | `"combined"` | Detection method |
| `threshold` | `float` | 0.5 | Ratio threshold |
| `velocity_threshold` | `float` | 0.1 | Min step-to-step change |
| `accel_threshold` | `float` | 0.05 | Min second-derivative |

**Methods:** `observe(ratio)`, `analyze(ratios)`, `reset()`

### `InterventionSimulator`

| Strategy | Description |
|---|---|
| `VACCINATE` | Lock neutral agents as engaged |
| `QUARANTINE` | Reset all avoiders to neutral |
| `CENSOR` | Halve the contact degree |
| `BOOST_ENGAGED` | Convert neutrals to engaged |

**Methods:** `baseline(steps)`, `simulate_intervention(strategy, ...)`, `compare_all(...)`

## Running Tests

```bash
PYTHONPATH=src pytest tests/ -v
```

## License

MIT © SuperInstance
