numpy.linalg.solve和numpy.linalg.lu_solve之间的区别

时间:2017-06-21 09:26:36

标签: python numpy

要解决线性矩阵方程,可以使用numpy.linalg.solve 它实现了LAPACK例程*gesv

根据文件

DGESV computes the solution to a real system of linear equations
    A * X = B,
 where A is an N-by-N matrix and X and B are N-by-NRHS matrices.

 The LU decomposition with partial pivoting and row interchanges is
 used to factor A as
    A = P * L * U,
 where P is a permutation matrix, L is unit lower triangular, and U is
 upper triangular.  The factored form of A is then used to solve the
 system of equations A * X = B.

但是,我们也可以使用scipy.linalg.lu_factor()scipy.linalg.lu_solve() 为了解决我们的问题,lu_factor()

Compute pivoted LU decomposition of a matrix.

The decomposition is:

A = P L U

where P is a permutation matrix, 
L lower triangular with unit diagonal elements, 
and U upper triangular.

显然这两种方法似乎是多余的。这种冗余有什么意义吗?似乎让我感到困惑..

1 个答案:

答案 0 :(得分:3)

确实你是对的:链接scipy的scipy.linalg.lu_factor()scipy.linalg.lu_solve()完全等同于numpy的numpy.linalg.solve()然而,可以访问LU分解在实际情况下是一个很大的优势。

首先,让我们证明等价。 numpy.linalg.solve()声明:

  

使用LAPACK例程_gesv

计算解决方案

实际上,github repository of numpy包含精简版LAPACK。 然后,我们来看看LAPACK dgesv的来源。计算矩阵的LU分解并用于求解线性系统。实际上,函数的源代码非常清楚:appart用于输入检查,它归结为调用dgetrf(LU分解)和dgetrs。最后,scipy.linalg.lu_factor()scipy.linalg.lu_solve()分别包含dgetrfdgetrs,其中包含getrf, = get_lapack_funcs(('getrf',), (a1,))getrs, = get_lapack_funcs(('getrs',), (lu, b1))等行。

正如@Alexander Reynolds所注意到的,LU分解可用于计算矩阵的行列式和秩。实际上,关于行列式, numpy.det调用LU分解_getrf!请参阅source of numpy.linalg。然而,numpy使用SVD分解来计算矩阵的等级。

但是使用LU计算排名并不是将接口暴露给dgetrfdgetrs的唯一原因。确实常见的情况是,dgetrf一次校准,将LU分解在内存中并多次调用dgetrs是一个决定性的优势。例如,请查看 iterative refinement 。必须注意的是,计算LU分解比使用分解(N ^ 2)求解线性系统需要更多的时间(N ^ 3)。

让我们看一下 Newton-Raphson method来求解耦合非线性方程 F(x)= 0的系统,其中F:R ^ N-> R ^ N.执行Newton-Raphson迭代需要求解一个线性系统,其中矩阵是雅可比矩阵J:

其中x_ {i + 1}是未知的。雅可比J(x_i)的计算成本通常很高,而不是必须解决系统必须解决的问题。因此,通常会考虑准牛顿方法,其中建立雅可比的近似值。一个直截了当的想法是不是每次迭代都更新雅可比矩阵并且只要残差的范数减小就继续迭代。 在此过程中,会不时调用dgetrf,而每次迭代都会调用dgetrs有关方案,请参阅there。让我们看一个例子:让我们尝试从x_0 = 2开始求解x ^ 2 = 1。对于牛顿方法的4次迭代,我们得到f(x_4)= 9.2e-8和f(x_5)<1e​​-13。但是如果每十次迭代更新一次雅可比行列式,则只需要对雅可比行列式进行两次评估即可得到f(x_12)= 5.7e-11和f(x_13)= 2.2e-14。

enter image description here enter image description here

更有效的策略包括每次迭代更新一次LU分解而不考虑任何矩阵。请参阅Denis和Marwil的"Direct Secant Updates of Matrix Factorizations"以及Brown等的"EXPERIMENTS WITH QUASI-NEWTON METHODS IN SOLVING STIFF ODE SYSTEMS" 。人

因此,在non-linear finite element analysis中,并非每次牛顿迭代(option of Code_Aster in paragraph 3.10.2 MATRICE dianahere或{{3}都会评估切线刚度的装配}。