【热力】随机游走布朗运动相关模拟

记录一下做的小课题

关于一维,二维,单粒子,多粒子的布朗运动模拟以及图像绘制

因为是随机游走,作图的时候要注意画布(坐标轴)大小要根据随机的最大值倍数设计,要不然会和难看(过大或过小)

 在做多粒子模拟(模块4)的时候遇到了一点麻烦,找不到显示距离的文本迭代的办法,要么根本不变,要么每次叠加,糊成一团,最后用了x轴label,这个自带update的函数,用起来真是十分省心。还有就是批量实例化也调整了很久,最终plt生成图像的那一段应该可以适当优化。

作图汉字乱码依旧要用两行代码解决:

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

最终代码: 

#类模块

import numpy as np
import matplotlib.pyplot as plt
class Brownian():

    def __init__(self,x0=0):

        assert (type(x0)==float or type(x0)==int or x0 is None)
        self.x0 = float(x0)

    def gen_random_walk(self,n_step=100):

        if n_step < 30:
            print("数据太少了!")

        w = np.ones(n_step)*self.x0

        for i in range(1,n_step):
            yi = np.random.choice([1,-1])
            # Weiner process
            w[i] = w[i-1]+(yi/np.sqrt(n_step))

        return w

    def gen_normal(self,n_step=100):
        if n_step < 30:
            print("WARNING! The number of steps is small. It may not generate a good stochastic process sequence!")

        w = np.ones(n_step)*self.x0

        for i in range(1,n_step):
            # Sampling from the Normal distribution
            yi = np.random.normal()
            # Weiner process
            w[i] = w[i-1]+(yi/np.sqrt(n_step))

        return w
#可执行模块1:一维随机游走

import matplotlib.pyplot as plt
from Brown import Brownian

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

b = Brownian()

branch = 50
nstep = 5000

for i in range(branch):
    plt.plot(b.gen_random_walk(nstep),linewidth = 0.5)
    pass

plt.title('一维随机游走  '+ str(branch)+'条轨迹  '+str(nstep)+'步')

plt.savefig('一维随机游走50轨迹.png')
plt.show()

 

 

#可执行模块2:单粒子等步长随机游走

import random
import matplotlib.animation as animation
import matplotlib.pyplot as plt
import numpy as np
import math
from Brown import Brownian

def init():
    xmax, xmin, ymax, ymin = x.max(), x.min(), y.max(), y.min()
    scale_factor = 1.15
    xmax, xmin, ymax, ymin = xmax * scale_factor, xmin * scale_factor, ymax * scale_factor, ymin * scale_factor
    mmax = max(xmax,ymax)
    mmin = min(xmin,ymin)
    plt.xlim(mmin, mmax)
    plt.ylim(mmin, mmax)
    # plt.xlim(xmin, xmax)
    # plt.ylim(ymin, ymax)
    pass



def update(frames):

    xdata.append(x[frames])
    ydata.append(y[frames])
    line.set_data(xdata,ydata)

    return line,

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

fig, ax = plt.subplots()
xdata = []
ydata = []
line, = plt.plot(xdata,ydata,marker='.',markersize=5,linewidth=0.7,color = 'red')

# 随机游走(二维)

nstep = 100
steplength = 0.5
chalist = []

b1 = Brownian()
b2 = Brownian()

x = b1.gen_normal(nstep)
# 通过等步长构建y
y = [0]*nstep

for i in range(nstep-1):
    chalist.append((x[i+1] - x[i])**2)
    pass

steplength = math.sqrt(max(chalist)+min(chalist))

for i in range(nstep-1):
    m = steplength**2-(x[i+1] - x[i])**2
    chazhi = math.sqrt(m)
    y[i+1] = y[i] + random.choice([chazhi,chazhi*(-1)])
    pass
y = np.array(y)

ani = animation.FuncAnimation(
    fig,
    update,
    frames = nstep,
    init_func=init
)


plt.title('随机游走(二维等步长)  '+ str(nstep) + '步')
ani.save('二维随机游走(等步长).gif')
plt.show()

 

 

#可执行模块3:单粒子随机游走

import matplotlib.animation as animation
import matplotlib.pyplot as plt
from Brown import Brownian

def init():
    xmax, xmin, ymax, ymin = x.max(), x.min(), y.max(), y.min()
    scale_factor = 1.25
    xmax, xmin, ymax, ymin = xmax * scale_factor, xmin * scale_factor, ymax * scale_factor, ymin * scale_factor
    plt.xlim(xmin, xmax)
    plt.ylim(ymin, ymax)
    pass



