DEBUG.WIKI
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →
PanstarCloud:部署应用,接入 AI,云服务器与 AI 网关
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →

SciPy 1.18 的 LinearOperator 子类报没有 _xp,补上基类初始化

SciPy 1.18.1 的 LinearOperator 需要基类建立数组命名空间。补上初始化或采用公开构造接口,再核对真实矩阵乘积与求解残差。

原来的矩阵算子只设置 shape、dtype 并实现 _matvec,升级 SciPy 1.18 后,eigsh() 还没算出结果就失败:

AttributeError: 'MyLinearOperator' object has no attribute '_xp'

先检查子类自己的 __init__。SciPy 1.18.1 的基类初始化还负责设置数组命名空间 _xp 和维数 ndim;只补两个公开属性,已经不能满足后续 matvec 的需要。旧版文档中“可以调用基类初始化”的措辞,不足以代表 1.18 实际实现的要求。

在子类中调用 super,而不是手工补私有字段

下面是 NumPy 一维向量、实对角算子的定义示例:

import numpy as np
from scipy.sparse.linalg import LinearOperator


class DiagonalOperator(LinearOperator):
    def __init__(self, diagonal):
        values = np.asarray(diagonal, dtype=np.float64)
        if values.ndim != 1 or values.size == 0:
            raise ValueError("diagonal must be a nonempty 1-D array")
        self._diagonal = values.copy()
        super().__init__(dtype=values.dtype, shape=(values.size, values.size))

    def _matvec(self, x):
        x = np.asarray(x)
        if x.ndim != 1 or x.shape[0] != self.shape[1]:
            raise ValueError("expected a 1-D vector with matching length")
        return self._diagonal * x

示例明确选用 float64 与 NumPy,并在乘法入口拒绝非一维或长度不匹配的向量;它不承接矩阵对象的特殊兼容路径。真实算子应保留自己的数值类型、矩阵尺寸和乘法语义,不能为了让初始化通过,把复数矩阵转换成实数,或把矩形算子改成方阵。super().__init__ 只建立基类状态,不会替你实现正确的乘法。

不要直接写 self._xp = np 来消除报错。它绕过了基类的类型与形状处理,也依赖内部字段;将来另一个方法需要 ndim 等状态时,还可能继续失败。

如果已有子类把 shape、dtype 实现成只读 property,调用基类初始化时可能触发新的赋值错误。这种设计需要一起调整属性实现,或改用公开的构造接口,不能不看子类结构就加一行 super。

不需要继承时,交给公开构造函数

若现有项目已经有可信的矩阵向量乘法函数,也可以直接创建算子:

operator = LinearOperator(
    shape=(n, n),
    matvec=existing_matvec,
    dtype=np.float64,
)

这里的 n 和 existing_matvec 是项目已有的维度与函数,必须满足输入输出形状及 dtype 约定。这一入口会建立内部算子对象,适合并不需要自定义子类状态的场景;它不会自动补齐求解器要求的对称性、伴随乘法或其他数学条件。

先看完整堆栈:若 _xp 缺失出现在另一个类中,或者算子已经正常调用基类,再查包装层是否绕过初始化、恢复旧对象时是否丢状态。不要把每个 AttributeError 都改成同一行。

用乘法结果和原求解任务一起验收

保留修改前的子类和依赖锁定。先用已知向量检查算子乘积与显式矩阵结果是否一致,再运行原来的 eigsh 或其他迭代求解任务,比较残差、特征值与预期约束。对真实项目支持的 dtype、输入维度和伴随路径分别复查;没有异常不代表数学结果正确。

升级还可能带来独立的形状警告。1.18 的列向量 (N, 1) 在 matvec 路径会有弃用提示,不能把它与缺 _xp 合并处理;按实际需要评估 matmat 与输入布局。回退时恢复完整依赖和算子实现组合,避免把仅适配新版内部状态的临时字段留在旧环境里。