简体   繁体   English

Numpy中的向量化特征值计算

[英]Vectorize eigenvalue calculation in Numpy

I would like a numpy-sh way of vectorizing the calculation of eigenvalues, such that I can feed it a matrix of matrices and it would return a matrix of the respective eigenvalues. 我想要一种向量化特征值计算的numpy-sh方式,这样我可以向其提供矩阵矩阵,并且它将返回各个特征值的矩阵。

For example, in the code below, B is the block 6x6 matrix composed of 4 copies of the 3x3 matrix A. C is what I would like to see as output, ie an array of dimension (2,2,3) (because A has 3 eigenvalues). 例如,在下面的代码中,B是由4个3x3矩阵A的副本组成的块6x6矩阵。C是我希望看到的输出,即维(2,2,3)的数组(因为A具有3个特征值)。

This is of course a very simplified example, in the general case the matrices A can have any size (although they are still square), and the matrix B is not necessarily formed of copies of A, but different A1, A2, etc (all of same size but containing different elements). 当然,这是一个非常简化的示例,在通常情况下,矩阵A可以具有任何大小(尽管它们仍然是正方形),并且矩阵B不一定由A的副本形成,而是由不同的A1,A2等组成(所有大小相同但包含不同的元素)。

import numpy as np
A = np.array([[0, 1, 0],
              [0, 2, 0],
              [0, 0, 3]])
B = np.bmat([[A, A], [A,A]])
C = np.array([[np.linalg.eigvals(B[0:3,0:3]),np.linalg.eigvals(B[0:3,3:6])],
              [np.linalg.eigvals(B[3:6,0:3]),np.linalg.eigvals(B[3:6,3:6])]])

Edit: if you're using a version of numpy >= 1.8.0 , then np.linalg.eigvals operates over the last two dimensions of whatever array you hand it, so if you reshape your input to an (n_subarrays, nrows, ncols) array you'll only have to call eigvals once: 编辑:如果您使用的是numpy> = 1.8.0的版本 ,则np.linalg.eigvals将在您处理的任何数组的最后两个维度上进行操作,因此,如果将输入的(n_subarrays, nrows, ncols)重塑为(n_subarrays, nrows, ncols)数组,您只需调用一次eigvals

import numpy as np

A = np.array([[0, 1, 0],
              [0, 2, 0],
              [0, 0, 3]])

# the input needs to be an array, since matrices can only be 2D.
B = np.repeat(A[np.newaxis,...], 4, 0)

# for arbitrary input arrays you could do something like:
# B = np.vstack(a[np.newaxis,...] for a in input_arrays)
# but for this to work it will be necessary for each element in 
# 'input_arrays' to have the same shape

# eigvals will operate over the last two dimensions of the array and return
# a (4, 3) array of eigenvalues
C = np.linalg.eigvals(B)

# reshape this output so that it matches your original example
C.shape = (2, 2, 3)

If your input arrays don't all have the same dimensions, eg input_arrays[0].shape == (2, 2) , input_arrays[1].shape == (3, 3) etc. then you could only vectorize this calculation across subsets with matching dimensions. 如果输入数组的维数都不相同,例如input_arrays[0].shape == (2, 2)input_arrays[1].shape == (3, 3)等,那么您只能对计算进行矢量化尺寸匹配的子集。

If you're using an older version of numpy then unfortunately I don't think there's any way to vectorize the calculation of the eigenvalues over multiple input arrays - you'll just have to loop over your inputs in Python instead. 如果您使用的是numpy的旧版本,那么不幸的是,我认为没有任何方法可以向量化多个输入数组上特征值的计算-您只需要在Python中循环输入即可。

You could just do something like this 你可以做这样的事情

C = np.array([[np.linalg.eigvals(B[i:i+3, j:j+3])
              for i in xrange(0, B.shape[0], 3)]
                for j in xrange(0, B.shape[1], 3)])

Perhaps a nicer approach is to use the block_view function from https://stackoverflow.com/a/5078155/1352250 : 也许更好的方法是使用https://stackoverflow.com/a/5078155/1352250block_view函数:

B_blocks = block_view(B)
C = np.array([[np.linalg.eigvals(m) for m in v] for v in B_blocks])

Update 更新资料

As ali_m points out, this method is a form of syntactic sugar that will not reduce the overhead incurred from calling eigvals a large number of times. 正如ali_m指出的那样,此方法是一种语法糖形式,不会减少因多次调用eigvals而引起的开销。 While this overhead should be small if each matrix it is applied to is large-ish, for the 6x6 matrices that the OP is interested in, it is not trivial (see the comments below; according to ali_m, there might be a factor of three difference between the version I give above, and the version he posted that uses Numpy >= 1.8.0). 如果要应用的每个矩阵的开销都很大,则此开销应该很小,但对于OP感兴趣的6x6矩阵,它并不是微不足道的(请参阅下面的注释;根据ali_m,可能是三分之一)我上面给出的版本与他发布的使用Numpy> = 1.8.0的版本之间的差异)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM