Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用二进制文件提高计算效率_Python_Python 3.x_Numpy_Binary_Differential Equations - Fatal编程技术网

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

Python 使用二进制文件提高计算效率,python,python-3.x,numpy,binary,differential-equations,Python,Python 3.x,Numpy,Binary,Differential Equations,我迭代求解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.

我迭代求解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], ...

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

在第二次计算中,在第一行,您将
u
v
数组分配到相同的内存位置。也就是说,当您分配给
u[j]
v[j]
时,您将分配给相同的位置,覆盖以前的内容。这将给出一个完全不同的计算

只有在使用cython或类似工具编译代码的情况下,以您所做的方式使用循环才是有效的,这样可以减少python语言类型不明确的常见开销,并且可以在每个步骤中避免
u,v
数组的分配和垃圾收集。Else矢量化操作的numpy机制

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

速度更快。但是,这种形式与相邻节点没有任何耦合。

如何确定“错误”?毕竟,您的SDE有一个随机输入。当然,当您更改计算时,结果会有所不同,您在计算
v[j]
时混合了新旧值。如果
j在范围(-P,P+1)
中,您对
u[-P]
u[P]
都进行了计算,但它们是相同的数组元素。轻微的随机变化不是问题。如果我多次运行第一个代码,图像看起来都很相似。问题是,当我运行第二个代码时,图像看起来完全不同。无论如何,你的代码运行不到一秒钟,所以我不明白为什么你认为每10步将二进制文件写入磁盘会更快。我真正的代码比这复杂得多。同样,N=100,P=50,t=500。我只使用了简单的代码和小的数字来提问啊哈!关于u=v=np.array(np.zeros(N))导致错误的说法是完全正确的。我应该写u,v=np.array(np.zeros(N)),np.array(np.zeros(N))。当我这样做时,两种方法的图像看起来更相似。两幅图像之间仍然存在一些显著的差异。我认为这是由于使用u[j][t]而不是你之前解释的u[j][t-1。啊哈!我犯了一个小小的打字错误。现在两张图片看起来差不多一样了!非常感谢你!这仍然存在效率问题。考虑到我的耦合项,你认为我应该使用cython或类似的循环,还是有其他方法?现在你得到了一个问题,索引'j+P-1'最终超过了数组的上限,在当前形式下,这可以通过使用卷积运算(或
np.polymul
)和后处理来解决。如果耦合后来是非线性的,那么使用数组操作的实现就会变得更复杂。我不太明白。你是说“范围内的k(j-P,j+P)”吗?如果我超过了数组的最后一个元素,我不就是到达了数组的第一个元素吗?我不认为这有什么问题,因为我所有的振荡器都在一个圆圈里。我该如何使用卷积运算?通常你会得到一个错误,只有负的索引会自动结束。//我没有看到一种简单的方法,在循环中为每个移位单独编码旋转可能更容易。