【发布时间】:2013-01-09 17:13:22
【问题描述】:
我想为所有i 和j 计算以下值:
M_ki = Sum[A_ij - A_ik - A_kj + A_kk, 1 <= j <= n]
如何在没有显式循环的情况下使用 Numpy (Python) 来做到这一点?
谢谢!
【问题讨论】:
我想为所有i 和j 计算以下值:
M_ki = Sum[A_ij - A_ik - A_kj + A_kk, 1 <= j <= n]
如何在没有显式循环的情况下使用 Numpy (Python) 来做到这一点?
谢谢!
【问题讨论】:
这是解决此类问题的一般策略。
首先,编写一个小脚本,在两个不同的函数中显式编写循环,最后进行测试,确保两个函数完全相同:
import numpy as np
from numpy import newaxis
def explicit(a):
n = a.shape[0]
m = np.zeros_like(a)
for k in range(n):
for i in range(n):
for j in range(n):
m[k,i] += a[i,j] - a[i,k] - a[k,j] + a[k,k]
return m
def implicit(a):
n = a.shape[0]
m = np.zeros_like(a)
for k in range(n):
for i in range(n):
for j in range(n):
m[k,i] += a[i,j] - a[i,k] - a[k,j] + a[k,k]
return m
a = np.random.randn(10,10)
assert np.allclose(explicit(a), implicit(a), atol=1e-10, rtol=0.)
然后,通过编辑 implicit 逐步矢量化函数,在每一步运行脚本以确保它们继续保持不变:
第一步
def implicit(a):
n = a.shape[0]
m = np.zeros_like(a)
for k in range(n):
for i in range(n):
m[k,i] = (a[i,:] - a[k,:]).sum() - n*a[i,k] + n*a[k,k]
return m
第 2 步
def implicit(a):
n = a.shape[0]
m = np.zeros_like(a)
m = - n*a.T + n*np.diag(a)[:,newaxis]
for k in range(n):
for i in range(n):
m[k,i] += (a[i,:] - a[k,:]).sum()
return m
第 3 步
def implicit(a):
n = a.shape[0]
m = np.zeros_like(a)
m = - n*a.T + n*np.diag(a)[:,newaxis]
m += (a.T[newaxis,...] - a[...,newaxis]).sum(1)
return m
瞧!最后一个没有循环。要矢量化这种方程,broadcasting 是要走的路!
警告:确保explicit 是您要矢量化的方程。我不确定不依赖于j 的术语是否也应该相加。
【讨论】: