Si A est une matrice symétrique, alors en utilisant la matrice orthogonale U,
\mathbf{A} = \mathbf{U} \mathbf{D} \mathbf{U}^T
Peut être diagonalisé (D est une matrice diagonale). En ce moment,
\mathbf{A}^n = \mathbf{U} \mathbf{D}^n \mathbf{U}^T
Est satisfait, donc le calcul de A à la nième puissance devient très facile.
Cette fois, j'ai créé du code python qui peut facilement calculer la diagonalisation (décomposition de valeur unique).
func.py
def Eigenvalue_decomp(A):
#La matrice symétrique A est diagonalisée à l'aide de la matrice orthogonale U.
import numpy as np
if A.shape[0]!=A.shape[1]: #Renvoie une erreur si A n'est pas une matrice carrée
raise Exception("error! A is not square matrix!")
if (A==A.T).all()==False: #Renvoie une erreur si A n'est pas une matrice symétrique
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
avec ça,
In[1]: import func
In[2]: U,D=func.Eigenvalue_decomp(A)
Vous pouvez obtenir la matrice orthogonale U et la matrice diagonale D pour diagonaliser la matrice symétrique A créée par 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*Calculer Ut
[[ 5. 2.]
[ 2. 7.]]
In[6]: print A.dot(A) #A*Calculer A
[[ 29. 24.]
[ 24. 53.]]
In[7]: print U.dot(D.dot(D.dot(U.T))) #A*A=U*D*D*Calculer 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*Calculer 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*Calculer 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*Calculer 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}
Lorsque cette matrice A est résolue analytiquement, la valeur propre contient une solution multiple (λ = 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*Calculer 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*Calculer 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*Calculer 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]]
Dans chaque cas, il semble que U et D sont calculés correctement.
Initialement [numpy.linalg.matrix_power](http://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.linalg.matrix_power.html "numpy.linalg.matrix_power" en Python numpy Puisqu'il existe une fonction appelée ") fonction qui peut calculer la nième puissance d'une matrice, vous n'utiliserez pas la fonction ci-dessus dans le but de" calculer la nième puissance d'une matrice symétrique ", mais vous pouvez utiliser la décomposition en valeurs propres d'une matrice symétrique. Je pense que c'est très efficace quand on veut le faire.
URL de référence: 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