如何创建一个Rician随机变量?

时间:2015-10-06 23:22:53

标签: python statistics sympy

我正在尝试使用Sympy建模信号检测问题,并需要两个随机变量。一个具有Rayleigh分布来模拟噪声,另一个具有Rician分布来模拟信号+噪声。 Sympy provides a Rayleigh distribution,但不是Rician--至少不是那个名字。

创建一个的最佳方法是什么?它是否以不同的名称存在?有没有办法将现有的分布操作为Rician?

根据@asmeurer的建议,我实施了自己的Rice发行版,如下:

from sympy.stats.crv_types import rv
from sympy.stats.crv import SingleContinuousDistribution

class RicianDistribution(SingleContinuousDistribution):
    _argnames=('nu','sigma')
    @property
    def set(self): return Interval(0,oo)

    def pdf(self,x):
        nu,sigma=self.nu, self.sigma
        return (x/sigma**2)*exp(-(x**2+nu**2)/(2*sigma**2))*besseli(0,x*nu/sigma**2)

def Rician(name,nu,sigma):
    return rv(name,RicianDistribution,(nu,sigma))

分布似乎与WikipediaScipy都匹配,但奇怪的是我得到的结果与Scipy不同。我会单独提出这个问题(asked and answered)。

作为旁注,以下行可以对密度函数进行lambdify,其中包括贝塞尔函数:

printing.lambdarepr.LambdaPrinter._print_besseli=(lambda self,expr: 'i0(%s)'%expr.argument)

它没有推广到所有贝塞尔函数,但适用于Rician分布中使用的第一类零阶修正贝塞尔。

2 个答案:

答案 0 :(得分:3)

如果你知道pdf函数,可以很容易地用sympy.stats创建一个新的发行版。看一下sympy source中的现有分布。您只需要子类class NormalDistribution(SingleContinuousDistribution): _argnames = ('mean', 'std') @staticmethod def check(mean, std): _value_check(std > 0, "Standard deviation must be positive") def pdf(self, x): return exp(-(x - self.mean)**2 / (2*self.std**2)) / (sqrt(2*pi)*self.std) def sample(self): return random.normalvariate(self.mean, self.std) def Normal(name, mean, std): return rv(name, NormalDistribution, (mean, std)) 并定义一些方法。例如,这是正态分布(删除了文档字符串):

SUBSTRING

答案 1 :(得分:0)

是的,你可以用卡方和泊松生成水稻。请参阅任何详细的Rice讨论,例如https://en.wikipedia.org/wiki/Rice_distribution

  

Rice(nu,sigma)的另一个案例来自以下步骤:

     
      
  1. 生成具有参数Poisson分布的P(对于泊松也是平均值)lambda = nu ^ 2 /(2 * sigma ^ 2)。
  2.   
  3. 生成具有2P + 2自由度的卡方分布的X.
  4.   
  5. 设置R = sigma * sqrt(X)。
  6.