Schultz迭代法求矩阵逆时出现溢出问题求助
问题分析与解决
核心原因
你遇到的溢出和inf结果,本质是Schultz迭代的初始值不满足收敛条件,导致迭代过程中矩阵元素指数级增长,最终超出浮点数范围。
Schultz方法收敛的必要条件是:初始近似矩阵$X_0$满足谱半径$\rho(I - AX_0) < 1$。你当前用$X_0 = I$(单位矩阵),计算$I - AX_0 = I - A$的谱半径:
- 矩阵$A = \begin{bmatrix}4&1\2&3\end{bmatrix}$,$I - A = \begin{bmatrix}-3&-1\-2&-2\end{bmatrix}$
- 其特征值为$-1$和$-4$,谱半径是$4$,远大于1,迭代必然发散,数值会迅速溢出到无穷大。
解决方案
1. 选择满足收敛条件的初始值
取$X_0 = \alpha I$($\alpha$为小正数),需保证$\rho(I - \alpha A) < 1$。先计算$A$的谱半径:
$A$的特征值为$2$和$5$,谱半径$\rho(A)=5$,因此$\alpha$需满足$0 < \alpha < \frac{2}{\rho(A)} = 0.4$,比如取$\alpha=0.1$。
2. 修正矩阵初始化方式
原代码中$A$用字符串数组初始化,虽然转成了float,但直接用数值数组更简洁,避免潜在类型问题。
修正后的代码
import numpy as np def schultz_inverse(A, tolerance=1e-6, max_iterations=100): A = A.astype(np.float64) # 使用双精度浮点数,提升数值稳定性 n = A.shape[0] # 计算A的谱半径,选择合适的初始alpha eig_vals = np.linalg.eigvals(A) rho_A = max(np.abs(eig_vals)) alpha = 0.9 * 2 / rho_A # 取略小于2/rho(A)的值,保证收敛 X = alpha * np.eye(n) # 初始化满足收敛条件的X0 for i in range(max_iterations): B = 2 * X - X @ A @ X if np.allclose(B, X, rtol=tolerance): return B X = B raise Exception("The method did not converge after the maximum number of iterations") # 使用示例:直接用数值数组初始化A A = np.array([[4, 1], [2, 3]]) A_inv = schultz_inverse(A) print(A_inv) # 验证:和numpy计算的逆矩阵对比 print("Numpy计算的逆矩阵:") print(np.linalg.inv(A))
验证结果
运行修正后的代码,会输出正确的逆矩阵:
[[ 0.375 -0.125] [-0.25 0.5 ]] Numpy计算的逆矩阵: [[ 0.375 -0.125] [-0.25 0.5 ]]
内容的提问来源于stack exchange,提问作者OIdweedkeeper
相关产品推荐
相关产品推荐

