[SciPy-User] scipy.stats convolution of two distributions
nicky van foreest
vanforeest at gmail.com
Mon Apr 9 17:04:39 EDT 2012
Hi,
In one of my projects I built some code that depends in a nice and
generic way on the methods of rv_continuous in scipy.stats. Now it
turns out that I shot myself in the foot because I need to run a test
with the sum (convolution) of three such distributions. As far as I
can see there is no standard way to achieve this in scipy.stats. Does
anybody know of a good (generic) way to do this? If not, would it
actually be useful to add such functionality to scipy.stats, if
possible at all?
After some struggling I wrote the code below, but this is a first
attempt. I am very interested in obtaining feedback to turn this into
something that is useful for a larger population than just me.
Thanks in advance
Nicky
import numpy as np
import scipy.stats
from scipy.stats import poisson, uniform, expon
import pylab as pl
# I need a grid since np.convolve requires two arrays.
# choose the grid such that it covers the numerically relevant support
# of the distributions
grid = np.arange(0., 5., 0.001)
# I need P(D1+D2+D3 <= x)
D1 = expon(scale = 1./2)
D2 = expon(scale = 1./3)
D3 = expon(scale = 1./6)
class convolved_gen(scipy.stats.rv_continuous):
def __init__(self, D1, D2, grid):
self.D1 = D1
self.D2 = D2
delta = grid[1]-grid[0]
p1 = self.D1.pdf(grid)
p2 = self.D2.pdf(grid)*delta
self.conv = np.convolve(p1, p2)
super(convolved_gen, self).__init__(name = "convolved")
def _cdf(self, grid):
cdf = np.cumsum(self.conv)
return cdf/cdf[-1] # ensure that cdf[-1] = 1
def _pdf(self, grid):
return self.conv[:len(grid)]
def _stats(self):
m = self.D1.stats("m") + self.D2.stats("m")
v = self.D1.stats("v") + self.D2.stats("v")
return m, v, 0., 0.
convolved = convolved_gen(D1, D2, grid)
conv = convolved()
convolved2 = convolved_gen(conv, D3, grid)
conv2 = convolved2()
pl.plot(grid,D1.cdf(grid))
pl.plot(grid,conv.cdf(grid))
pl.plot(grid,conv2.cdf(grid))
pl.show()
More information about the SciPy-User
mailing list