Python 生成长度分布为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

我正在写一个关于辐射传输的代码,生成了各向同性向量,如我的代码所示。我现在不确定如何生成长度分布为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 = 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()