【问题标题】:Mean square displacement of a 1d random walk in pythonpython中一维随机游走的均方位移
【发布时间】:2020-12-09 07:42:27
【问题描述】:

我想计算一维轨迹的所有时间的均方位移。我是新手程序员,所以我通过模拟随机游走进行了尝试。

import numpy as np
import matplotlib.pyplot as plt

# generate random walk
path = np.zeros(60)
position = 0
for i in range(1, path.size):
    move = np.random.randint(0, 2)
    if move == 0: position += -1
    else: position += 1
    path[i] = position

# returns a vector of MSDs from a given path
def calcMSD(data):
    msd = np.zeros(data.size - 1)
    for i in range(1, data.size):
        squareddisplacements = (data[i:] - data[:data.size - i])**2
        msd[i - 1] = squareddisplacements.mean()
    return msd

msd = calcMSD(path)
plt.plot(msd)
plt.show()

我是否正确实施了这一点?感谢您提供任何和所有建议,谢谢。

【问题讨论】:

  • “走路”是什么意思?
  • 路径生成部分看起来不错。我不相信calcMSD。你到底想计算什么?您是从一条路径计算它,您不想对一堆路径进行平均吗?我只是不知道这里的目标,最好是你解释一下或发布一个链接到你试图复制的任何计算。此外,您可能缺少msd[i - 1] = np.sqrt(squareddisplacements.mean()) 中的平方根,并且可能缺少“i”除法?再次真的取决于您要计算的内容
  • @piterbarg 感谢您的回复。我正在尝试计算每个时间间隔与起始位置的平均平方距离。因此,如果我有 60 个时间点,我将首先计算大小为 1、大小为 2、然后一直到大小为 60 的时间间隔。在 60 时,只有该大小的 1 步,所以它只会计算终点到起点的距离。例如,如果 p(t) 为您提供作为时间函数的位置,那么我在 t = 1 时尝试计算的内容将是: [p(1) - p(0))**2 + (p( 2) - p(1))**2 + … + (p(n) - p(n - 1))**2] / n
  • @Luke 在我看来,您的代码正是这样做的。您的代码可以简化一点。例如,您的路径循环可以是简单的for i in range(1, path.size): path[i] = path[i-1] + 2*np.random.randint(0, 2)-1。同样在calcMSD 函数中,data[:data.size - i] 可以用更 Pythonic 的方式编写为data[:- i]。否则对我来说看起来不错

标签: python tracking particles random-walk


【解决方案1】:

均方位移

均方位移的定义

为了确保我们在定义上达成一致,均方位移 (MSD) 是在特定步骤中粒子集合(在我们的例子中是步行者)到原点的平方距离的平均值。

因为我们是一维的,所以距离就是绝对位置:时间 t = | 的距离路径[t] |

要在第 t 步得到 MSD,我们必须在第 t 步取所有平方位置,然后取结果数组的平均值。

这意味着:MSD at step t == (path[:, t]**2).mean()(逐元素平方使得取绝对值毫无用处)

path[:, t] 在这里表示:每个 walker 在步骤 t 的位置。

生成路径

我们必须稍微修改一下您的代码以拥有多个独立路径。

walkers = 50 # Example for 50 walkers
path = []
steps = 60
for walker in range(walkers):
    walker_path=[0]
    position = 0
    for i in range(1, steps):
        move = np.random.randint(0, 2)
        if move == 0: position += -1
        else: position += 1
        walker_path.append(position)
    path.append(walker_path)
path = np.array(path)

作为旁注,您还可以使用 random.choice 直接随机选择 -1 或 1,如下所示:

for i in range(1, steps):
    position += np.random.choice([-1, 1])
    walker_path.append(position)

从现在开始,路径是一个二维数组:每条步行者路径一行。

每一步获取 MSD

为了获得每一步的所有 MSD,我们将 t 从 1 变为步数。

您可以在 Python 中的列表推导中执行此操作(并摆脱您的 calcMSD 函数):

msd = [(path[:, i]**2).mean() for i in range(1, steps)] 
# you could also put range(1, len(path[0]))

结果

您的函数不适用于绘制多个步行者。

建议的解决方案会给你这样的东西:

你想要什么

我希望我明白你真正想要什么。我不知道它是如何调用的,但它也可以在列表理解中计算。考虑单个步行者的路径:

not_msd = [(np.array([path[start:start+sep+1] for start in range(steps-sep)])**2).mean() for sep in range(1, steps)]

我们从开始到开始 + 步来获取相距 step 步的两个位置之间的差异。我们重现这个操作,从 0 开始到列表的末尾。然后我们将得到的列表平方并取平均值。

我们对所有步长都这样做:从 1 到整个长度。

结果:

【讨论】:

  • 感谢您的明确答复。我想我误解了如何计算 MSD。假设 p(t) 是作为时间函数的位置。如果我对您的理解正确,那么在 t = 3 时,您将计算: [ p(1)**2 + p(2)**2 + p(3)**2 ] / 3 我将尝试解释我的正在尝试。我认为您需要计算由某个数字 t 分隔的时间点之间的位置差异。所以对于 t = 3 我认为它会是: [ (p(3) - p(0))**2 + (p(4) - p(1))**2 + (p(5) - p( 2))**2 + … (p(n) - p(n - 3))**2 ] / (中间有 3 个步骤的时间点数。
  • 我对 MSD 的定义是错误。我将每个步骤的平均值与特定步骤中所有位置的平均值混淆了。您需要几个步行者才能拥有一个 MSD,否则 MSD 将只是您单条路径的正方形。我编辑了我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多