来自 scipy.stats.rv_continuous 个不需要的上限的自定义 PDF
Custom PDF from scipy.stats.rv_continuous unwanted upper-bound
我正在尝试生成具有特定光度的 QSO 的随机概率密度函数,其形式为:
1/( (L/L_B^* )^alpha + (L/L_B^* )^beta )
其中 L_B^*、alpha 和 beta 都是常量。为此,使用以下代码:
import scipy.stats as st
logLbreak = 43.88
alpha = 3.4
beta = 1.6
class my_pdf(st.rv_continuous):
def _pdf(self,l_L):
#"l_L" in this is always log L
L = 10**(l_L/logLbreak)
D = 1/(L**alpha + L**beta)
return D
dist_Log_L = my_pdf(momtype = 0, a = 0,name='l_L_dist')
distro = dist_Log_L.rvs(size = 10000)
(L/L^* 被提升为 10 的幂,因为一切都是在对数尺度上完成的)
该分布应该生成一个近似于 this, trailing off to infinity, but in reality the graph it produces looks like this(10,000 个样本)的图形。无论使用多少样本,上限都是相同的。是否有原因限制它的方式?
您的 PDF 未正确规范化。 PDF 在域上的积分必须为 1。您的 PDF 积分大约为 3.4712:
In [72]: from scipy.integrate import quad
In [73]: quad(dist_Log_L._pdf, 0, 100)
Out[73]: (3.4712183965415373, 2.0134487716044682e-11)
In [74]: quad(dist_Log_L._pdf, 0, 800)
Out[74]: (3.4712184965748905, 2.013626296581202e-11)
In [75]: quad(dist_Log_L._pdf, 0, 1000)
Out[75]: (3.47121849657489, 8.412130378805368e-10)
这将破坏 class 对 inverse transform sampling 的实现。它只会从域中生成样本,直到 PDF 从 0 到 x 的积分首先达到 1.0,在您的情况下约为 2.325
In [81]: quad(dist_Log_L._pdf, 0, 2.325)
Out[81]: (1.0000875374350238, 1.1103202107010366e-14)
事实上,这就是您在直方图中看到的内容。
作为验证问题的快速修复,我将 _pdf()
方法的 return
语句修改为:
return D/3.47121849657489
和 运行 再次编写您的脚本。 (在真正的修复中,该值将是其他参数的函数。)然后命令
In [85]: import matplotlib.pyplot as plt
In [86]: plt.hist(distro, bins=31)
生成此图:
我正在尝试生成具有特定光度的 QSO 的随机概率密度函数,其形式为:
1/( (L/L_B^* )^alpha + (L/L_B^* )^beta )
其中 L_B^*、alpha 和 beta 都是常量。为此,使用以下代码:
import scipy.stats as st
logLbreak = 43.88
alpha = 3.4
beta = 1.6
class my_pdf(st.rv_continuous):
def _pdf(self,l_L):
#"l_L" in this is always log L
L = 10**(l_L/logLbreak)
D = 1/(L**alpha + L**beta)
return D
dist_Log_L = my_pdf(momtype = 0, a = 0,name='l_L_dist')
distro = dist_Log_L.rvs(size = 10000)
(L/L^* 被提升为 10 的幂,因为一切都是在对数尺度上完成的)
该分布应该生成一个近似于 this, trailing off to infinity, but in reality the graph it produces looks like this(10,000 个样本)的图形。无论使用多少样本,上限都是相同的。是否有原因限制它的方式?
您的 PDF 未正确规范化。 PDF 在域上的积分必须为 1。您的 PDF 积分大约为 3.4712:
In [72]: from scipy.integrate import quad
In [73]: quad(dist_Log_L._pdf, 0, 100)
Out[73]: (3.4712183965415373, 2.0134487716044682e-11)
In [74]: quad(dist_Log_L._pdf, 0, 800)
Out[74]: (3.4712184965748905, 2.013626296581202e-11)
In [75]: quad(dist_Log_L._pdf, 0, 1000)
Out[75]: (3.47121849657489, 8.412130378805368e-10)
这将破坏 class 对 inverse transform sampling 的实现。它只会从域中生成样本,直到 PDF 从 0 到 x 的积分首先达到 1.0,在您的情况下约为 2.325
In [81]: quad(dist_Log_L._pdf, 0, 2.325)
Out[81]: (1.0000875374350238, 1.1103202107010366e-14)
事实上,这就是您在直方图中看到的内容。
作为验证问题的快速修复,我将 _pdf()
方法的 return
语句修改为:
return D/3.47121849657489
和 运行 再次编写您的脚本。 (在真正的修复中,该值将是其他参数的函数。)然后命令
In [85]: import matplotlib.pyplot as plt
In [86]: plt.hist(distro, bins=31)
生成此图: