【问题标题】:Numpy.Matmul and Numpy.Dot: Accelerating code by using Numpy in-built functionsNumpy.Matmul 和 Numpy.Dot:使用 Numpy 内置函数加速代码
【发布时间】:2020-12-10 15:26:48
【问题描述】:

我正在尝试加速我的代码中的一个函数。

我写的初始函数是:

def f(self):
    temp = 0
    for i in range(self.N):
        for j in range(self.N):
            a = self.Asolution[:, j]
            b = self.Bsolution[:, i]
            c = self.Matrix[j][i]

            d = c*np.multiply(a, b)
            temp += simps(d, self.time)
    return temp

self.Asolution = odeint(...) 的位置,self.Bsolution 的位置相同。

self.Matrix 是大小为self.N x self.N 的方阵,simps 是辛普森积分。 self.Asolutionself.Bsolution 的尺寸为 (t x N)。

但是,我需要多次调用这个函数,而且由于self.N 很大,所以耗时太长。因此,我决定尝试使用 numpy 内置函数,因为我主要处理矩阵乘法。我倾向于对所有内容都使用 for 循环,这不是最聪明的选择......因此,我对内置的 numpy 函数有点不熟悉。我将函数修改为:

def f(self):
   d = np.dot(np.dot(self.Asolution, self.Matrix), self.Bsolution.transpose())
   d = np.array(d)
   temp = simps(d, self.time)
   temp = sum(temp)
 
   return temp

这明显更快,但我没有得到与上面相同的结果。

我想我误解了 np.dot 的使用,或者我错过了乘以矩阵的方式。 我的主要目标是从第一个代码中删除双 for 循环,因为它需要永远。我在这里想念什么?提前感谢您的任何提示!

编辑:

self.Asolution self.Bsolution 的大小为 (t x N) - 每列是不同的位置,行表示位置如何随时间演变。

self.Matrix 的大小为 (N x N)。

【问题讨论】:

  • 你做了什么来调试这个?您是否比较了d 的值(在simps 调用之前)?
  • 我没有比较 d 值,因为我认为它们是两个不同的东西(我可能错了):在第一个选项中,我对每个 i 和 j 进行积分,它们对积分求和,而在第二个选项中,我相信我先对索引求和,然后再进行积分。 @hpaulj
  • 你有一个无用的d = np.array(d) 行的事实告诉我你没有详细测试这段代码!
  • 您好,非常感谢您的意见,我现在确认可以删除那段代码。我对 numpy 数组不是很熟悉,但我发现很多函数在传递列表而不是数组时都会抱怨,所以我这样做是为了“安全”,以防尺寸混淆或我不知道是什么。我理解你的评论,但请不要以为我只是在发布前没有挠头几次就发布了这个;还在学习:)

标签: python numpy matrix-multiplication


【解决方案1】:

让我们试试这个-


# self.t x self.N ----> self.N x self.t x 1
# arranging one column in one layer
self.Bsolution = np.swapaxes(np.expand_dims(self.Bsolution, axis=-1), 0, 1)

# self.N x self.t x self.N == N columns of Bsolution multiplied with N columns of Asolution
# multiplying 1 column of B with N columns of A in a layer done for N layers
product = np.multiply(self.Bsolution, self.Asolution)

# self.N x self.N ----> self.N x 1 x self.N 
self.Matrix = np.expand_dims(self.Matrix, axis=1)

# integration need to take place along axis=1 i believe
# multiplying each of N x N columns(4 rows in length) with N x N matrix elements
result = np.sum(simps(np.multiply(self.Matrix, product), self.time))

让我知道它是否有效

【讨论】:

  • 您好,非常感谢您的帮助!不幸的是,它不起作用 - 事实上,它抱怨ValueError: operands could not be broadcast together with shapes (50,255,1) (50,255) 。我的self.Bsolution 是一个 (t x N) 矩阵,所以我不明白你的第一行是什么意思。你能描述一下你做了什么吗?再次感谢!
  • 对不起,我以为它们都是 N x N 尺寸。您可以尝试更新的解决方案吗?如果无法验证,这有点棘手。
  • 您好!不幸的是它还没有工作,它仍然在抱怨尺寸。但是,我不知道np.swapaxesnp.expand_dims,所以我会仔细研究这些函数。非常感谢您的帮助,这很有用!
【解决方案2】:

经过多次反复试验,我设法找到了一种比双 for 循环更快地获得相同结果的方法。我发布它只是为了完整并结束问题。

n = len(self.time)
d = [np.matmul(np.matmul(self.Asolution[:][i], self.Matrix),
     self.Bsolution[:][i].transpose) for i in range(n)]
temp = np.simps(d, self.time)

【讨论】:

    猜你喜欢
    • 2011-08-24
    • 1970-01-01
    • 2015-12-11
    • 2022-11-07
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    • 2011-10-03
    • 1970-01-01
    相关资源
    最近更新 更多