1

鉴于这种...

在此处输入图像描述

我必须解释这段代码的作用,知道它使用广播和元素明智的操作概念执行 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 可以将它们转换为相同大小的其他数组,则也可以使用不同大小的数组,这种转换称为广播),用另一个 Nx1 阶的数组减去 1xN 阶的数组,得到阶矩阵 D NxN 包含 x_j - x_1、x_j - x_2 等作为元素,最后,在最后一行计算 alpha 的倒数(这显然是一种排列),其中每个元素乘以每个单元格的 R 评估的总和矩阵 D 乘以 alpha_j 水平(由于参数中的轴 = 1)

问题:

  1. 考虑到我是 Python 新手,我的解释可以吗?
  2. 代码有没有错误?因为我没有看到代码中考虑了每个总和中的“j 必须不同于 1、2、...、n”...如果它实际上是错误的...我该如何解决代码,所以它做的事情与图像中所述的完全一样吗?
4

1 回答 1

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然后用它生成元素乘法。同样,这意味着更清晰的代码。

可以使用as(alpha.reshape(1,-1) * vals).sum(axis=1)替换,从而进一步提高性能。这一步对性能的好处应该是显而易见的。matrix-multiplicatiionnp.dotalpha.dot(vals)

因此,第二步简化为 -

out = (1./alpha) * alpha.dot(vals)
于 2016-09-20T06:42:30.953 回答