Performance 优化平均外积

Performance 优化平均外积,performance,numpy,optimization,matrix,eigenvalue,Performance,Numpy,Optimization,Matrix,Eigenvalue,我目前正在写一个简短的程序来进行一些随机矩阵特征值分布的分析,但是我的分析所需的参数选择使得整个过程非常缓慢。基本上,我应该在下面的函数上循环,最好是大约5000次,最后收集完整的特征值列表 C = np.zeros((N,N)) time_series = np.random.normal(mu,sigma, (N + B*(M-1)) ) for k in range(int(M)): C += np.outer(time_series[k*B : (N) + k*B],

我目前正在写一个简短的程序来进行一些随机矩阵特征值分布的分析,但是我的分析所需的参数选择使得整个过程非常缓慢。基本上,我应该在下面的函数上循环,最好是大约5000次,最后收集完整的特征值列表

C = np.zeros((N,N))
time_series = np.random.normal(mu,sigma,  (N + B*(M-1))    )

for k in range(int(M)):
    C += np.outer(time_series[k*B : (N) + k*B], time_series[k*B : (N) + k*B])
C = C/M

eg_v = np.linalg.eigvalsh(C)
其中N=1000,B约为10,M=100。 然而,有了这些参数的选择,程序在我性能相当好的笔记本电脑上运行大约需要4-5个小时

撇开硬件限制不谈,我能在代码方面做些什么来加速整个过程吗


提前谢谢

您可以使用

因此,以下-

C = np.zeros((N,N))
for k in range(int(M)):
    C += np.outer(time_series[k*B : (N) + k*B], time_series[k*B : (N) + k*B])
可替换为:

# Get the starting indices for each iteration
idx = (np.arange(M)*B)[:,None] + np.arange(N)

# Get the range of indices across all iterations as a 2D array and index 
# time_series with it to give us "time_series[k*B : (N) + k*B]" equivalent  
time_idx = time_series[idx]

# Use broadcasting to perform summation accumulation
C = np.tensordot(time_idx,time_idx,axes=([0],[0]))
tensordot
可以用简单的点积代替:

C = time_idx.T.dot(time_idx)
运行时测试

职能:

def original_app(time_series,B,N,M):
    C = np.zeros((N,N))
    for k in range(int(M)):
        C += np.outer(time_series[k*B : (N) + k*B], time_series[k*B : (N) + k*B])
    return C

def vectorized_app(time_series,B,N,M):
    idx = (np.arange(M)*B)[:,None] + np.arange(N)
    time_idx = time_series[idx]
    return np.tensordot(time_idx,time_idx,axes=([0],[0]))
投入:

In [115]: # Inputs
     ...: mu = 1.2
     ...: sigma = 0.5
     ...: N = 1000
     ...: M = 100
     ...: B = 10
     ...: time_series = np.random.normal(mu,sigma,  (N + B*(M-1))  )
     ...: 
时间:

In [116]: out1 = original_app(time_series,B,N,M)

In [117]: out2 = vectorized_app(time_series,B,N,M)

In [118]: np.allclose(out1,out2)
Out[118]: True

In [119]: %timeit original_app(time_series,B,N,M)
1 loops, best of 3: 1.56 s per loop

In [120]: %timeit vectorized_app(time_series,B,N,M)
10 loops, best of 3: 26.2 ms per loop

因此,我们看到问题中列出的输入加速了60倍

这真让我高兴,非常感谢。修改后的代码现在正在运行,速度明显加快。