学术, 其他笔记

验证特征向量在矩阵中的朝向(附Python、Matlab、Mathematica、Fortran代码)

矩阵的特征向量是有朝向的,通常写为列向量。这里给出特性向量在矩阵中朝向的验证。

先给出结论:

  • Python中numpy.linalg.eig求解特征向量在矩阵中的朝向为列向量
  • Matlab中eig求解特征向量在矩阵中的朝向为列向量
  • Mathematica中Eigenvectors求解特征向量在矩阵中的朝向为横向量(只有这里为横向量)。
  • Fortran中lapack的geev求解特征向量在矩阵中的朝向为列向量

计算矩阵特征向量的例子[1]:

1. Python中的numpy.linalg.eig验证

numpy.linalg.eig官方文档:https://numpy.org/doc/stable/reference/generated/numpy.linalg.eig.html

Python代码验证:

import numpy as np

A = np.array([[3, 2, -1], [-2, -2, 2], [3, 6, -1]])
eigenvalue, eigenvector = np.linalg.eig(A)
print('矩阵:\n', A)
print('特征值:\n', eigenvalue)
print('特征向量:\n', eigenvector)
print('特征值为-4对应的特征向量理论值:\n', np.array([1/3, -2/3, 1])/np.sqrt((1/3)**2+(-2/3)**2+1**2))

print('\n判断是否正交:\n', np.dot(eigenvector.transpose(), eigenvector))
print('判断是否正交:\n', np.dot(eigenvector, eigenvector.transpose()))

print('特征向量矩阵的列向量模方和:')
for i in range(3):
    print(eigenvector[0, i]**2+eigenvector[1, i]**2+eigenvector[2, i]**2)
print('特征向量矩阵的行向量模方和:')
for i in range(3):
    print(eigenvector[i, 0]**2+eigenvector[i, 1]**2+eigenvector[i, 2]**2)

运算结果:

结论:Python中numpy.linalg.eig求解特征向量在矩阵中的朝向为列向量

2. Matlab中的eig验证

eig官方文档:https://www.mathworks.com/help/matlab/ref/eig.html

Matlab代码验证:

clc;clear all;
A = [3, 2, -1; -2, -2, 2; 3, 6, -1]
[V,D] = eig(A)

运算结果:

结论:Matlab中eig求解特征向量在矩阵中的朝向为列向量

3. Mathematica中的Eigenvectors验证

Eigenvectors官方文档:https://reference.wolfram.com/language/ref/Eigenvectors.html

MMA代码验证:


Clear["`*"]
A = {{3, 2, -1}, {-2, -2, 2}, {3, 6, -1}};
MatrixForm[A]
eigenvalue = MatrixForm[Eigenvalues[A]]
eigenvector = MatrixForm[Eigenvectors[A]]

运算结果:

结论:Mathematica中Eigenvectors求解特征向量在矩阵中的朝向为横向量

4. Fortran中lapack的geev验证

用到MKL-lapack中的geev函数。

Fortran代码验证:

program main 
    use lapack95
    implicit none
    integer i,j,info
    complex*16  A(3,3), eigenvalues(3), eigenvectors(3,3)

    A(1,1)=(3.d0, 0.d0)
    A(1,2)=(2.d0, 0.d0)
    A(1,3)=(-1.d0, 0.d0)
    A(2,1)=(-2.d0, 0.d0)
    A(2,2)=(-2.d0, 0.d0)
    A(2,3)=(2.d0, 0.d0)
    A(3,1)=(3.d0, 0.d0)
    A(3,2)=(6.d0, 0.d0)
    A(3,3)=(-1.d0, 0.d0)
    
    write(*,*) 'matrix:'
    do i=1,3
        do j=1,3
            write(*,"(f10.4, '+1i*',f7.4)",advance='no') A(i,j)  ! 内循环为列的指标
        enddo
        write(*,*) ''
    enddo
    
    call geev(A=A, W=eigenvalues, VR=eigenvectors, INFO=info)  
    
    write(*,*) 'eigenvectors:'
    do i=1,3
        do j=1,3
            write(*,"(f10.4, '+1i*',f7.4)",advance='no') eigenvectors(i,j)  ! 内循环为列的指标。输出结果列向量为特征向量。
        enddo
        write(*,*) ''
    enddo
    write(*,*) 'eigenvalues:'
    do i=1,3
        write(*,"(f10.4, '+1i*',f7.4)",advance='no') eigenvalues(i)  
    enddo
    write(*,*)  ''
    write(*,*)  ''
end program

运算结果:

结论:Fortran中lapack的geev求解特征向量在矩阵中的朝向为列向量

5. 实对称矩阵的验证(使用Python)

Python代码验证:

import numpy as np

A = np.array([[3, 2, -1], [2, -2, 6], [-1, 6, 1]])
eigenvalue, eigenvector = np.linalg.eig(A)
print('矩阵:\n', A)
print('特征值:\n', eigenvalue)
print('特征向量:\n', eigenvector)

