将scipy.linalg.eigh之类的矩阵函数应用于高维数组

时间:2018-09-16 08:51:36

标签: python arrays numpy scipy

我是numpy的新手,但作为一名工程师已经使用python相当一段时间了。 我正在编写一个程序,当前将应力张量存储为另一个NxM数组中的3x3 numpy数组,该数组表示通过时间和通过壁的厚度的值,因此总体上来说,它是NxMx3x3 numpy数组。我想有效地计算此更大数组中每个3x3数组的特征值和向量。到目前为止,我尝试使用“ fromiter”,但这似乎不起作用,因为函数返回2个数组。我也尝试了apply_along_axis,它也行不通,因为它说内部3x3不是正方形矩阵?我可以通过列表理解来做到这一点,但这似乎不适合使用列表。

仅使用列表理解来计算特征值的示例

import numpy as np
from scipy import linalg
a=np.random.random((2,2,3,3))
f=linalg.eigvalsh
ans=np.asarray([f(x) for x in a.reshape((4,3,3))])
ans.shape=(2,2,3)

我以为这样的事情会起作用,但是我已经尝试过了,但无法起作用:

np.apply_along_axis(f,0,a)
顺便说一句,2x2位可能高达5000x100,并且此代码重复〜50x50x200次,因此需要提高效率。任何帮助将不胜感激?

1 个答案:

答案 0 :(得分:1)

您可以使用numpy.linalg.eigh。它接受像您的示例a这样的数组。

这是一个例子。首先,创建一个3x3对称数组的数组:

In [96]: a = np.random.random((2, 2, 3, 3))

In [97]: a = a + np.transpose(a, axes=(0, 1, 3, 2))

In [98]: a[0, 0]
Out[98]: 
array([[0.61145048, 0.85209618, 0.03909677],
       [0.85209618, 1.79309413, 1.61209077],
       [0.03909677, 1.61209077, 1.55432465]])

计算所有3x3数组的特征值和特征向量:

In [99]: evals, evecs = np.linalg.eigh(a)

In [100]: evals.shape
Out[100]: (2, 2, 3)

In [101]: evecs.shape
Out[101]: (2, 2, 3, 3)

看看a[0, 0]的结果:

In [102]: evals[0, 0]
Out[102]: array([-0.31729364,  0.83148477,  3.44467813])

In [103]: evecs[0, 0]
Out[103]: 
array([[-0.55911658,  0.79634401,  0.23070516],
       [ 0.63392772,  0.23128064,  0.73800062],
       [-0.53434473, -0.55887877,  0.63413738]])

验证是否与分别计算a[0, 0]的特征值和特征向量相同:

In [104]: np.linalg.eigh(a[0, 0])
Out[104]: 
(array([-0.31729364,  0.83148477,  3.44467813]),
 array([[-0.55911658,  0.79634401,  0.23070516],
        [ 0.63392772,  0.23128064,  0.73800062],
        [-0.53434473, -0.55887877,  0.63413738]]))