首页 > 其他 > 详细

蒙特卡罗方法(二):各类分布的抽样方法(直接、挑选、对称、复合、加、乘加抽样)、光子康普顿散射后的能量分布

时间:2021-03-28 22:19:35      阅读:53      评论:0      收藏:0      [点我收藏+]

导入相关库,编写作图函数

"""
已知分布的随机抽样
2020.11.10
"""
import numpy as np
import matplotlib.pyplot as plt
import time
import matplotlib
from scipy import optimize
matplotlib.rcParams[‘font.sans-serif‘] = [‘SimHei‘]  #将默认字体font...改为黑体
matplotlib.rcParams[‘axes.unicode_minus‘] = False    #有负号不正常显示,使负号不显示

def plot_hist(arr, bins, title):
    plt.hist(arr, bins)
    plt.title(title)
    plt.xlabel(‘抽样值‘)
    plt.ylabel(‘频数‘)
    plt.savefig(title+‘.jpg‘)
    plt.show()

题1

技术分享图片

技术分享图片
time1 = time.process_time_ns()
‘‘‘题一‘‘‘

直接抽样

time1 = time.process_time_ns()
‘‘‘题一‘‘‘
# 直接抽样
arr = np.random.uniform(size=(3, 10000000))**2   # 抽样得到随机数s的平方
arr = arr.max(axis=0)    # 对每一列的三个随机数s做max(s1,s2,s3)
plot_hist(arr, np.linspace(0, 1, 1000),‘题一:直接抽样‘)   # 作图

time2 = time.process_time_ns()
print(‘直接抽样运行时间: ‘, (time2-time1)*10**-6, ‘毫秒, 抽样个数为:‘, arr.size)

技术分享图片

挑选抽样

技术分享图片
技术分享图片

# 挑选抽样
xf = np.array([])
for i in range(100000):
    s1 = np.random.uniform()   # 抽取s1
    s2 = np.random.uniform()   # 抽取s2
    if np.sqrt(s2)>s1:
        xf = np.append(xf,s2)
plot_hist(xf,np.linspace(0,1,300),‘题一:挑选抽样‘)

# 方法二
s1 = np.random.uniform(size=100000)
s2 = np.sqrt(np.random.uniform(size=100000))
xf = np.array([])
for s1,s2 in zip(s1,s2):
    if (s2)>s1:
        xf = np.append(xf,s2)
xf = xf**2                                             # 千万要注意,判断时用"根号s",取值时用s 。所以要平方回来
plot_hist(xf,np.linspace(0,1,100),‘题一:挑选抽样1‘)

# 方法三
s1arr = np.random.uniform(size=100000)
s2arr = np.random.uniform(size=100000)
s3arr = np.random.uniform(size=100000)
xf = np.array([])
for s1,s2,s3 in zip(s1arr,s2arr,s3arr):
    s2 = np.max([s2,s3])
    if s2>s1:
        xf = np.append(xf,s2**2)
plot_hist(xf,np.linspace(0,1,100),‘题一:挑选抽样1‘)

time1 = time.process_time_ns()
# 方法四:快速矩阵方法
s1 = np.random.uniform(size=10000000)
s2 = np.max(np.random.uniform(size=10000000*2).reshape(2,10000000),axis=0)
a = (s2-s1)
a[a<0] = 0
a[a>0] = 1
s2=s2*a   # 相当于选取了符合挑选条件s1<s2的部分
s2 = s2[s2>0]   # 清洗掉0项
s2 = s2**2      # max相当于开根号,现在平方回来
plot_hist(s2,np.linspace(0,1,100),‘题一:挑选抽样2‘)
time2 = time.process_time_ns()
print(‘直接抽样运行时间: ‘, (time2-time1)*10**-9, ‘秒, 抽样次数为:‘, s1.size)

抽样分布如图:
技术分享图片

题二 : 对称抽样

技术分享图片

技术分享图片

‘‘‘题二  对称抽样‘‘‘
xf = np.array([])
for i in range(100000):
    s1 = np.random.uniform()
    s2 = np.random.uniform()
    if s1<=0.5*(1+2*s2-1):
        xf = np.append(xf, 2*s2-1)
    else:
        xf = np.append(xf, 1-2*s2)
plot_hist(xf,np.linspace(-1,1,300),‘题二:对称抽样‘)

# 矩阵方法
s1 = np.random.uniform(size=100000)
s2 = np.random.uniform(size=100000)
a = 0.5*(1+2*s2-1)-s1
a[a>0] = 1
a[a<0] = -1
xf = (2*s2-1)*a
plot_hist(xf,np.linspace(-1,1,100),‘题二:对称抽样2‘)

技术分享图片

题三: 乘加抽样光子康普顿散射后的能量分布

技术分享图片

技术分享图片

‘‘‘题三:乘加抽样,光子康普顿散射能量分布‘‘‘

# 入射粒子能量,单位(mc**2)
a = 0.3
k = (1-(2*a+2)/a**2)*np.log(1+2*a)+0.5+4/a - 1/(2*(2*a+1)**2)

def H1(x):
    z = -( 2*a/(k+2*k*a) * ((a+1-x)**2)/a**2 + 1/x )
    return z

result1 = optimize.fminbound(H1,1,5,full_output=True)
m1 = -result1[1]
print(‘最小值计算结果:‘,result1,‘, 最大值为:‘,m1)
def H2(x):
    z = -( 2*a/k * (1/x - 1/x**2) )
    return z
result2 = optimize.fminbound(H2,1 ,5, full_output=True)
m2 = -result2[1]
print(‘最小值计算结果:‘,result2,‘, 最大值为:‘,m2)

line = m1/(m1+m2)
print(‘加抽样部分判断条件:‘,line)


xf = np.array([])
for i in range(100000):
    s1 = np.random.uniform()
    if s1 <= line:
        condition=True
        while condition:
            xf1 = (1+2*a) / (1+2*a-2*a*np.random.uniform())
            s2 = np.random.uniform()
            if  s2 <= -H1(xf1) / m1:
                xf = np.append(xf, xf1)
                condition=False
    else:
        condition2 = True
        while condition2:
            xf2 = 1+2*a*np.random.uniform()
            s2 = np.random.uniform()
            if s2 <= -H2(xf2)/m2:
                xf = np.append(xf,xf2)
                condition2 = False
plot_hist(xf,np.linspace(1,1+2*a,300),‘乘加抽样,光子康普顿散射能量分布‘)

技术分享图片

题四: 复合抽样

技术分享图片

技术分享图片

‘‘‘题四:复合抽样‘‘‘
xfarr = np.array([])
for i in range(10000):
    yf = np.random.uniform()
    xf = yf*np.random.uniform()
    xfarr = np.append(xfarr,xf)
plot_hist(xfarr,np.linspace(0,1,100),‘题四:复合抽样‘)

技术分享图片

题五 : 加抽样

技术分享图片

技术分享图片

‘‘‘题五:自选-加抽样‘‘‘
xf = np.array([])
for i in range(100000):
    s0 = np.random.uniform()
    s1 = np.random.uniform()
    s2 = np.random.uniform()
    if s0 <= 0.5:
        xf1 = np.log(s1)
        xf = np.append(xf,xf1)
    else:
        xf2 = -1*np.log(1-s2)
        xf = np.append(xf,xf2)
plot_hist(xf,np.linspace(-10,10,300),‘题五:加抽样解‘)

技术分享图片

蒙特卡罗方法(二):各类分布的抽样方法(直接、挑选、对称、复合、加、乘加抽样)、光子康普顿散射后的能量分布

原文:https://www.cnblogs.com/mayuhua/p/14589555.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!