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

如何实现scipy.linalg.eigvals对单矩阵与批量矩阵的广播调用?

问题解决:scipy.linalg.eigvals批量处理广义特征值计算

错误原因

scipy.linalg.eigvals不支持自动识别批量矩阵(带前导额外维度的数组)。当传入形状为(3,2,2)的b时,函数无法将其解析为3个独立的2x2矩阵,而是将其视为非方阵的3D数组,因此抛出ValueError: expected square matrix错误。


可行方案

方案1:手动循环遍历批量矩阵

直接遍历b中的每个子矩阵,逐个计算与a的广义特征值,逻辑直观且性能稳定:

import scipy.linalg as la
import numpy as np

# 转换为numpy数组方便维度操作
a = np.array([[1, 2], [3, 4]])
b = np.array([[[5, 6], [7, 8]], [[9, 10], [11, 12]], [[13, 14], [15, 16]]])

eigvals = []
for b_i in b:
    vals = la.eigvals(a, b_i)
    eigvals.append(vals)

# 转换为形状为(3,2)的numpy数组
eigvals = np.array(eigvals)
print(eigvals)

方案2:使用numpy.apply_along_axis批量处理

利用numpy.apply_along_axis简化循环代码,沿着批量维度(axis=0)对每个子矩阵执行计算:

import scipy.linalg as la
import numpy as np

a = np.array([[1, 2], [3, 4]])
b = np.array([[[5, 6], [7, 8]], [[9, 10], [11, 12]], [[13, 14], [15, 16]]])

# 定义单个矩阵对的特征值计算函数
def calc_single_eig(b_i):
    return la.eigvals(a, b_i)

# 沿着批量维度处理所有子矩阵,转置调整输出形状为(3,2)
eigvals = np.apply_along_axis(calc_single_eig, axis=0, arr=b).T
print(eigvals)

方案3:向量化包装(可选)

通过np.vectorize结合维度广播,实现更简洁的批量调用:

import scipy.linalg as la
import numpy as np

a = np.array([[1, 2], [3, 4]])
b = np.array([[[5, 6], [7, 8]], [[9, 10], [11, 12]], [[13, 14], [15, 16]]])

# 将a扩展为与b匹配的批量形状(3,2,2)
a_broadcast = np.broadcast_to(a, b.shape)

# 向量化eigvals函数,指定输入输出的矩阵/数组形状
vec_eig = np.vectorize(la.eigvals, signature='(n,n),(n,n)->(n)')
eigvals = vec_eig(a_broadcast, b)

print(eigvals)

补充说明

  • 所有方案均需先将列表转换为numpy数组,便于维度操作和计算。
  • 若处理超大规模批量数据(如上万矩阵),可考虑使用jax.scipy.linalg.eigvals,它原生支持广播和GPU加速,但需额外安装JAX库。对于100个20x20矩阵的场景,上述前两种方案完全能满足需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 04:05:46