如何使用特征值信息有效地对矩阵进行对角化?

计算科学 线性代数 矩阵 特征值
2021-12-13 09:02:14

如果以前以更一般的形式提出过这个问题,我深表歉意。我有一个三对角 Toeplitz 矩阵K,其特征值和特征向量对于任何维度都是解析已知的N[ 1 ]。具体来说,在本文第 2.2 节的符号中,我希望对角化的矩阵是这样的a1=a2 =2, 和b1=b2=c1=c2=1.

要么

K=(2100..01210..00121..0..)

然后定理 2.1 给出它的特征值和特征向量。

他们是:λi=4cos2((i+1)π2(N+1))和特征向量vi=(.,.,[U(j2,(λi+2)222)+U(j21,(λi+2)222)],.,.)T,

在哪里U(j,x)是二阶切比雪夫多项式j.

我进一步想做的是使用特征向量矩阵,比如A, 来实现相似变换。(注意A在这个例子中一点也不稀疏)。我怎样才能在计算上做到最好?在 Python 中,对于N=104, 程序甚至需要花费大量时间来计算A并存储矩阵,大概是因为存在切比雪夫多项式。另一方面,使用稀疏线性代数模块 scipy.sparse.linalg.eigs 可以更快地完成任务,即使我没有提供任何信息!

所以,我的问题是——如何结合我对真实特征值和特征向量的知识以及 SciPy 中的有效线性代数例程来实现对角矩阵 D 的相似性变换?

即使我只使用有关特征值的信息,我可以有效地计算特征向量吗?如果已知特征值,是否有例程在输入特征值后计算特征向量?

例如,以下代码是我在 Python 中的试用版:

import numpy as np
from scipy.special import eval_chebyu
from scipy import sparse as sp

N = 10**3

def Mat(x,j):
if j%2==0:
    if j==0:
        return 1
    else:
        return eval_chebyu(j/2, ((x+2)**2-2)/2) + eval_chebyu(j/2-1, ((x+2)**2-2)/2)
else:
    return (x+2)*eval_chebyu((j-1)/2, ((x+2)**2-2)/2)

def norm(A):
A=A.transpose()/np.sqrt(np.einsum('...i,...i', A,A ))
return A

def tridiag(a, b, c, N):
return sp.diags(a*np.ones(N-1), -1) + sp.diags(b*np.ones(N), 0) +sp.diags(c*np.ones(N-1), 1)

K = tridiag(1,-2,1,N)
A = np.zeros([N,N])
lam = np.zeros(N)

for i in range(0,N):
    lam[i] = -4*(np.cos((i+1)*np.pi/(2*(N+1))))**2
    for j in range(0,N):
        A[i,j]= Mat(lam[i],j)

A = norm(A)

Tq_new = sp.diags(1/(2*omega*np.sqrt(-lam)),0)

Tq_old = A.transpose().dot(Tq_new.todense()).dot(A)
1个回答

Gilbert Strang 在这里解释了第二个差分矩阵的矩阵平方根

特别是,

导入 numpy
导入 scipy.linalg

定义 f(N, p):
    a = 2 * (-1)**(p-1)
    b = 1/numpy.tan((numpy.pi * (2*p - 1)) / (4 + 4*N))
    c = 1/numpy.tan((numpy.pi * (2*p + 1)) / (4 + 4*N))
    返回 a - b + c

N = 10000
K_tri = numpy.eye(N) - numpy.eye(N, k=1)
K = K_tri + K_tri.T

s = numpy.arange(N)
T = scipy.linalg.toeplitz(f(N, s))
H = scipy.linalg.hankel(f(N, s+2), f(N, N+1+s))
K_sqrt = (0.5 / (N+1)) * (T - H)

打印(numpy.max(numpy.abs(numpy.dot(K_sqrt, K_sqrt) - K)))
2.14717132963e-13