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
12 changes: 0 additions & 12 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,18 +53,6 @@ A current-state audit of the whole `recurrent/` package (parametric intensity,
renewal, regression, nonparametric, competing risks). Findings are grouped by
theme; items already resolved are marked **[done]**.

**B. Dead code / stubs / docs**
- `ParametricRecurrenceRegressionModel` (`parametric_regression.py`) — was a
`# TODO` stub, never imported/exported and a duplicate of
`ParametricRecurrenceModel`; recurrence-regression results are served by
`ProportionalIntensityModel`. **[done]** (file removed)
- `_validate_memory` duplicated verbatim in `renewal/ara.py` and
`renewal/ari.py`.
- 16 copy-pasted docstrings read "Parameters of the Duane model" inside
`CrowAMSAA`/`CoxLewis`.
- `has_left_censoing` typo (`nhpp_fitter.py`, NHPP regression file).
- Doubled `to_xrd()` call in `nonparametric/mcf.py:106-107`.

**C. Simplification**
- The multi-start MLE fit scaffolding is copy-pasted across the four repair
fitters (`GeneralizedRenewal`, `GeneralizedOneRenewal`, `ARA`, `ARI`): the
Expand Down
8 changes: 4 additions & 4 deletions surpyval/recurrent/parametric/crow_amsaa.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def cif(self, x, *params):
x : float
The value at which CIF is evaluated.
params : tuple
Parameters of the Duane model.
Parameters of the Crow-AMSAA model.


Returns
Expand All @@ -85,7 +85,7 @@ def iif(self, x, *params):
x : float
The value at which IIF is evaluated.
params : tuple
Parameters of the Duane model.
Parameters of the Crow-AMSAA model.

Returns
-------
Expand All @@ -108,7 +108,7 @@ def log_iif(self, x, *params):
x : float
The value at which log(IIF) is evaluated.
params : tuple
Parameters of the Duane model.
Parameters of the Crow-AMSAA model.

Returns
-------
Expand All @@ -131,7 +131,7 @@ def inv_cif(self, N, *params):
N : float
The number of events expected to have occured.
params : tuple
Parameters of the Duane model.
Parameters of the Crow-AMSAA model.

Returns
-------
Expand Down
6 changes: 3 additions & 3 deletions surpyval/recurrent/parametric/nhpp_fitter.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def create_negll_func(self, data):

has_interval_censoring = True if 2 in c else False
has_observed = True if 0 in c else False
has_left_censoing = True if -1 in c else False
has_left_censoring = True if -1 in c else False
has_right_censoring = True if 1 in c else False

x_l = x if x.ndim == 1 else x[:, 0]
Expand All @@ -41,8 +41,8 @@ def create_negll_func(self, data):
x_prev_l[c == 1] if has_right_censoring else np.array([])
)

x_left = x_l[c == -1] if has_left_censoing else np.array([])
n_left = n[c == -1] if has_left_censoing else np.array([])
x_left = x_l[c == -1] if has_left_censoring else np.array([])
n_left = n[c == -1] if has_left_censoring else np.array([])

x_i_l = x_l[c == 2] if has_interval_censoring else np.array([])
x_i_r = x_r[c == 2] if has_interval_censoring else np.array([])
Expand Down
10 changes: 6 additions & 4 deletions surpyval/recurrent/regression/nhpp_proportional_intensity.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def create_negll_func(self, data, dist):

has_interval_censoring = True if 2 in c else False
has_observed = True if 0 in c else False
has_left_censoing = True if -1 in c else False
has_left_censoring = True if -1 in c else False
has_right_censoring = True if 1 in c else False

x_l = x if x.ndim == 1 else x[:, 0]
Expand Down Expand Up @@ -112,9 +112,11 @@ def create_negll_func(self, data, dist):
)

