for循环中的Numpy点

时间:2016-05-14 15:24:26

标签: python numpy

我有以下代码,我使用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,最慢的部分是外环。现在我问自己是否有办法摆脱这种循环?

编辑:在数学术语中,此代码看起来像这样 In mathematical Terms this code would look like this

2 个答案:

答案 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]) ,那么它会更快