如何在R/Python中以相近速度获取正交左右特征向量且无需矩阵求逆
非对称矩阵双正交左右特征向量实现方案
核心逻辑
对于可对角化的非对称矩阵m,默认方法得到的左右特征向量不满足正交性的核心原因是两类特征向量的归一化逻辑独立(默认均采用L2范数归一化),无需矩阵求逆,仅通过简单的标量缩放即可得到满足双正交要求的特征向量组:
- 右特征向量矩阵
V(列存储右特征向量)满足m %*% V = V %*% Λ,Λ为特征值对角阵 - 转置矩阵的右特征向量即为原矩阵的左特征向量原始值
W_raw,满足t(m) %*% W_raw = W_raw %*% Λ - 默认状态下
t(W_raw) %*% V为对角阵但非单位阵,只需将W_raw的每一列缩放为原值的1/(t(W_raw[,i]) %*% V[,i]),即可得到缩放后的左特征向量矩阵W,满足t(W) %*% V = I,即W的转置就是V的逆矩阵,全程无矩阵求逆操作。
R语言实现
# 生成测试用非对称可对角化矩阵 set.seed(123) m <- matrix(rnorm(25), 5, 5) # 计算右特征向量和对应特征值 eig_right <- eigen(m) V <- eig_right$vectors lambda <- eig_right$values # 计算左特征向量原始值(转置矩阵的右特征向量) eig_left <- eigen(t(m)) W_raw <- eig_left$vectors # 特征值匹配排序,消除特征值顺序、符号浮动的数值影响 order_right <- order(abs(lambda), decreasing = TRUE) V <- V[, order_right] lambda <- lambda[order_right] order_left <- order(abs(eig_left$values), decreasing = TRUE) W_raw <- W_raw[, order_left] # 双正交缩放校正 scale_factor <- diag(t(W_raw) %*% V) W <- sweep(W_raw, 2, scale_factor, FUN = "/") # 验证双正交性,数值误差范围内输出为单位矩阵 print(zapsmall(t(W) %*% V))
Python实现
import numpy as np # 生成测试用非对称可对角化矩阵 np.random.seed(123) m = np.random.randn(5,5) # 计算右特征向量和对应特征值 lambda_val, V = np.linalg.eig(m) # 计算左特征向量原始值(转置矩阵的右特征向量) lambda_val_t, W_raw = np.linalg.eig(m.T) # 特征值匹配排序,消除特征值顺序、符号浮动的数值影响 order_right = np.argsort(np.abs(lambda_val))[::-1] lambda_val = lambda_val[order_right] V = V[:, order_right] order_left = np.argsort(np.abs(lambda_val_t))[::-1] W_raw = W_raw[:, order_left] # 双正交缩放校正 scale_factor = np.diag(W_raw.T @ V) W = W_raw / scale_factor[np.newaxis, :] # 验证双正交性,数值误差范围内输出为单位矩阵 print(np.round(W.T @ V, decimals=10))
特征投影算子构造
得到双正交的左右特征向量后,第i个特征对应的投影算子可以直接通过外积构造:
- R写法:
V[,i, drop=FALSE] %*% t(W[,i, drop=FALSE]) - Python写法:
V[:,[i]] @ W[:,[i]].T
所有特征对应的投影算子求和等于单位矩阵,符合投影算子的数学性质。
提示:如果矩阵存在重特征值,需要先对重根对应的左右特征子空间做双正交化处理,避免缩放系数出现奇异问题。
内容的提问来源于stack exchange,提问作者Hirek
相关产品推荐
相关产品推荐

