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

如何子类化numpy array实现对称矩阵专用类?

最简实现对称矩阵的NumPy子类

要实现满足你需求的NumPy子类,核心是继承np.ndarray并在构造阶段处理矩阵对称化,同时通过懒加载方式实现特征分解字段U和D。以下是最简实现:

完整代码

import numpy as np

class SymmetricMatrix(np.ndarray):
    def __new__(cls, input_array):
        # 强制将输入矩阵转换为对称形式
        symmetric_arr = 0.5 * (input_array + input_array.T)
        # 创建子类实例并转换视图
        obj = np.asarray(symmetric_arr).view(cls)
        # 初始化特征分解缓存属性
        obj._U = None
        obj._D = None
        return obj

    @property
    def U(self):
        # 懒加载:首次访问时计算特征分解
        if self._U is None:
            # 针对对称矩阵,使用eigh效率更高(专门适配Hermitian/对称实矩阵)
            eig_vals, eig_vecs = np.linalg.eigh(self)
            # 反转顺序,让特征值从大到小排列(可选,根据需求调整)
            self._D = eig_vals[::-1]
            self._U = eig_vecs[:, ::-1]
        return self._U

    @property
    def D(self):
        # 复用U的计算逻辑,避免重复计算
        if self._D is None:
            self.U  # 触发U的计算,同时填充_D
        return self._D

    def __array_finalize__(self, obj):
        # 确保子类实例在视图转换、运算后保留缓存属性
        if obj is None:
            return
        self._U = getattr(obj, '_U', None)
        self._D = getattr(obj, '_D', None)

关键细节说明

  • 构造阶段对称化:重写__new__方法(NumPy数组的构造逻辑在__new__中完成,而非__init__),通过0.5*(m+m.T)强制输入矩阵对称,避免非对称数据传入。
  • 懒加载特征分解:用@property实现U和D,仅在首次访问时调用np.linalg.eigh计算特征值和特征向量,避免不必要的计算开销。相比np.linalg.svd,eigh针对对称矩阵做了优化,速度更快、精度更高。
  • 属性继承:__array_finalize__方法确保子类在进行数组运算(如加法、乘法)或视图转换时,保留_U和_D的缓存状态,避免重复计算。

使用示例

# 测试非对称输入
raw_mat = np.array([[1, 3], [2, 4]])
sym_mat = SymmetricMatrix(raw_mat)

# 验证矩阵对称
print("对称化后的矩阵:")
print(sym_mat)
# 输出:
# [[1.  2.5]
#  [2.5 4. ]]

# 获取特征向量和特征值
print("\n特征向量U:")
print(sym_mat.U)
print("\n特征值D:")
print(sym_mat.D)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 03:42:39