使用numpy对角化酉矩阵未得到正交归一化特征向量的问题
问题分析与解决
核心原因
numpy.linalg.eig 对带有重特征值的酉矩阵进行对角化时,不会自动对同一特征值对应的特征向量做正交化处理。
酉矩阵的特征向量正交性仅保证不同特征值的特征向量相互正交;对于同一特征值的特征向量,它们属于同一个特征子空间,numpy 返回的只是该子空间的一组线性无关基,而非正交基——这就是你看到内积不为0的原因。
针对QFT矩阵的具体情况
4量子比特带交换操作的QFT矩阵是16×16酉矩阵,其特征值仅有4种:$\pm1$、$\pm i$,每种特征值的重数均为4。你选取的两个特征向量v_i和v_j属于同一个纯虚数特征值的特征子空间,因此numpy返回的原始向量未正交化,内积自然不为0。
你可以通过以下代码验证这两个特征值是否相等(考虑数值精度):
print(np.isclose(eigvals[2], eigvals[-1]))
输出会是True,证实它们属于同一特征值的特征子空间。
解决方法
对同一特征值对应的特征向量组进行正交化处理即可,这里提供两种实现方式:
方式1:使用Gram-Schmidt正交化(借助scipy工具)
import numpy as np from scipy.linalg import orth from qiskit.circuit.library import QFT from qiskit.quantum_info import Operator op = Operator(QFT(num_qubits=4, do_swaps=True)).data eigvals, eigvecs = np.linalg.eig(op) eigvecs = eigvecs.T # 按特征值分组,对每组特征向量做正交化 # 考虑数值精度,先对特征值做近似去重 unique_vals = np.unique(np.round(eigvals, 10)) ortho_eigvecs = {} for val in unique_vals: # 筛选当前特征值对应的所有特征向量 mask = np.isclose(eigvals, val) vec_group = eigvecs[mask].T # 转置为列向量,适配orth函数 ortho_group = orth(vec_group).T # 正交化后转置回行向量形式 ortho_eigvecs[val] = ortho_group # 从正交化后的组中取向量验证 lambda_i = eigvals[2] v_i_orth = ortho_eigvecs[lambda_i][0].reshape(-1,1) v_j_orth = ortho_eigvecs[lambda_i][1].reshape(-1,1) print(v_j_orth.T.conj() @ v_i_orth) # 结果接近0,符合正交要求
方式2:使用Schur分解(直接得到正交向量)
对于酉矩阵,Schur分解会直接返回正交的特征向量(Schur向量),无需额外正交化:
import numpy as np from scipy.linalg import schur from qiskit.circuit.library import QFT from qiskit.quantum_info import Operator op = Operator(QFT(num_qubits=4, do_swaps=True)).data T, Z = schur(op, unitary=True) # Z的列是正交的特征向量/ Schur向量 eigvals_schur = np.diag(T) # 取第2和最后一个特征向量(对应原问题的索引) v_i = Z[:,2].reshape(-1,1) v_j = Z[:,-1].reshape(-1,1) print(v_j.T.conj() @ v_i) # 结果接近0
内容的提问来源于stack exchange,提问作者Tristan Nemoz
相关产品推荐
相关产品推荐

