【发布时间】:2018-09-17 10:40:59
【问题描述】:
我试图了解使用 numpy 和 scipy 库进行 LU 分解的必要性。据我了解,我们要求解 Ax = b,我们首先将 A 分解为两个三角矩阵 L 和 U,然后通过求解 Ly = b 然后 Ux = y 求解 LUx = b。通过求解三角矩阵,与高斯消元法相比,我们可以减少时间。
所以,我在 python 中使用 numpy 和 scipy 厌倦了这个想法。
我首先使用玩具示例构造 A 和 b:
A = np.array([[2, 1, 0, 5], [1, 2, 1, 2], [0, 1, 2, 4], [1, 3, 6, 4.5]])
b = np.array([9, 10, -2, 3])
那么先在 np.solve 中解决这个玩具例子
%timeit np.linalg.solve(A, b )
时间是
每个循环 9.76 µs ± 782 ns(7 次运行的平均值 ± 标准偏差,每次 100000 次循环)
然后我使用分解来解决这个系统:
lu, piv = linalg.lu_factor(A)
%timeit linalg.lu_solve((lu, piv), b)
我看到输出是
每个循环 18.8 µs ± 213 ns(7 次运行的平均值 ± 标准偏差,每次 100000 次循环)
,与 np.solve 相比非常缓慢。
所以,我的问题是,为什么 np.solve 比 linalg.lu_factor 快?我的猜测是 numpy.solve 不使用高斯消元法来求解方程?对这里的结果有点困惑。
编辑
现在,我使用一个更大的矩阵进行实验 (10000 x 10000)。
结果如下: 对于 np.linalg.solve
8.64 s ± 180 ms per loop (mean ± std. dev. of 7 runs, 1 loop each);
对于 scipy.linalg.lu_solve
121 ms ± 3.79 ms per loop (mean ± std. dev. of 7 runs, 10 loops each).
对于lu_solve,我只计算求解的时间,分解部分不计算。现在速度更快了!
【问题讨论】:
-
我想知道“通过求解三角矩阵,与高斯消元法相比,我们可以减少时间。”这一说法的来源。 AFAIU LU分解基本上是高斯消除的一种修改形式,因此LU分解本身的时间复杂度不能比高斯消除更好。如果你想用不同的
bs 解决许多Ax = b,LU 分解可能是有益的,但对于单个系统,我认为没有理由让它更快。 -
尝试更多、很多个更大的矩阵,以确保 Python 与 C 算法对话的开销(相对)尽可能小。在 4x4 矩阵上进行比较毫无意义,为函数调用分配所有帧堆栈将比实际计算花费更长的时间。
-
@SergGr 也许我之前的问题令人困惑。我是说在LU分解之后,使用L和U来求解方程应该比高斯消去更快。
-
@AndreyTyukin 我现在使用更大的矩阵来执行此操作,lu_solve 的结果要快得多。
标签: python numpy math scipy linear-algebra