If A is a symmetric matrix, then using the orthogonal matrix U,
\mathbf{A} = \mathbf{U} \mathbf{D} \mathbf{U}^T
It can be diagonalized as follows (D is a diagonal matrix). At this time,
\mathbf{A}^n = \mathbf{U} \mathbf{D}^n \mathbf{U}^T
Is true, so the calculation of A to the nth power becomes very easy.
This time, I created a python code that can easily perform the diagonalization calculation (eigenvalue decomposition).
func.py
def Eigenvalue_decomp(A):
#The symmetric matrix A is diagonalized using the orthogonal matrix U.
import numpy as np
if A.shape[0]!=A.shape[1]: #Returns an error if A is not a square matrix
raise Exception("error! A is not square matrix!")
if (A==A.T).all()==False: #Returns an error if A is not a symmetric matrix
raise Exception("error! A is not symmetric matrix!")
la, U = np.linalg.eig(A) # eigen value and eigen vector is resolved.
U,_=np.linalg.qr(U) # Gram-Schmidt orthonormalization
D=np.diag(la)
return U,D
with this,
In[1]: import func
In[2]: U,D=func.Eigenvalue_decomp(A)
You can get the orthogonal matrix U and the diagonal matrix D for diagonalizing the symmetric matrix A created by numpy.
\mathbf{A}=
\begin{pmatrix}
5.0 & 2.0 \\
2.0 & 7.0
\end{pmatrix}
In[3]: A=np.array([[5.0,2.0],[2.0,7.0]])
In[4]: U,D=func.Eigenvalue_decomp(A)
In[5]: print U.dot(D.dot(U.T)) #A=U*D*Calculate Ut
[[ 5. 2.]
[ 2. 7.]]
In[6]: print A.dot(A) #A*Calculate A
[[ 29. 24.]
[ 24. 53.]]
In[7]: print U.dot(D.dot(D.dot(U.T))) #A*A=U*D*D*Calculate Ut
[[ 29. 24.]
[ 24. 53.]]
\mathbf{A}=
\begin{pmatrix}
1.0 & \sqrt{2.0} & 0 \\
\sqrt{2.0} & 1.0 & \sqrt{2.0} \\
0 & \sqrt{2.0} & 1.0
\end{pmatrix}
In[8]: A=np.array([[1.0,np.sqrt(2.0),0],[np.sqrt(2.0),1.0,np.sqrt(2.0)],[0,np.sqrt(2.0),1.0]])
In[9]: U,D=func.Eigenvalue_decomp(A)
In[10]: print U.dot(D.dot(U.T)) #A=U*D*Calculate Ut
[[ 1.00000000e+00 1.41421356e+00 -3.33066907e-16]
[ 1.41421356e+00 1.00000000e+00 1.41421356e+00]
[ -3.33066907e-16 1.41421356e+00 1.00000000e+00]]
In[11]: print A.dot(A) #A*Calculate A
[[ 3. 2.82842712 2. ]
[ 2.82842712 5. 2.82842712]
[ 2. 2.82842712 3. ]]
In[12]: print U.dot(D.dot(D.dot(U.T))) #A*A=U*D*D*Calculate Ut
[[ 3. 2.82842712 2. ]
[ 2.82842712 5. 2.82842712]
[ 2. 2.82842712 3. ]]
\mathbf{A}=
\begin{pmatrix}
0 & -\sqrt{2.0} & \sqrt{2.0} \\
-\sqrt{2.0} & 1.0 & 1.0 \\
\sqrt{2.0} & 1.0 & 1.0
\end{pmatrix}
When this matrix A is solved analytically, the eigenvalues include multiple solutions (λ = 2).
In[13]: A=np.array([[0,-np.sqrt(2.0),np.sqrt(2.0)],[-np.sqrt(2.0),1.0,1.0],[np.sqrt(2.0),1.0,1.0]])
In[14]: U,D=func.Eigenvalue_decomp(A)
In[15]: print U.dot(D.dot(U.T)) #A=U*D*Calculate Ut
[[ -2.85835307e-16 -1.41421356e+00 1.41421356e+00]
[ -1.41421356e+00 1.00000000e+00 1.00000000e+00]
[ 1.41421356e+00 1.00000000e+00 1.00000000e+00]]
In[16]: print A.dot(A) #A*Calculate A
[[ 4.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 4.00000000e+00 -4.44089210e-16]
[ 0.00000000e+00 -4.44089210e-16 4.00000000e+00]]
In[17]: print U.dot(D.dot(D.dot(U.T))) #A*A=U*D*D*Calculate Ut
[[ 4.00000000e+00 3.16592776e-16 -5.71585644e-16]
[ 3.16592776e-16 4.00000000e+00 -4.44089210e-16]
[ -5.71585644e-16 -4.44089210e-16 4.00000000e+00]]
In each case, it seems that U and D are calculated correctly.
Numpy in Python was originally [numpy.linalg.matrix_power](http://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.linalg.matrix_power.html "numpy.linalg.matrix_power" Since there is a function called ") function that can calculate the nth power of a matrix, you probably won't use the above function for the purpose of" calculating the nth power of a symmetric matrix ", but you can do the eigenvalue decomposition of a symmetric matrix. I think it is very effective when you want to do it.
Reference URL: http://mathtrain.jp/symmetriceigen http://ksmzn.hatenablog.com/entry/2014/02/16/004921 http://takegue.hatenablog.com/entry/2014/07/26/222141 http://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.linalg.matrix_power.html
Recommended Posts