0

I have created a class which represents a statistical simulation. One aspect of that is a distribution of p-values, and the class contains methods characterizing that distribution:

class Simulation:
    ...
    def pdf_p(self, p):
        ...
    def cdf_p(self, p):
        ...
    def ppf_p(self, P):
        ...
    def rvs_p(self, size):
        ...

I would now like to expose that distribution also as a scipy.stats-style distribution object. To do so, the __init__ method of my class contains a statement

self.p = PValueDist(self.pdf_p, self.cdf_p, self.ppf_p, self.rvs_p)

where the class PValueDist is defined as

from scipy.stats import rv_continuous

class PValueDist (rv_continuous):
    def __init__(self, pdf, cdf, ppf, rvs):
        self._pdf = pdf
        self._cdf = cdf
        self._ppf = ppf
        self._rvs = rvs
        super().__init__(self)

This seems to work, but I'm wondering whether it is the right or canonical way to do it?

Of course I could also make Simulation a subclass of rv_continuous and rename my methods. However, the simulation comprises several different distributions, and identifying the simulation with one of them doesn't seem semantically correct.

A. Donda
  • 8,381
  • 2
  • 20
  • 49

1 Answers1

1

Seems OK. Several things to watch out for: 1) scipy.stats distributions are instances, so don't forget to create one, 2) if the support is not a default ((0, inf) IIRC), set them in the__init__ .

ev-br
  • 24,968
  • 9
  • 65
  • 78
  • 1) I did instantiate, as shown in the question. Or do I misunderstand something? 2) I thought that's the default support of parameters, not of the RV itself? Anyway, it's p-values, so the support is [0, 1]. – A. Donda Jan 18 '21 at 22:16
  • 1
    By the support I mean the support of the distribution, `[a, b]`, where, say, `pdf(x)` takes `x\in [a, b]`. If it's `[0, 1]`, then you want `super().__init__(self, a=0, b=1)` and define `_argcheck` – ev-br Jan 19 '21 at 19:18
  • "Whether a shape parameter is valid is decided by an _argcheck method (which defaults to checking that its arguments are strictly positive.)" – My distribution doesn't have numerical parameters, it represents a specific fixed distribution defined by the copied methods, so AFAICS `_argcheck` doesn't apply. – A. Donda Jan 21 '21 at 00:15
  • But you seem to be right about `a=0, b=1` though. – A. Donda Jan 21 '21 at 00:18
  • Since I don't have parameters, I'm wondering whether I should inherit from `rv_frozen`? – A. Donda Jan 21 '21 at 00:40
  • Inheriting from rv_frozen is unlikely to do much good. Just inherit from rv_coutinuous – ev-br Jan 22 '21 at 18:08