我有以下代码,我使用numpy.dot来加速我的计算。
u = numpy.zeros((l, l))
wp = numpy.zeros((l,2))
# some code which edits u and wp
for x in range(N):
wavg = numpy.dot(wp[:, 0], wp[:, 1])
wp[:, 0] = 1.0/wavg*numpy.dot(u, numpy.multiply(wp[:, 0], wp[:, 1]))
对于小l,最慢的部分是外环。现在我问自己是否有办法摆脱这种循环?
答案 0 :(得分:4)
我仍然对数组的形状以及代码和方程之间的关系感到困惑。
但是只看这个等式,我认为它可以计算为:
document.getElementById('form').style.visibility = 'hidden'; // hide form
目前我关心的是要匹配尺寸;不是最终价值观。计算很简单,它不需要爱因斯坦符号,但In [515]: n,m = 3,4
In [516]: U = np.ones((n,m))
In [517]: w = np.ones((m,))
In [518]: f = np.ones((m,))
In [519]: np.einsum('ij,j,j->i',U,w,f)
Out[519]: array([ 4., 4., 4.])
使翻译几乎是机械的。
einsum
等效于
dot
由于这会随着时间的推移而发展,In [520]: np.dot(U, w*f)
Out[520]: array([ 4., 4., 4.])
的迭代取决于前一个值(以及此外部值f
),因此很难删除该循环;我们可以更快地制作内容。
答案 1 :(得分:1)
预先计算一个术语
的小改进//screendriver.h
class LCDScreenDriver extends ScreenDriver {
protected function output(data){
...very specific ASM code for your LCD monitor goes here..
...this code is very specific to output a -data- buffer
...and nothing more than this
}
}
class ScreenDriver {
protected function output(data); // a virtual pure function
public function printf(args,...){
dataTobePrinted = ..make your own printf methods...
this.output(dataToBePrinted);
}
}
但我们可以做得更好 - 而不是每次都计算平均值,我们可以在最后一次迭代中完成:
u = np.zeros((l, l))
wp = np.zeros((l,2))
# some code which edits u and wp
m = u*wp[:, 1]
for x in range(N):
wavg = np.dot(wp[:, 0], wp[:, 1])
wp[:, 0] = 1.0/wavg*np.dot(m, wp[:, 0])
但还有一件事我们可以做 - 循环可以用矩阵取幂来代替:
m = u*wp[:, 1]
for x in range(N - 1):
wp[:, 0] = np.dot(m, wp[:, 0])
wavg = np.dot(wp[:, 0], wp[:, 1])
wp[:, 0] = 1.0/wavg*np.dot(m, wp[:, 0])
不幸的是,这似乎慢了一些。但是,如果您可以预先计算m = u*wp[:, 1]
wp[:, 0] = np.linalg.matrix_power(m, N-1).dot(wp[:, 0])
wavg = np.dot(wp[:, 0], wp[:, 1])
wp[:, 0] = 1.0/wavg*np.dot(m, wp[:, 0])
,那么它会更快