Metadata-Version: 2.5
Name: remflow
Version: 0.1.1
Summary: Relational event models for ordered sender-receiver data in Python.
Project-URL: Repository, https://github.com/damianfraszczak/REMFlow
Project-URL: Documentation, https://remflow.readthedocs.io/en/stable/
License-Expression: MIT
License-File: LICENSE
Requires-Python: >=3.11
Requires-Dist: numpy<2.4,>=1.26
Requires-Dist: pandas>=2.1
Requires-Dist: scipy>=1.11
Provides-Extra: benchmark-cuda
Requires-Dist: cupy-cuda12x>=14; extra == 'benchmark-cuda'
Provides-Extra: dev
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Provides-Extra: docs
Requires-Dist: myst-parser<5,>=3; extra == 'docs'
Requires-Dist: sphinx-rtd-theme<4,>=3; extra == 'docs'
Requires-Dist: sphinx<9,>=7; extra == 'docs'
Provides-Extra: gpu
Requires-Dist: jax<0.8,>=0.4.30; extra == 'gpu'
Description-Content-Type: text/markdown

# REMFlow: relational event modeling in Python

REMFlow implements relational event models (REMs) for ordered sender-receiver
interactions. For each observed event, it constructs the set of events that
could have occurred and evaluates time-varying network statistics for the
observed and alternative events.

The package fits conditional event-choice models for ordinal data and intensity
models for exact or duration data. It supports tie-oriented and actor-oriented
specifications, model diagnostics, and next-event prediction. The general
high-level facade supports untyped and typed tie-oriented events. A dedicated
misinformation subclass adds descriptive actor-role and group-similarity
measures and evaluates actor removal in the conditional next-event
distribution.

## Installation

REMFlow requires Python 3.11 or newer. Install the released package from
PyPI:

```bash
python -m pip install remflow
```

Only for development from a source checkout, use an editable install:

```bash
python -m pip install -e .
```

For development and documentation work:

```bash
python -m pip install -e ".[dev,docs]"
```

JAX support is optional:

```bash
python -m pip install "remflow[gpu]"
```

For GPU use, install the JAX build appropriate for the local CUDA setup. An
explicit `backend="jax:gpu"` request fails with `BackendUnavailable` if JAX
cannot see a GPU; it does not fall back to the CPU.

The optional CuPy dependency is used only by the CUDA comparison benchmarks:

```bash
python -m pip install "remflow[benchmark-cuda]"
```

## A small example

The following example fits an exact-time model with inertia, reciprocity, and
outgoing two-path statistics:

```python
import pandas as pd

from remflow import diagnostics, remify, remstats, remstimate

events = pd.DataFrame(
    {
        "time": [1.0, 2.0, 3.0, 4.0, 5.0],
        "sender": ["A", "B", "A", "C", "B"],
        "receiver": ["B", "A", "C", "A", "C"],
    }
)

history = remify(events, actors=["A", "B", "C"], ordinal=False)
statistics = remstats(
    history,
    tie_effects="~ inertia() + reciprocity() + otp()",
    first=2,
)
fit = remstimate(history, statistics, backend="numpy")

print(fit.summary())
print(diagnostics(fit, history, statistics).summary())
```

Set `ordinal=True` to fit a conditional event-choice model instead. Public
actor, dyad, type, and event identifiers are 1-based; the input labels remain
available in the history dictionaries.

The formula language is intentionally restricted and never calls `eval` or
`exec`. The same effects can also be assembled with the Python builder API.

## What is implemented

Event histories may be directed or undirected and may use exact, ordinal, or
duration time. The preprocessing code handles simultaneous and typed events,
weights, actor and dyad attributes, manual opportunity sets, and sampled tie
risk sets. For larger datasets, `remify(..., ncores=2)` can build risk sets
concurrently without changing their order.

The statistics module includes inertia, reciprocity, degree effects, shared
partners, participation shifts, recency, rank, active-state effects, and user
covariates. Both string formulas and typed effect objects preserve term order.

The main estimation paths are:

- tie-oriented and actor-oriented ordinal or exact-time MLE;
- HMC for supported tie and actor models;
- interval and ordinal duration MLE;
- sampled tie likelihoods;
- frequentist penalties, random effects, finite mixtures, and moving windows;
- Bayesian shrinkage in its documented NumPy paths.

