提交 eadc6e33 authored 作者: Rémi Louf's avatar Rémi Louf 提交者: Brandon T. Willard

Add the Student's t `RandomVariable`

上级 1a3ec8db
...@@ -1370,6 +1370,60 @@ class TruncExponentialRV(ScipyRandomVariable): ...@@ -1370,6 +1370,60 @@ class TruncExponentialRV(ScipyRandomVariable):
truncexpon = TruncExponentialRV() truncexpon = TruncExponentialRV()
class StudentTRV(ScipyRandomVariable):
r"""A Student's t continuous random variable.
The probability density function for `t` in terms of its degrees of freedom
parameter :math:`\nu`, location parameter :math:`\mu` and scale
parameter :math:`\sigma` is:
.. math::
f(x; \nu, \alpha, \beta) = \frac{\Gamma(\frac{\nu + 1}{2})}{\Gamma(\frac{\nu}{2})} \left(\frac{1}{\pi\nu\sigma}\right)^{\frac{1}{2}} \left[1+\frac{(x-\mu)^2}{\nu\sigma}\right]^{-\frac{\nu+1}{2}}
for :math:`\nu > 0`, :math:`\sigma > 0`.
"""
name = "t"
ndim_supp = 0
ndims_params = [0, 0, 0]
dtype = "floatX"
_print_name = ("StudentT", "\\operatorname{StudentT}")
def __call__(self, df, loc=0.0, scale=1.0, size=None, **kwargs):
r"""Draw samples from a Student's t distribution.
Signature
---------
`(), (), () -> ()`
Parameters
----------
df
Degrees of freedom parameter :math:`\nu` of the distribution. Must be
positive.
loc
Location parameter :math:`\mu` of the distribution.
scale
Scale parameter :math:`\sigma` of the distribution. Must be
positive.
size
Sample shape. If the given size is `(m, n, k)`, then `m * n * k`
independent, identically distributed samples are returned. Default is
`None` in which case a single sample is returned.
"""
return super().__call__(df, loc, scale, size=size, **kwargs)
@classmethod
def rng_fn_scipy(cls, rng, df, loc, scale, size):
return stats.t.rvs(df, loc=loc, scale=scale, size=size, random_state=rng)
t = StudentTRV()
class BernoulliRV(ScipyRandomVariable): class BernoulliRV(ScipyRandomVariable):
r"""A Bernoulli discrete random variable. r"""A Bernoulli discrete random variable.
...@@ -2071,4 +2125,5 @@ __all__ = [ ...@@ -2071,4 +2125,5 @@ __all__ = [
"standard_normal", "standard_normal",
"negative_binomial", "negative_binomial",
"gengamma", "gengamma",
"t",
] ]
...@@ -145,6 +145,9 @@ Aesara can produce :class:`RandomVariable`\s that draw samples from many differe ...@@ -145,6 +145,9 @@ Aesara can produce :class:`RandomVariable`\s that draw samples from many differe
.. autoclass:: aesara.tensor.random.basic.StandardNormalRV .. autoclass:: aesara.tensor.random.basic.StandardNormalRV
:members: __call__ :members: __call__
.. autoclass:: aesara.tensor.random.basic.StudentTRV
:members: __call__
.. autoclass:: aesara.tensor.random.basic.TriangularRV .. autoclass:: aesara.tensor.random.basic.TriangularRV
:members: __call__ :members: __call__
......
...@@ -48,6 +48,7 @@ from aesara.tensor.random.basic import ( ...@@ -48,6 +48,7 @@ from aesara.tensor.random.basic import (
poisson, poisson,
randint, randint,
standard_normal, standard_normal,
t,
triangular, triangular,
truncexpon, truncexpon,
uniform, uniform,
...@@ -926,6 +927,48 @@ def test_truncexpon_samples(b, loc, scale, size): ...@@ -926,6 +927,48 @@ def test_truncexpon_samples(b, loc, scale, size):
) )
@pytest.mark.parametrize(
"df, loc, scale, size",
[
(
np.array(2, dtype=config.floatX),
np.array(0, dtype=config.floatX),
np.array(1, dtype=config.floatX),
None,
),
(
np.array(2, dtype=config.floatX),
np.array(0, dtype=config.floatX),
np.array(1, dtype=config.floatX),
[],
),
(
np.array(2, dtype=config.floatX),
np.array(0, dtype=config.floatX),
np.array(1, dtype=config.floatX),
[2, 3],
),
(
np.full((1, 2), 5, dtype=config.floatX),
np.array(0, dtype=config.floatX),
np.array(1, dtype=config.floatX),
None,
),
],
)
def test_t_samples(df, loc, scale, size):
compare_sample_values(
t,
df,
loc,
scale,
size=size,
test_fn=lambda *args, size=None, random_state=None, **kwargs: t.rng_fn(
random_state, *(args + (size,))
),
)
@pytest.mark.parametrize( @pytest.mark.parametrize(
"p, size", "p, size",
[ [
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论