Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 18 additions & 8 deletions acopula/compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -366,21 +366,31 @@ def compile_model(
``model_fn`` expects. Values are used only to drive oryx's
tracer; pass any sensible defaults (e.g.
``{"theta": 1.0}``).
method: Density evaluation backend. ``"bell"`` uses the
polynomial-powering scan (recommended for nested >= 2
levels), ``"single_layer"`` is the closed-form unnested
formula, ``"nested"`` falls back to numerical integration
via the implicit-LST solver. ``"auto"`` picks ``"bell"``
for depth > 1 else ``"single_layer"``.
method: Density-evaluation backend:

- ``"auto"`` (default): ``"bell"`` for depth > 1, else
``"single_layer"``.
- ``"bell"``: polynomial-powering scan (recommended for
nested copulas; the only backend that supports
``with_censored_mask``).
- ``"single_layer"``: closed-form unnested formula (flat
copulas only).
- ``"integral"``: numerical inverse-Laplace integration —
the only backend that uses ``ils_method`` / ``ils_params``.
survival: Treat marginals as survival functions
``S(t) = 1 - F(t)`` rather than CDFs. Required for the
HACSurv-style joint survival likelihood.
with_censored_mask: If True, the returned ``ll_fn`` takes a
third ``censored_mask`` argument so callers can ``vmap``
per-observation masks. Forces ``method="bell"`` since the
other backends do not support dynamic censoring.
ils_method: Implicit-LST solver for ``method="nested"``.
ils_params: Extra params for the implicit solver.
ils_method: Inverse-Laplace solver used **only** by
``method="integral"`` — e.g. ``"cohen"`` (default),
``"euler"``, ``"post_widder"``. **Ignored by ``"bell"`` and
``"single_layer"``**, which assemble the density analytically
and never invert a Laplace transform.
ils_params: Extra params for that solver; likewise **only used by
``method="integral"``** and ignored by the other backends.

Returns:
A :class:`CompiledModel` holding the frozen graph, flattener,
Expand Down
25 changes: 13 additions & 12 deletions acopula/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,25 +151,26 @@ def __call__(self, children: Iterable[Union["Node", "Leaf", jax.Array]]) -> "Nod


def copula(cls):
"""Decorator to create a copula class with dataclass-like syntax.
"""Class decorator for defining a copula family with dataclass-style
parameters.

Usage:
Generates an ``__init__`` from the type-annotated class attributes,
makes the class inherit from `Copula`, and registers the parameters —
while preserving every user-defined method. Instances accept positional
or keyword arguments.

Examples:
```python
@copula
class Clayton:
theta: float

def generator(self, u: jax.Array) -> jax.Array:
def generator(self, u):
return (1.0 + u) ** (-1.0 / self.theta)

# Can instantiate with positional or keyword arguments
c1 = Clayton(2.0)
c2 = Clayton(theta=2.0)

This automatically:
- Makes the class inherit from Copula
- Generates an __init__ method from type annotations
- Preserves all user-defined methods
- Handles parameter registration
c1 = Clayton(2.0) # positional
c2 = Clayton(theta=2.0) # keyword
```
"""
# Get type annotations in definition order
annotations = getattr(cls, "__annotations__", {})
Expand Down
2 changes: 1 addition & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ plugins:
filters: ["!^_"] # hide private / dunder members
show_source: false
summary: true
heading_level: 2
heading_level: 3 # section headers are ## (h2); symbols nest as h3
# Emits /llms.txt (an index for LLMs/agents, per llmstxt.org) plus a single
# concatenated llms-full.txt of the whole site.
- llmstxt:
Expand Down
Loading