2015-10-06 32 views
2

我试图使用Sympy来建模信号检测问题,并且需要两个随机变量。一个用瑞利分布来模拟噪声,另一个用Rician分布来模拟信号+噪声。 Sympy provides a Rayleigh distribution,但不是Rician--或者至少不是那个名字。如何创建一个Rician随机变量?

创建一个最好的方法是什么?它是否以不同的名字存在?有没有办法将现有的发行版操作为Rician?


在从@asmeurer的建议,我已经实现了我自己的莱斯分布,像这样:

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分布中使用的第一种类型。

回答

3

如果您知道pdf函数,可以很容易地使用sympy.stats创建一个新的发行版。看看sympy source中的现有分布。您只需要划分SingleContinuousDistribution并定义一些方法。例如,以下是正常分布(删除文档字符串):

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)) 
+1

也许形式_X = ContinuousRV(x,exp( - (x - mean)** 2 /(2 * std ** 2))/(sqrt(2 * pi)* std))_更容易编写,参数化不受支持。 –

0

是的,你可以从卡方和泊松生成米。看到任何彻底水稻的讨论中,如https://en.wikipedia.org/wiki/Rice_distribution

其中水稻(NU,SIGMA)来自以下步骤的另一种情况:

  1. 生成具有参数的泊松分布P(也意味着,对于泊松)λ= nu^2 /(2 *σ^ 2)。
  2. 生成具有2P + 2自由度的卡方分布的X.
  3. 设置R = sigma * sqrt(X)。
+0

我曾看过该说明,但没有完全理解它。您能够在Sympy代码中显示该工作流程吗?第2步对我来说特别奇怪:它似乎意味着Chi Squared分布的参数本身就是一个随机变量(使用步骤1中的P)? – Omegaman

+0

我不用sympy编程;抱歉。是的,输入是一个随机变量。输出是一个额外维度的分布,将整个分布(值x概率)作为输入并产生(卡方分布x概率)的输出。 – Prune