使用二进制文件提高计算效率

问题描述 投票:0回答:1

我正在迭代求解N个耦合微分方程(u1(t),v1(t),u2(t),v2(t),...)。我有一个由N个振荡器组成的环,每个振荡器都连接到P个邻居。我试图通过不将所有迭代步骤都保存到列表中来提高效率,而是将每10个时间步的结果导出到一个二进制文件中,然后导入该文件,以便随时间推移绘制结果。以下是我未使用二进制文件的旧代码。结果不错,但是效率很低:

import numpy as np
import matplotlib.pyplot as plt

dt = 0.001
ts = np.arange(0, 30, dt)
N, P = 4, 2 

u = np.array([np.zeros(len(ts)) for i in range(N)]) 
v = np.array([np.zeros(len(ts)) for i in range(N)])

def a_u(j,t,P,u,v):
    del_li = []
    for k in range(j-P,j+P):
        del_li.append(u[k][t-1] - u[j][t-1])
    return (u[j][t-1] - ((u[j][t-1])**3)/3 - v[j][t-1] + (1/(4*P))*sum(del_li)) 

for t in range(len(ts)):
    for j in range(-P,P):  

        u[j][t] = u[j][t-1] + a_u(j,t,P,u,v)*dt
        v[j][t] = v[j][t-1] + (u[j][t-1] + 1.05)*dt + np.random.normal(scale=np.sqrt(dt))  

我尝试使用二进制文件使以上代码更快的尝试如下:

u, v = np.array(np.zeros(N)), np.array(np.zeros(N))   

def a_u(j,t,P,u,v):
    del_li = []
    for k in range(j-P,j+P):
        del_li.append(u[k] - u[j])
    return (u[j] - ((u[j])**3)/3 - v[j] + (1/(4*P))*sum(del_li)) 

with open('oscillators.bin', 'wb') as f: # write binary file
    for t in range(len(ts)):
        osc_list = []

        for j in range(-P,P): 

            u[j] += a_u(j,t,P,u,v)*dt  
            v[j] += (u[j] + 1.05)*dt + np.random.normal(scale=np.sqrt(dt))

            if not t % 10:  

                osc_list.append(u[j])
                osc_list.append(v[j])

                if j==P:
                    np.save(f, osc_list) 

fp = open("oscillators.bin", 'rb') # read binary file

a = []
for i in range(int(len(ts)/10)): 
    a.append(np.load(fp))

A = np.array(a) # u[1], v[1], ... = A[:,0], A[:,1], ...

我是否采取了正确的步骤来提高代码效率?我的实际代码比这复杂得多,并且我使用的参数要大得多,因此效率很重要。

python python-3.x numpy binary differential-equations
1个回答
1
投票

在第二行的第一行中,您将uv数组分配到相同的存储位置。即,当您分配给u[j]v[j]时,您分配给相同的位置,将覆盖先前的内容。这将提供完全不同的计算。

使用循环的方式只有在使用cython或类似代码编译代码时才有效率,在这种情况下,类型歧义的python语言的通常开销会减少,并且您可以避免分配和垃圾回收。 u,v数组的每一步。矢量化运算的其他numpy机制

u,v = u - (u**3)/3 - v)*dt, (u + 1.05)*dt + np.random.normal(scale=np.sqrt(dt), size=len(v))

更快。但是,这种形式仍然没有与相邻节点的耦合。

© www.soinside.com 2019 - 2024. All rights reserved.