Computing the mean square displacement of a 2d random walk in Python

好久不见. 提交于 2020-05-16 08:54:23

问题


I'm simulating a 2-dimensional random walk, with direction 0 < θ < 2π and T=1000 steps. I already have a code which simulates a single walk, repeats it 12 times, and saves each run into sequentially named text files:

a=np.zeros((1000,2), dtype=np.float)
print a                                   # Prints array with zeros as entries

# Single random walk
def randwalk(x,y):              # Defines the randwalk function
    theta=2*math.pi*rd.rand() 
    x+=math.cos(theta);
    y+=math.sin(theta);
    return (x,y)                # Function returns new (x,y) coordinates

x, y = 0., 0.                   # Starting point is the origin
for i in range(1000):           # Walk contains 1000 steps
    x, y = randwalk(x,y)
    a[i,:] = x, y               # Replaces entries of a with (x,y) coordinates

# Repeating random walk 12 times
fn_base = "random_walk_%i.txt"      # Saves each run to sequentially named .txt
for j in range(12):
    rd.seed()                       # Uses different random seed for every run
    x, y = 0., 0.
    for i in range(1000):
        x, y = randwalk(x,y)
        a[i,:] = x, y
    fn = fn_base % j                # Allocates fn to the numbered file
    np.savetxt(fn, a)               # Saves run data to appropriate text file

Now I want to calculate the mean square displacement over all 12 walks. To do this, my initial thought was to import the data from each text file back into a numpy array, eg:

infile="random_walk_0.txt"
rw0dat=np.genfromtxt(infile)
print rw0dat

And then somehow manipulate the arrays to find the mean square displacement.

Is there a more efficient way to go about finding the MSD with what I have?


回答1:


Here is a quick snipet to compute the mean square displacement (MSD). Where path is made of points equally spaced in time, as it seems to be the case for your randwalk. You can just place in the 12-walk for loop and compute it for each a[i,:]

#input path =[ [x1,y1], ... ,[xn,yn] ].

def compute_MSD(path):
   totalsize=len(path)
   msd=[]
   for i in range(totalsize-1):
       j=i+1
       msd.append(np.sum((path[0:-j]-path[j::])**2)/float(totalsize-j))

   msd=np.array(msd)
   return msd



回答2:


First, you don't actually need to store the whole 1000-step walk, just the final position.

Also, there's no reason to store them out to textfiles and load them back, you can just use them in-memory—just put them in a list of arrays, or in an array of 1 more dimension. Even if you need to write them out, you can do that as well as keeping the final values, instead of in place of. (Also, if you're not actually using numpy for performance or simplicity in building the 2D array, you might want to consider building it iteratively, e.g., using the csv module, but that one's more of a judgment call.)

At any rate, given your 12 final positions, you just calculate the distance of each one from (0, 0), then square that, sum them all, and divide by 12. (Or, since the obvious way to compute the distance from (0, 0) is to just add the squares of the x and y positions and then squareroot the result, just skip the squareroot and square at the end.)

But if you want to store each whole walk into a file for some reason, then after you load them back in, walk[-1] gives you the final position as a 1D array of 2 values. So, you can either read those 12 final positions into a 12x2 array and vectorize the mean square distance, or just accumulate them in a list and do it manually.

While we're at it, the rd.seed() isn't necessary; the whole point of a PRNG is that you continue to get different numbers unless you explicitly reset the seed to its original value to repeat them.

Here's an example of dropping the two extra complexities and doing everything directly:

destinations = np.zeros((12, 2), dtype=np.float)
for j in range(12):
    x, y = 0., 0.
    for i in range(1000):
        x, y = randwalk(x, y)
    destinations[j] = x, y

square_distances = destinations[:,0] ** 2 + destinations[:,1] ** 2
mean_square_distance = np.mean(square_distances)


来源:https://stackoverflow.com/questions/26472653/computing-the-mean-square-displacement-of-a-2d-random-walk-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!