python - numpy 中更快的矩阵计算

标签 python numpy math

给定一个 nxn 矩阵 M 和一个 n 向量 X: this paper ,是否有一些更快的变体来计算以下矩阵(来自 G_ij = sqrt(M_ij^2 + ((X_i - X_j)/M_ij)^2 + 2X_i^2 + 2X_j^2)/2 ) ?

我目前的计算如下:

#M, X are given as numpy arrays
G = np.zeros((n,n))
for i in range(0,n):
    for j in range(i,n):
        xi = X[i]
        if i == j:
            G[i,j] = abs(xi)
        else:
            xi2 = xi*xi
            xj = X[j]
            xj2 = xj*xj
            mij = M[i,j]
            mid = (xi2 - xj2)/mij
            top =  mij*mij + mid*mid + 2*xi2 + 2*xj2
            G[i,j] = math.sqrt(top)/2

这非常慢,但我怀疑有一种更好的“numpythonic”方法可以代替循环......

编辑:虽然所有答案都有效并且比我天真的实现要快得多,但我选择了我基准测试中最快的一个。谢谢!

最佳答案

实际上非常简单。

import math
import numpy as np

n = 5
M = np.random.rand(n, n)
X = np.random.rand(n)

您的代码和结果:

G = np.zeros((n,n))
for i in range(0,n):
    for j in range(i,n):
        xi = X[i]
        if i == j:
            G[i,j] = abs(xi)
        else:
            xi2 = xi*xi
            xj = X[j]
            xj2 = xj*xj
            mij = M[i,j]
            mid = (xi2 - xj2)/mij
            top =  mij*mij + mid*mid + 2*xi2 + 2*xj2
            G[i,j] = math.sqrt(top)/2
array([[0.77847813, 5.26334534, 0.8794082 , 0.7785694 , 0.95799072],
       [0.        , 0.15662266, 0.88085031, 0.47955479, 0.99219171],
       [0.        , 0.        , 0.87699707, 8.92340836, 1.50053712],
       [0.        , 0.        , 0.        , 0.45608367, 0.95902308],
       [0.        , 0.        , 0.        , 0.        , 0.95774452]])

使用广播:

temp = M**2 + ((X[:, None]**2 - X[None, :]**2) / M)**2 + 2 * (X[:, None]**2) + 2 * (X[None, :]**2)
G = np.sqrt(temp) / 2
array([[0.8284724 , 5.26334534, 0.8794082 , 0.7785694 , 0.95799072],
       [0.89251217, 0.25682736, 0.88085031, 0.47955479, 0.99219171],
       [0.90047282, 1.10306597, 0.95176428, 8.92340836, 1.50053712],
       [0.85131766, 0.47379576, 0.87723514, 0.55013345, 0.95902308],
       [0.9879939 , 1.46462011, 0.99516443, 0.95774481, 1.02135642]])

请注意,您没有直接对对角线元素使用公式,而仅针对 G 的上三角区域进行计算。我只是实现了计算所有 G[i, j] 的公式。

注意:如果M的对角线元素不重要并且它们包含一些零,只需添加一些偏移量以避免被零除 错误如下:

M[np.arange(n), np.arange(n)] += 1e-5

# Do calculation to get G

# Assign diagonal to X
G[np.arange(n), np.arange(n)] = abs(X)

关于python - numpy 中更快的矩阵计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65018845/

相关文章:

Java:Math.random() Max Value (double just less than 1)

python - 如何使用PyQt发送http请求?

python - numpy 矩阵子集 View

python - 我如何判断一个 numpy bool 数组是否只包含一个 `True` block ?

json - 如何在 F# 中对数学向量类型进行 JSON 序列化?

r - 如何绘制具有精确起点和终点的弯曲箭头?

python - opencv python 检测多尺度 api

python - 生成继承层次结构的依赖树

python - 使用 Tensorflow 2.0 使用多个 GPU 进行训练时出现错误 : Out of range: End of sequence

python - 用 numpy 数组中的元组替换整数?