You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SymPy生成的简并子空间特征向量无法构造有效投影算子的问题排查

SymPy计算简并特征子空间投影算子的问题

我尝试用SymPy符号化计算列表An中各矩阵对应特征子空间的投影算子集合,生成An的代码如下:

import numpy as np
import sympy as sp
qutritketsn = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
qutritketss = sp.Matrix(qutritketsn)
an = [(1/sp.sqrt(1+sp.cos(sp.pi/5)))*(sp.cos(4*sp.pi*n/5)*qutritketss.col(0)+sp.sin(4*sp.pi*n/5)*qutritketss.col(1)+sp.sqrt(sp.cos(sp.pi/5))*qutritketss.col(2)) for n in range(5)]
An = [sp.eye(3)-2*(v*v.T.conjugate()) for v in an]

注:An中的矩阵特征值均应为-1、1、1(1为二重简并)。

尝试的实现代码

我用以下代码实现投影算子计算:

eigproj = []
for num in range(len(An)):
    eig_stuff = An[num].eigenvects(simplify=True)
    eigproj_temp = []
    for i in range(len(eig_stuff)):
        if eig_stuff[i][1]<2:
            evnorm = eig_stuff[i][2][0].normalized()
            proj = evnorm*evnorm.T.conjugate()
            eigproj_temp.append(proj)
        else: # 对简并子空间的投影算子求和
            shp = eig_stuff[i][2][0].shape
            init = sp.zeros(shp[0], shp[0])
            for j in range(len(eig_stuff[i][2])):
                evnorm1 = eig_stuff[i][2][j].normalized()
                init += evnorm1*evnorm1.T.conjugate()
            eigproj_temp.append(init)

遇到的问题

运行后发现,eig_stuff中返回的简并特征值对应的特征向量,经归一化后逐个计算投影算子再求和,无法得到有效投影算子:

  • 生成的简并子空间投影算子不满足幂等性
  • 与非简并特征值对应的投影算子不正交
  • 两者之和不等于单位矩阵

而非简并特征值对应的投影算子是满足幂等性的,问题应该出在简并特征值的处理上。

NumPy对比实现

用等价的NumPy代码处理An的NumPy版本时,返回的特征向量可以构造有效投影算子,参考代码如下:

from collections import Counter
eigproj = []
for num in range(len(An)):
    eigs_temp, eigvs_temp = np.linalg.eigh(An[num])
    # 将接近整数的特征值取整
    for i in range(len(eigs_temp)):
        if np.abs(eigs_temp[i].real-np.round(eigs_temp[i].real)) < 10**(-13):
            temps = np.round(eigs_temp[i].real)
            eigs_temp.real[i] = temps    
    eig_mult = Counter(eigs_temp) # 统计特征值重数
    eig_mult = list(eig_mult.values())
    # 根据重数获取特征值索引
    dup_inds = [[k for k in range(int(int(i>0)*sum([eig_mult[j] for j in range(max(i, 0))])), sum([eig_mult[j] for j in range(i+1)]))] for i in range(len(eig_mult))]
    eigproj_temp = [np.outer(eigvs_temp[:, i], np.conj(eigvs_temp[:, i])) for i in range(eigvs_temp.shape[0])]
    eigproj_temp1 = []
    for i in dup_inds:
        # 对简并子空间的投影算子求和
        if len(i)>1:
            og = np.zeros(eigproj_temp[0].shape)
            for j in i:
                og += eigproj_temp[j]
            eigproj_temp1.append(og)
        else:
            eigproj_temp1.append(eigproj_temp[i[0]])

    eigproj_temp1 = np.array(eigproj_temp1)
    eigproj.append(eigproj_temp1)

示例结果对比

以如下矩阵为例:

Matrix([
[0.27639320225002103036, 0.52573111211913360603, 0.80449586419071039205],
[0.52573111211913360603, 0.61803398874989484820, -0.58450045893897621288],
[0.80449586419071039205, -0.58450045893897621288, 0.10557280900008412144]
])

SymPy下20位精度的投影算子结果:

# 特征值-1对应的投影算子
Matrix([
[0.36180339887498948482, -0.26286555605956680301, -0.40224793209535519602],
[-0.26286555605956680301, 0.19098300562505257590, 0.29225022946948810644],
[-0.40224793209535519602, 0.29225022946948810644, 0.44721359549995793928]
])

# 简并特征值1对应的投影算子
Matrix([
[0.89827790731256834867, 0.47552825814757678606, 0.49720578787857844011],
[0.47552825814757678606, 0.65450849718747371205, 0],
[0.49720578787857844011, 0, 0.44721359549995793928]
])

NumPy下的输出结果:

# 特征值-1对应的投影算子
array([
[ 0.3618034 , -0.26286556, -0.40224793],
[-0.26286556,  0.19098301,  0.29225023],
[-0.40224793,  0.29225023,  0.4472136 ]
])

# 简并特征值1对应的投影算子
array([
[ 0.6381966 ,  0.26286556,  0.40224793],
[ 0.26286556,  0.80901699, -0.29225023],
[ 0.40224793, -0.29225023,  0.5527864 ]
])

核心疑问

SymPy为何返回这类特征向量?问题出在我的代码实现还是SymPy本身?如果是我的问题,哪里出错了?

内容的提问来源于stack exchange,提问作者Riemann

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 12:47:02