numpy.tensordot 或 ufunc 可以替换这个嵌套的 for 循环吗?

Can numpy.tensordot or ufunc replace this nested for loop?

注意:我知道这与 非常相似,只是我们正在处理的实际实例似乎有所不同(我需要二次形式计算)而且我不够聪明,无法推断那里的讨论, 所以问这个问题。

Objective: 将for循环替换为矩阵计算or/and通用函数,使计算速度更快

问题:

#Toy example
def A(a):
 return [[a,1,1],[1,1,1],[1,1,a**2]]

val = 0
for a in range(1,5):
 for x in [ [1,1,1], [2,2,2], [3,3,3] ]:
   val +=np.exp(-1* np.dot(np.dot(x,A(a)), x))  
print(val)

在实际实现中,我将 x 作为 9 维向量,范围超过 10**9 次迭代,范围超过 (50)**2 次迭代,并且它需要永远使用这个 for 循环?有什么建议么?我觉得 tensordot 似乎最有可能,但我一直没有得到我想要的结果,因此问。 由于我是一个真正的初学者,如果你能写出我可以直接应用的示例代码,那将非常有帮助...... 提前致谢。

补充:经过进一步调查,np.tensordot() 似乎不一定是最快的,因此欢迎使用 for 循环以外的任何解决方案。(例如,使用 np.einsum 两次, np.dot 和 np.einsum 的组合等) 感谢@hpaulj,我现在知道如何消除 z 循环,但我真的也想解决 a 循环...

In [155]: a=1
     ...: val=0
In [156]: for x in [ [1,1,1], [2,2,2], [3,3,3] ]:
     ...:    val +=np.exp( np.dot(np.dot(x,A(a)), x))
     ...: 
In [157]: val
Out[157]: 1.5060973145850306e+35

部分可以替换为

In [158]: X = np.array([ [1,1,1], [2,2,2], [3,3,3] ])
In [159]: np.exp(np.einsum('ki,ij,kj->k',X,A(a),X)).sum()
Out[159]: 1.5060973145850306e+35