# Untangle the left censored data
x_left = x_l[c == -1] if has_left_censoing else np.array([])
n_left = n[c == -1] if has_left_censoing else np.array([])
Z_left = Z[c == -1] if has_left_censoing else np.zeros((1, Z.shape[1]))
x_left = x_l[c == -1] if has_left_censoring else np.array([])
n_left = n[c == -1] if has_left_censoring else np.array([])
Z_left = (
Z[c == -1] if has_left_censoring else np.zeros((1, Z.shape[1]))
)

# Untangle the interval censored data
x_i_l = x_l[c == 2] if has_interval_censoring else np.array([])
Expand Down
14 changes: 3 additions & 11 deletions surpyval/recurrent/renewal/ara.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from surpyval.utils.recurrent_utils import (
handle_xicn,
reject_left_truncation,
validate_memory,
validate_renewal_censoring,
)

Expand Down Expand Up @@ -81,15 +82,6 @@ class ARA:
>>> model = ARA.fit(x, i, c=c, m=2)
"""

@staticmethod
def _validate_memory(m):
if m == np.inf:
return
if not (isinstance(m, (int, np.integer)) and m >= 1):
raise ValueError(
"m must be a positive integer or numpy.inf; got {!r}".format(m)
)

@staticmethod
def _build_sampler(model):
rho = model.rho
Expand Down Expand Up @@ -179,7 +171,7 @@ def fit_from_recurrent_data(self, data, dist=Weibull, m=1, init=None):
RenewalModel
A fitted renewal model.
"""
self._validate_memory(m)
validate_memory(m)
validate_renewal_censoring(data.c, type(self).__name__)
reject_left_truncation(data, type(self).__name__)

Expand Down Expand Up @@ -293,6 +285,6 @@ def fit_from_parameters(self, params, rho, m=1, dist=Weibull):
ARA
An ARA object built from the supplied parameters.
"""
self._validate_memory(m)
validate_memory(m)
model = dist.from_params(params)
return self._make_model(model, rho, m)
14 changes: 3 additions & 11 deletions surpyval/recurrent/renewal/ari.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from surpyval.utils.recurrent_utils import (
handle_xicn,
reject_left_truncation,
validate_memory,
validate_renewal_censoring,
)

Expand Down Expand Up @@ -69,15 +70,6 @@ class ARI:
>>> model = ARI.fit(x, i, m=1, dist=CrowAMSAA)
"""

@staticmethod
def _validate_memory(m):
if m == np.inf:
return
if not (isinstance(m, (int, np.integer)) and m >= 1):
raise ValueError(
"m must be a positive integer or numpy.inf; got {!r}".format(m)
)

@staticmethod
def _build_sampler(model):
dist = model.model.dist
Expand Down Expand Up @@ -185,7 +177,7 @@ def fit_from_recurrent_data(self, data, dist=CrowAMSAA, m=1, init=None):
ARI
A fitted ARI object.
"""
self._validate_memory(m)
validate_memory(m)
validate_renewal_censoring(data.c, type(self).__name__)
reject_left_truncation(data, type(self).__name__)

Expand Down Expand Up @@ -294,5 +286,5 @@ def fit_from_parameters(self, dist_params, rho, m=1, dist=CrowAMSAA):
ARI
An ARI object built from the supplied parameters.
"""
self._validate_memory(m)
validate_memory(m)
return self._make_model(dist, dist_params, rho, m)
15 changes: 15 additions & 0 deletions surpyval/utils/recurrent_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,21 @@ def reject_unsupported_nonparametric(
)


def validate_memory(m: object) -> None:
"""
The Arithmetic Reduction of Age/Intensity models (``ARA``/``ARI``) are
parameterised by an integer memory ``m`` (how many prior failures the
repair acts on), with ``m = numpy.inf`` recovering the infinite-memory
limit. Reject anything that is neither a positive integer nor ``inf``.
"""
if m == np.inf:
return
if not (isinstance(m, (int, np.integer)) and m >= 1):
raise ValueError(
"m must be a positive integer or numpy.inf; got {!r}".format(m)
)


def validate_renewal_censoring(c: npt.ArrayLike, model_name: str) -> None:
"""
The renewal models only define likelihood contributions for exact events
Expand Down
Loading