print('\n判断是否正交:\n', np.dot(eigenvector.transpose(), eigenvector))
print('判断是否正交:\n', np.dot(eigenvector, eigenvector.transpose()))

print('特征向量矩阵的列向量模方和:')
for i in range(3):
    print(eigenvector[0, i]**2+eigenvector[1, i]**2+eigenvector[2, i]**2)
print('特征向量矩阵的行向量模方和:')
for i in range(3):
    print(eigenvector[i, 0]**2+eigenvector[i, 1]**2+eigenvector[i, 2]**2)

print('\n对角化验证:')
print(np.dot(np.dot(eigenvector.transpose(), A), eigenvector))
print(np.dot(np.dot(eigenvector, A), eigenvector.transpose()))

运算结果:

结论1:虽然实对称矩阵的特征向量组成的矩阵为正交矩阵,即列向量和横向量均是标准正交组,但从最后“对角化验证”中可以看出:特征向量只能是列向量。

这里再给出一个实对称矩阵的例子:

import numpy as np

A = np.array([[0, 1, 1, -1], [1, 0, -1, 1], [1, -1, 0, 1], [-1, 1, 1, 0]])
eigenvalue, eigenvector = np.linalg.eig(A)
print('矩阵:\n', A)
print('特征值:\n', eigenvalue)
print('特征向量:\n', eigenvector)

print('\n判断是否正交:\n', np.dot(eigenvector.transpose(), eigenvector))
print('判断是否正交:\n', np.dot(eigenvector, eigenvector.transpose()))

print('特征向量矩阵的列向量模方和:')
for i in range(4):
    print(eigenvector[0, i]**2+eigenvector[1, i]**2+eigenvector[2, i]**2+eigenvector[3, i]**2)
print('特征向量矩阵的行向量模方和:')
for i in range(4):
    print(eigenvector[i, 0]**2+eigenvector[i, 1]**2+eigenvector[i, 2]**2+eigenvector[i, 3]**2)

print('\n对角化验证:')
print(np.dot(np.dot(eigenvector.transpose(), A), eigenvector))
print(np.dot(np.dot(eigenvector, A), eigenvector.transpose()))

print('\n特征向量理论值:')
T = np.array([[1/np.sqrt(2), 1/np.sqrt(6), -1/np.sqrt(12), 1/2], [1/np.sqrt(2), -1/np.sqrt(6), 1/np.sqrt(12), -1/2], [0, 2/np.sqrt(6), 1/np.sqrt(12), -1/2], [0, 0, 3/np.sqrt(12), 1/2]])
print(T)

print('\n判断是否正交:\n', np.dot(T.transpose(), T))
print('判断是否正交:\n', np.dot(T, T.transpose()))

print('\n对角化验证:')
print(np.dot(np.dot(T.transpose(), A), T))
print(np.dot(np.dot(T, A), T.transpose()))

运算结果:

结论2:由于有相同的特征值,因此数值计算得到的特征向量矩阵不一定是正交矩阵,但可通过施密特正交化得到正交矩阵。参考博文:幺正矩阵和厄密矩阵施密特正交化(附Python代码)

6. 厄密矩阵的验证(使用Python)

Python代码验证:

import numpy as np

A = np.array([[3, 2+1j, -1], [2-1j, -2, 6], [-1, 6, 1]])
eigenvalue, eigenvector = np.linalg.eig(A)
print('矩阵:\n', A)
print('特征值:\n', eigenvalue)
print('特征向量:\n', eigenvector)

print('\n判断是否正交:\n', np.dot(eigenvector.transpose().conj(), eigenvector))
print('判断是否正交:\n', np.dot(eigenvector, eigenvector.transpose().conj()))

print('特征向量矩阵的列向量模方和:')
for i in range(3):
    print(np.abs(eigenvector[0, i])**2+np.abs(eigenvector[1, i])**2+np.abs(eigenvector[2, i])**2)
print('特征向量矩阵的行向量模方和:')
for i in range(3):
    print(np.abs(eigenvector[i, 0])**2+np.abs(eigenvector[i, 1])**2+np.abs(eigenvector[i, 2])**2)

print('\n对角化验证:')
print(np.dot(np.dot(eigenvector.transpose().conj(), A), eigenvector))
print(np.dot(np.dot(eigenvector, A), eigenvector.transpose().conj()))

运算结果:

参考资料:

[1] 截图自北京科技大学廖福成老师的”高等代数与解析几何“课件

[2] ”高等代数与解析几何“、”线性代数“、”高等数学“等相关教材

1,371 次浏览

【说明:本站主要是个人的一些笔记和代码分享,内容可能会不定期修改。为了使全网显示的始终是最新版本,这里的文章未经同意请勿转载。引用请注明出处:https://www.guanjihuan.com

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注