Skip to content

Commit

Permalink
fix l_poly compatibility with rv_frozen
Browse files Browse the repository at this point in the history
  • Loading branch information
jorenham committed May 22, 2024
1 parent a8182cd commit 00c85fb
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 2 deletions.
17 changes: 15 additions & 2 deletions lmo/distributions.py
Original file line number Diff line number Diff line change
Expand Up @@ -861,15 +861,28 @@ def l_kurtosis(self, trim: AnyTrim | None = None) -> float:
"""
return float(self.l_ratio(4, 2, trim=trim))

# `rv_continuous` and `rv_frozen` compatibility

@property
def dist(self) -> type[Self]: # noqa: D102
return type(self)

@property
def args(self) -> _LPolyParams: # noqa: D102
return (self._l_moments, self._trim)

@property
def kwds(self) -> dict[str, Any]: # noqa: D102
return {}

@classmethod
def freeze(
def freeze( # noqa: D102
cls,
lmbda: lnpt.AnyVectorFloat,
/,
trim: AnyTrim = 0,
**kwds: Any,
) -> Self:
"""For compatibility with `rv_generic`."""
return cls(lmbda, trim, **kwds)

@overload
Expand Down
60 changes: 60 additions & 0 deletions lmo/typing/_scipy.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,29 @@ def nnlf(

@runtime_checkable
class RVDiscrete(RV, Protocol):
"""
Runtime-checkable interface for discrete probability distributions,
like [`scipy.stats.rv_discrete`][scipy.stats.rv_discrete] subtype
instances.
Examples:
>>> import numpy as np
>>> from scipy.stats import distributions as distrs
>>> isinstance(distrs.binom, RVDiscrete)
True
Continuous distributions aren't included:
>>> isinstance(distrs.norm, RVDiscrete)
False
Note that for "frozen" distributions (a.k.a. random variables),
this is not the case:
>>> isinstance(distrs.binom(5, .42), RVDiscrete)
False
"""

@property
def inc(self) -> int: ...

Expand Down Expand Up @@ -741,6 +764,21 @@ def expect(

@runtime_checkable
class RVDiscreteFrozen(RVFrozen[_RV_D_co], Protocol[_RV_D_co]):
"""
Runtime-checkable interface for discrete probability distributions,
like [`scipy.stats.rv_discrete`][scipy.stats.rv_discrete] subtype
instances.
Examples:
>>> import numpy as np
>>> from scipy.stats import distributions as distrs
>>> isinstance(distrs.bernoulli, RVDiscreteFrozen)
False
>>> isinstance(distrs.bernoulli(.42), RVDiscreteFrozen)
True
>>> isinstance(distrs.uniform(), RVDiscreteFrozen)
False
"""
@overload
def pmf(self, k: _Real0D) -> _F8: ...
@overload
Expand All @@ -760,6 +798,28 @@ def logpmf(self, k: lnpt.AnyArrayFloat) -> lnpt.Array[_ND1, _F8]: ...

@runtime_checkable
class RVContinuousFrozen(RVFrozen[_RV_C_co], Protocol[_RV_C_co]):
"""
Runtime-checkable interface for discrete probability distributions,
like [`scipy.stats.rv_discrete`][scipy.stats.rv_discrete] subtype
instances.
Examples:
>>> import numpy as np
>>> from scipy.stats import distributions as distrs
>>> isinstance(distrs.uniform, RVContinuousFrozen)
False
>>> isinstance(distrs.uniform(), RVContinuousFrozen)
True
>>> isinstance(distrs.bernoulli(.5), RVContinuousFrozen)
False
>>> from lmo.distributions import l_poly
>>> isinstance(l_poly([0, 1/6]), RVContinuousFrozen)
True
>>> isinstance(l_poly, RVContinuousFrozen)
True
"""

@overload
def pdf(self, x: _Real0D) -> _F8: ...
@overload
Expand Down

0 comments on commit 00c85fb

Please sign in to comment.