2016-09-20 47 views
1

鉴于这种......矢量化评估,广播单元方式操作

enter image description here

我要解释这个代码做什么,知道它执行F的量化评估,利用广播,元素明智的操作理念......

def F(x_pos, alpha): 
    D = x_pos.reshape(1,-1) - x_pos.reshape(-1,1) 
    return (1./alpha) * (alpha.reshape(1,-1) * R(D)).sum(axis=1) 

我的解释是:

函数F的第一行接收x_pos和alpha作为参数(均为numpy数组),在第二行中,通过广播计算矩阵D(基本操作,如数组中的加法numpy是元素执行的,即元素但如果numpy可以将它们转换成其他尺寸相同的其他尺寸,那么也可以使用不同大小的arranys,这种转换称为广播),将Nx1的另一个序列减去1xN的序列,得到矩阵D的包含x_j - x_1,x_j - x_2等等的顺序NxN作为元素,最后,在最后一行中计算alpha的倒数(显然是一种排列),其中每个元素乘以每个元素的R评估值之和矩阵D的单元格水平地乘以alpha_j(由于参数中的轴= 1)

问题:

  1. 考虑到我是新来的Python,我的解释好吗?
  2. 该代码有错误或没有?因为我没有看到每个数字中的“j必须与1,2,...,n不同”在代码中被考虑到......并且如果它实际上是错误的......我该如何修复该代码与图像中所陈述的完全相同?

回答

0

这里可以提出一些意见/改进/修复。

1]第一步可以只引入一个新的轴,并与自身相减,像这样被交替做 -

D = x_pos[:,None] - x_pos 

在我看来,这是一个更清洁的选择。性能优势可能只是边际。

2]在第二行中,我认为需要修复,因为我们需要避免计算R(D)的对角线元素。所以,如果我得到了正确,更正后的代码会 -

vals = R(D) 
np.fill_diagonal(vals,0) 
out = (1./alpha) * (alpha.reshape(1,-1) * vals).sum(axis=1) 

现在,让我们做一下代码更地道/清洁剂。

在该行,我们可以写:(alpha * vals)而不是alpha.reshape(1,-1) * vals。这是因为,如下面的示意图中的形状已经对broadcasting对齐 -

alpha :  n 
vals : n x n 

因此,alpha将自动延长到2D与其元件沿着所述第一轴线为vals然后的elementwise长度广播乘法与它一起产生。再次,这意味着更清洁的代码。

这里还有一个进一步的性能改进,(alpha.reshape(1,-1) * vals).sum(axis=1)可以用matrix-multiplicatiion替换,使用​​作为alpha.dot(vals)。这一步应该注意到性能的好处。

因此,第二步骤减小到 -

out = (1./alpha) * alpha.dot(vals) 
+0

'X_POS [:,无] - x_pos'几乎肯定会慢一些,因为它具有解析切片,而是仅由具有可忽略的恒定量,并且肯定是更地道 – Eric

+0

Divakar ...谢谢你,但我觉得你没看过我的问题... – OiciTrap

+0

@Oici看看编辑的文本和代码有意义吗? – Divakar