Python 生成长度分布为exp(-x/lambda)的各向同性步长
我正在写一个关于辐射传输的代码,生成了各向同性向量,如我的代码所示。我现在不确定如何生成长度分布为exp(-x/lambda)的各向同性步长。有什么建议吗Python 生成长度分布为exp(-x/lambda)的各向同性步长,python,function,random,montecarlo,Python,Function,Random,Montecarlo,我正在写一个关于辐射传输的代码,生成了各向同性向量,如我的代码所示。我现在不确定如何生成长度分布为exp(-x/lambda)的各向同性步长。有什么建议吗 def isotropic_unit_vectors(): nparticles = 1000 lambda_a = 45 lambda_s = 0.3 sigma_a = 1/lambda_a sigma_s = 1/lambda_s sigma_T = sigma_a + sigma_s lambda_T = 1/sigma_T u
def isotropic_unit_vectors():
nparticles = 1000
lambda_a = 45
lambda_s = 0.3
sigma_a = 1/lambda_a
sigma_s = 1/lambda_s
sigma_T = sigma_a + sigma_s
lambda_T = 1/sigma_T
u = np.random.uniform(low = 0, high =1, size = 1000)
step = -lambda_T*np.log(u)
theta = 2*np.pi*np.random.rand(nparticles)
phi = np.arccos(2*np.random.rand(nparticles)-1)
dx = step*np.cos(theta)*np.cos(phi)
dy = step*np.cos(theta)*np.sin(phi)
dz = step*np.sin(theta)
rand = np.column_stack((dx,dy,dz))
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(dx, dy, dz, c='r', marker='.')
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')
plt.show()
return rand
编辑:我希望多个粒子从0,0,0开始,然后随机移动 我假设您想用CDF生成随机数;F(x)=exp(-x/lambda),对于x的有效支持,例如0Ok,您有正确的位和块,但它们在一起并不完全正确。下面是它的外观,Python 3.7,Anaconda WIndows 10 x64
import numpy as np
def isotropic_unit_vectors():
"""Generates troika of directional cosines isotropically on the sphere"""
cs_theta = 2.0 * np.random.random() - 1.0
sn_theta = np.sqrt((1.0 - cs_theta)*(1.0 + cs_theta))
phi = 2.0 * np.pi * np.random.random()
wx = sn_theta * np.cos(phi)
wy = sn_theta * np.sin(phi)
wz = cs_theta
return (wx, wy, wz)
def random_step(λ):
u = 1.0 - np.random.random() # NB! avoids log(0)
return -λ * np.log(u)
nparticles = 100
λ_a = 45 # absorbtion
λ_s = 0.3 # scattering
# cross-sections
σ_a = 1/λ_a
σ_s = 1/λ_s
σ_t = σ_a + σ_s
λ_t = 1/σ_t
trajectories = {} # dictionary for all trajectories
for k in range(0, nparticles):
trajectory = []
# initialize particle position
x = 0.0
y = 0.0
z = 0.0
print(f"Partile number {k+1}")
print(f" Position {x}, {y}, {z}")
trajectory.append((x, y, z))
while True:
(wx, wy, wz) = isotropic_unit_vectors() # sample direction
step = random_step(λ_t)
# make step and find new position
x += wx * step
y += wy * step
z += wz * step
print(f" Position {x}, {y}, {z}")
trajectory.append((x, y, z))
# simulate absorbtion
if np.random.random() < σ_a/σ_t:
trajectories[k] = trajectory
break # absorbtion, end of trajectory, next particle would be tracked
else:
pass # scattering, continue with this trajectory
但是您已经有了正确生成为
u=np.random.uniform(低=0,高=1,大小=1000)的步长;步骤=-lambda\u T*np.log(u)
问题出在哪里?我想我有点困惑了。这一部分是有意义的,但我希望x,y,z,(0)在0,0,0处随机移动。好吧,已经有代码做了完全正确的事情:u=np.random.uniform(低=0,高=1,大小=1000);步骤=-lambda_T*np.log(u)。指数采样看起来还可以。我在前面的函数中有:。。。对于范围(20)内的i:u=np.random.uniform(low=0,high=1,size=10**7)lamda=45长度=-lamda*np.log(u)我希望x,y,z(0)在0,0,0处,然后以exp(x/lamba)的形式分布长度的步长。不确定这是否有意义,但感谢您的帮助!啊,我明白了。因此,最初您处于(0,0,0),然后您希望采取以下步骤,即遵循分布?台阶沿x、y和z的长度是否应相同?如果不是,三个方向上的步骤是否相互独立?是。步长应遵循分布,但x、y、z不必相同。它们将结合在一起得到单位向量r。我有点不确定如何将每个新的x,y,z写入每个粒子的表中。我需要用它来绘制一个图表来显示一个随机行走。@KatieP请检查更新,我添加了代码来存储轨迹,它并没有被测试,所以生成了一个步骤数组,但我认为它在初始条件x,y,z=0上“重新附加”。@KatieP不,它没有。我添加了绘图代码来检查它是否正常
from mpl_toolkits import mplot3d
import matplotlib.pyplot as plt
fig = plt.figure()
ax = plt.axes(projection='3d')
# Data for a three-dimensional line
k = 7 # print particle #8
trj = trajectories[k]
xline = [x for x, y, z in trj]
yline = [y for x, y, z in trj]
zline = [z for x, y, z in trj]
# plot trajectory
ax.plot3D(xline, yline, zline, 'gray')
# plot vertices
xpts = [x for x, y, z in trj]
ypts = [y for x, y, z in trj]
zpts = [z for x, y, z in trj]
rpts = [np.sqrt(x*x+y*y+z*z) for x, y, z in trj]
ax.scatter3D(xpts, ypts, zpts, c=rpts, cmap='hsv')
plt.show()