def update(frames):

    xdata.append(x[frames])
    ydata.append(y[frames])
    line.set_data(xdata,ydata)

    return line,

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

fig, ax = plt.subplots()
xdata = []
ydata = []
line, = plt.plot(xdata,ydata,marker='.',markersize=5,linewidth=0.7)

# 随机游走(二维)

nstep = 30

b1 = Brownian()
b2 = Brownian()

x = b1.gen_normal(nstep)
y = b2.gen_normal(nstep)

ani = animation.FuncAnimation(
    fig,
    update,
    frames = nstep,
    init_func=init
)


plt.title('随机游走(二维)  '+ str(nstep) + '步')
ani.save('二维随机游走.gif')
plt.show()

 

 

#可执行模块4:10粒子随机游走

import matplotlib.animation as animation
import matplotlib.pyplot as plt
import numpy as np

from Brown import Brownian

def init():
    global xmin,ymin
    xmax, xmin, ymax, ymin = 0,0,0,0
    for i in x:
        if xmax < max(i):
            xmax = max(i)
        if xmin > min(i):
            xmin = min(i)
            pass
    for i in y:
        if ymax < max(i):
            ymax = max(i)
        if ymin > min(i):
            ymin = min(i)
            pass

    scale_factor = 1.10
    xmax, xmin, ymax, ymin = xmax * scale_factor, xmin * scale_factor, ymax * scale_factor, ymin * scale_factor
    plt.xlim(xmin, xmax)
    plt.ylim(ymin, ymax)
    pass

def update(frames):
    global dis
    for i in range(branch):
        datax[i].append(x[i][frames])
        datay[i].append(y[i][frames])
        dis = np.sqrt(datax[i][frames] ** 2 + datay[i][frames] ** 2) + dis
        line[i].set_data(datax[i], datay[i])
        pass
    text1 =str('距原点平均值:' + str(round(float(dis)/10,4)))
    ax.set_xlabel(text1,fontsize=18)
    dis = 0

    return line

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

fig, ax = plt.subplots(figsize = (15,15))
nstep = 50
branch = 10
dis = 0
xmin = 0
ymin = 0

datax = list(range(branch))
datay = list(range(branch))

# 构建一系列空列表,datax,datay的每个元素都是一个空列表
# datax,datay用来迭代数据(append)

for i in range(branch):
    datax[i] = []
    datay[i] = []
    pass

# 储存实例
ex = list(range(branch))
ey = list(range(branch))

for i in range(branch):
    ex[i] = Brownian()
    ey[i] = Brownian()
    pass

# 储存遍历数据
x,y = [],[]

# 批量实例化,对每个粒子的x(y)坐标进行赋值 x(y)列表每个元素为一串随机数组

for i in range(branch):

    x.append(list(ex[i].gen_normal(nstep)))
    y.append(list(ey[i].gen_normal(nstep)))

    pass

# 创建图像
line = ln = plt.plot([], [],
                     [], [],
                     [], [],
                     [], [],
                     [], [],
                     [], [],
                     [], [],
                     [], [],
                     [], [],
                     [], [],
marker='.',markersize=5,linewidth=0.7)

plt.title('随机游走(二维)  '+ str(nstep) + '步'+str(branch) + '粒子',fontsize=18)



ani = animation.FuncAnimation(
    fig,
    update,
    frames = nstep,
    init_func=init
)

ani.save('二维随机游走(多粒子).gif')

plt.show()

 

 

#可执行模块5:粒子落点正态分布

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

def init():
    xmax, xmin, ymax, ymin = x.max(), x.min(), y.max(), y.min()
    scale_factor = 1.15
    xmax, xmin, ymax, ymin = xmax * scale_factor, xmin * scale_factor, ymax * scale_factor, ymin * scale_factor
    plt.xlim(xmin, xmax)
    plt.ylim(ymin, ymax)
    pass

def update(frames):

    xdata = x[frames]
    ydata = y[frames]
    plt.plot(xdata,ydata,'bo',markersize=3.)

    pass

# 散点数
n = 500

x,y = np.random.randn(2,n)

fig, ax = plt.subplots()
xdata = []
ydata = []

ani = animation.FuncAnimation(
    fig,
    update,
    frames = n,
    init_func=init,
    interval = 15
)

ani.save('散点正态分布.gif')

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值