Fits retain coefficient order, covariance information, convergence status,
backend metadata, fitted probabilities, and the data needed by the available
diagnostics. AIC, BIC, AICC, and WAIC are provided where their required inputs
exist.

The general `RelationalEventModel` facade works with untyped or typed events.
`MisinformationModel` extends it with action and stance conventions,
descriptive actor-role scores, source ranking, echo-chamber metrics, and a
conditional next-event intervention. The intervention is not a full cascade
simulator or a causal estimator.

## Current limitations

Several combinations are rejected explicitly because their statistical or
backend implementation is not complete:

- type-expanded actor risk sets and actor case-control sampling;
- Bayesian frailty/random-effects models and general Bayesian duration models;
- WAIC for mixture, random-effects, and duration fits;
- non-constant concomitant formulas in mixture models;
- JAX execution for mixtures, random effects, penalties, and shrinkage;
- duration attribution with `remtribute`.

Text embeddings and stance labels are not generated by REMFlow. Supply them
as covariates if an analysis needs them.

## Backends

Use `backend="numpy"`, `"jax"`, `"jax:cpu"`, or `"jax:gpu"`. The default
`numpy` backend runs on the CPU. For model families with a JAX implementation,
`jax:cpu` and `jax:gpu` place the likelihood and derivative calculations on the
requested device. Both implementations use float64, and the test suite checks
their numerical agreement. Fit metadata records the selected backend,
platform, device, precision, JAX version, and compilation state.

`engine="auto"` currently selects SciPy. The optimizer engine and array backend
are separate choices: selecting SciPy does not prevent supported objective or
gradient work from running through JAX.

## GPU benchmark

The hardware-gated suite was run using an NVIDIA GeForce RTX
4070 Laptop GPU (8 GiB), Python 3.12.3, JAX/JAXLIB 0.7.2, CUDA 12, and float64.
All 11 GPU tests passed without CPU fallback.

The measurements below are means from 10 likelihood-and-gradient evaluations
after JAX compilation. They measure the numerical kernel, not event
preprocessing or total fitting time.

| Actors | Events | Risk set | NumPy | JAX GPU | Speedup | Maximum gradient error |
|---:|---:|---:|---:|---:|---:|---:|
| 50 | 1,000 | 2,450 | 176.330 ms | 5.734 ms | 30.75x | 2.13e-14 |
| 100 | 1,000 | 9,900 | 419.867 ms | 11.055 ms | 37.98x | 2.49e-14 |

Warm-up took 3.208 seconds for 50 actors and 11.220 seconds for 100 actors.
Measured peak GPU memory was 165.42 MiB and 512.00 MiB, respectively. To rerun
the checks and benchmark:

```bash
REMFLOW_REQUIRE_GPU=1 JAX_ENABLE_X64=true python -m pytest -q tests/gpu
python benchmarks/run_gpu_study.py --repeats 10 --include-large
```

Small problems may be faster with NumPy because JAX compilation and device
transfer overhead dominate the computation.

## Development checks

```bash
uv run python -m pytest
uv run python -m ruff check .
uv run python -m mypy src
uv run python -m sphinx -W --keep-going -b html docs docs/_build/html
```

The physical-GPU tests run only when compatible hardware is available and
`REMFLOW_REQUIRE_GPU=1` is set.

## Documentation

- [Source repository](https://github.com/damianfraszczak/REMFlow)
- [Read the Docs: Quick start](https://remflow.readthedocs.io/en/stable/QUICK_START.html)
- [Introduction](docs/INTRODUCTION.md)
- [Quick start](docs/QUICK_START.md)
- [Usage guide](docs/USAGE.md)
- [API reference](docs/api.rst)
- [Performance evaluation](docs/BENCHMARKING.md)
- [Classroom event study](docs/CLASSROOM_EVENT_STUDY.md)

## License

REMFlow is released under the [MIT License](LICENSE). The classroom dataset in
`data/classroom_events/` keeps its upstream CC BY-NC-ND 4.0 license and is not
covered by the project license. Provenance and reuse terms are recorded with
the data.
