From ec4821ee4e2d38b09f651b6eae9857104cf4281d Mon Sep 17 00:00:00 2001 From: Aadya Chinubhai <77720426+aadya940@users.noreply.github.com> Date: Tue, 5 Sep 2023 20:50:44 +0530 Subject: [PATCH] Add sampler class for F-distribution in tensor.random.basic --- aesara/tensor/random/basic.py | 46 +++++++++++++++++++++++++++++++ tests/tensor/random/test_basic.py | 14 ++++++++++ 2 files changed, 60 insertions(+) diff --git a/aesara/tensor/random/basic.py b/aesara/tensor/random/basic.py index 5dd529a4f2..44a6bbd66d 100644 --- a/aesara/tensor/random/basic.py +++ b/aesara/tensor/random/basic.py @@ -2194,6 +2194,51 @@ def __call__(self, x, **kwargs): random = uniform +class FRV(RandomVariable): + r"""An F-distribution continuous random variable. + + The probability density function for `F` in terms of its degrees of freedom parameters `dfn` and `dfd` is: + + .. math:: + + f(x; dfn, dfd) = \frac{\sqrt{\frac{(dfn \cdot x)^{dfn} \cdot dfd^{dfd}}{(dfn \cdot x + dfd)^{dfn + dfd}}}}{x \cdot \text{Beta}(\frac{dfn}{2}, \frac{dfd}{2})} + + for :math:`x > 0`, :math:`dfn > 0`, and :math:`dfd > 0`. + + """ + name = "f" + ndim_supp = 0 + ndims_params = [0, 0] + dtype = "floatX" + _print_name = ("F", "\\operatorname{F}") + + def __call__(self, dfn=1, dfd=1, size=None, **kwargs): + r"""Draw samples from an F-distribution. + + Signature + --------- + + `() -> ()` + + Parameters + ---------- + dfn + Degrees of freedom parameter for the numerator. Must be positive. + dfd + Degrees of freedom parameter for the denominator. Must be positive. + size + Sample shape. If the given size is, e.g. `(m, n, k)` then `m * n * k` + independent, identically distributed random variables are + returned. Default is `None` in which case a single random variable + is returned. + + """ + return super().__call__(dfn, dfd, size=size, **kwargs) + + +f = FRV() + + __all__ = [ "permutation", "choice", @@ -2242,4 +2287,5 @@ def __call__(self, x, **kwargs): "rayleigh", "power", "zipf", + "f", ] diff --git a/tests/tensor/random/test_basic.py b/tests/tensor/random/test_basic.py index 4a9f11e1ff..d5b8dc19be 100644 --- a/tests/tensor/random/test_basic.py +++ b/tests/tensor/random/test_basic.py @@ -27,6 +27,7 @@ choice, dirichlet, exponential, + f, gamma, gengamma, geometric, @@ -1513,3 +1514,16 @@ def test_pickle(): a_unpkl = pickle.loads(a_pkl) assert a_unpkl.owner.op._props() == sample_a.owner.op._props() + + +@pytest.mark.parametrize( + "dfn, dfd", + [ + (1, 1), + (2, 2), + (5, 10), + (10, 5), + ], +) +def test_f_samples(dfn, dfd): + compare_sample_values(f, dfn, dfd)