如何创建 Rician 随机变量? [英] How to create a Rician random variable?

查看:37
本文介绍了如何创建 Rician 随机变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 Sympy 对信号检测问题进行建模,并且需要两个随机变量.一种使用瑞利分布来模拟噪声,另一种使用 Rician 分布来模拟信号 + 噪声.Sympy 提供瑞利分布,但不是 Rician——或者至少不是一个叫这个名字.

I'm trying to model a signal detection problem using Sympy, and need two random variables. One with a Rayleigh distribution to model noise, and one with a Rician distribution to model signal+noise. Sympy provides a Rayleigh distribution, but not a Rician-- or at least not one by that name.

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

What's the best way of creating one? Does it exist under a different name? Is there a way to manipulate existing distributions into a Rician?

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

Following advice from @asmeurer, I've implemented my own Rice distribution, like so:

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

分布似乎与维基百科Scipy,但奇怪的是我得到的结果与西皮.我会单独问这个问题(提问和回答).

The distribution seems to match both Wikipedia and Scipy, but oddly I'm getting different results than Scipy. I'll ask that question separately (asked and answered).

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

As a side note, the following line makes it possible to lambdify the density function, which includes a Bessel function:

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

它并未推广到所有 Bessel 函数,但适用于 Rician 分布中使用的第一类零阶修正 Bessel.

It's not generalized to all Bessel functions, but works for the zero order modified Bessel of the first kind used in the Rician distribution.

推荐答案

如果您了解 pdf 函数,那么使用 sympy.stats 很容易创建新的发行版.查看 sympy 源 中的现有发行版.您只需要继承 SingleContinuousDistribution 并定义一些方法.例如,这里是正态分布(删除了文档字符串):

If you know the pdf function, it's easy to create a new distribution with sympy.stats. Take a look at the existing distributions in the sympy source. You just need to subclass SingleContinuousDistribution and define some methods. For example, here is the normal distribution (with the docstrings removed):

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

这篇关于如何创建 Rician 随机变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