【发布时间】: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.Asolution 和 self.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