我想用theano.tensor.nlinalg.eig来计算非对称方阵的特征值。
问题是:如何获得特征值/特征向量的复数值?
似乎theano.tensor.nlinalg.eig只返回它们的真实部分(参见下面的代码)。
谢谢大家。
码
import numpy as np
import theano
rng = np.random
T = theano.tensor
# Create an asymmetric (random) square matrix
N = 3
asymm_Matrix = rng.randn(N,N)
# Compute eigenv* with numpy
np_eigenvalues, np_eigenvectors = np.linalg.eig(asymm_Matrix)
# Define a theano node that computes eigenv*
symMatrix = T.dmatrix("symMatrix")
symEigenvalues, eigenvectors = T.nlinalg.eig(symMatrix)
get_Eigen = theano.function([symMatrix], [symEigenvalues, eigenvectors] )
# Compute eigenv* with theano
theano_eigenvalues, theano_eigenvectors = get_Eigen(asymm_Matrix)
print("---- asymm_Matrix :")
print(asymm_Matrix)
print()
print("---- np.linalg.eig")
print("eigenvalues :")
print(np_eigenvalues)
print("eigenvectors :")
print(np_eigenvectors)
print()
print("---- T.nlinalg.eig")
print("eigenvalues :")
print(theano_eigenvalues)
print("eigenvectors :")
print(theano_eigenvectors)
输出:
---- asymm_Matrix :
[[-0.163 -0.2099 1.1227]
[-1.132 -0.9667 -1.0436]
[-0.0974 -0.4395 -0.3839]]
---- np.linalg.eig
eigenvalues :
[-1.0136+0.1346j -1.0136-0.1346j 0.5136+0.j ]
eigenvectors :
[[-0.3948-0.1604j -0.3948+0.1604j 0.6638+0.j ]
[ 0.7736+0.j 0.7736-0.j -0.6977+0.j ]
[ 0.4630+0.0742j 0.4630-0.0742j 0.2696+0.j ]]
---- T.nlinalg.eig
eigenvalues :
[-1.0136 -1.0136 0.5136]
eigenvectors :
[[-0.3948 -0.3948 0.6638]
[ 0.7736 0.7736 -0.6977]
[ 0.463 0.463 0.2696]]
答案 0 :(得分:1)
我没有找到T.nlinalg.eig如何工作的明确文档,但似乎它的输出始终与输入的类型相同(参见nlinalg.eig代码https://github.com/Theano/Theano/blob/master/theano/tensor/nlinalg.py中的第321行)。
因此,为了获得复杂的输出,我只是将输入symMatrix定义为复杂的:symMatrix = T.cmatrix("symMatrix")
。
由于symMatrix现在很复杂,当你调用get_Eigen时,参数asymm_Matrix也必须很复杂,所以我将其相应地转换为一个新变量:c_asymm_Matrix = asymm_Matrix.astype('complex64')
。
以下代码也返回虚部:
import numpy as np
import theano
rng = np.random
T = theano.tensor
# Create an asymmetric (random) square matrix
N = 3
asymm_Matrix = rng.randn(N,N)
# Compute eigenv* with numpy
np_eigenvalues, np_eigenvectors = np.linalg.eig(asymm_Matrix)
# Define a theano node that computes eigenv*
# symMatrix defined as complex so that nlinalg.eig outputs are complex as well
symMatrix = T.cmatrix("symMatrix")
symEigenvalues, eigenvectors = T.nlinalg.eig(symMatrix)
get_Eigen = theano.function([symMatrix], [symEigenvalues, eigenvectors] )
# Compute eigenv* with theano
# Our input for get_Eigen has to be complex too now
c_asymm_Matrix = asymm_Matrix.astype('complex64')
theano_eigenvalues, theano_eigenvectors = get_Eigen(c_asymm_Matrix) #this one gives error because it expects float64 input and tries to downcast
print("---- asymm_Matrix :")
print(asymm_Matrix)
print()
print("---- np.linalg.eig")
print("eigenvalues :")
print(np_eigenvalues)
print("eigenvectors :")
print(np_eigenvectors)
print()
print("---- T.nlinalg.eig")
print("eigenvalues :")
print(theano_eigenvalues)
print("eigenvectors :")
print(theano_eigenvectors)
输出:
---- asymm_Matrix :
[[ 1.16270655 0.7266984 -0.87479655]
[-3.04065245 -1.09469397 -1.57315266]
[ 0.4850981 0.56072627 1.16248949]]
()
---- np.linalg.eig
eigenvalues :
[ 0.03696641+1.49515503j 0.03696641-1.49515503j 1.15656924+0.j ]
eigenvectors :
[[ 0.22084674+0.37455923j 0.22084674-0.37455923j -0.66915708+0.j ]
[-0.87172957+0.j -0.87172957-0.j 0.57392013+0.j ]
[ 0.20022446+0.10454574j 0.20022446-0.10454574j 0.47206407+0.j ]]
()
---- T.nlinalg.eig
eigenvalues :
[ 0.03696636 +1.49515510e+00j 0.03696636 -1.49515510e+00j
1.15656924 +1.52098596e-17j]
eigenvectors :
[[-0.22084673 -3.74559224e-01j -0.22084673 +3.74559224e-01j
0.66915709 +0.00000000e+00j]
[ 0.87172955 +0.00000000e+00j 0.87172955 +0.00000000e+00j
-0.57392007 +5.55111512e-17j]
[-0.20022446 -1.04545735e-01j -0.20022446 +1.04545735e-01j
-0.47206411 +3.88578059e-16j]]
输出稍有不同,但这只是因为在Theano输出中显示的一些非常小的虚部在numpy输出中为零。