![](/img/trans.png)
[英]Why is 'scipy.sparse.linalg.spilu' less efficient than 'scipy.linalg.lu' for sparse matrix?
[英]What algorithm does the scipy.sparse.linalg.spilu(A).solve() function use?
考慮以下代碼:
import numpy as np
import scipy.sparse.linalg
# Setup
A = scipy.sparse.csc_matrix([[1, -3], [-1, 4]])
b = np.array([1, 0])
spilu = scipy.sparse.linalg.spilu(A) # Find ILU decomposition
x = spilu.solve(b) # Use an iterative method to solve Ax = b ?
這導致x
是Ax = b
的解。
據我了解, scipy.sparse.linalg.spilu(A)
計算的是 A 的不完全 LU 分解。
我的問題是: spilu.solve(b)
究竟使用什么算法來求解Ax = b
?
我希望它使用一些迭代方法,例如共軛梯度法,因為這似乎是使用不完全 LU 分解的正常方法。 但是,我一直無法找到支持或不同意這一點的文件。 Furthermore, I'm confused because I see some people use LinearOperator
and scipy.sparse.linalg.cg
/ scipy.sparse.linalg.cg
in conjunction with scipy.sparse.linalg.spilu(A)
, which would seem foolish if my hypothesis是正確的( 例如)。
文檔說:
這個 function 使用 SuperLU 庫。
代碼通過:
return _superlu.gstrf(N, A.nnz, A.data, A.indices, A.indptr,
csc_construct_func=csc_construct_func,
ilu=True, options=_options)
這只是一個 SuperLU 包裝器:
static char gstrf_doc[] = "gstrf(A, ...)\n\
\n\
performs a factorization of the sparse matrix A=*(N,nnz,nzvals,rowind,colptr) and \n\
returns a factored_lu object.\n\
\n\
arguments\n\
---------\n\
\n\
Matrix to be factorized is represented as N,nnz,nzvals,rowind,colptr\n\
as separate arguments. This is compressed sparse column representation.\n\
\n\
N number of rows and columns \n\
nnz number of non-zero elements\n\
nzvals non-zero values \n\
rowind row-index for this column (same size as nzvals)\n\
colptr index into rowind for first non-zero value in this column\n\
size is (N+1). Last value should be nnz. \n\
\n\
additional keyword arguments:\n\
-----------------------------\n\
options specifies additional options for SuperLU\n\
(same keys and values as in superlu_options_t C structure,\n\
and additionally 'Relax' and 'PanelSize')\n\
\n\
ilu whether to perform an incomplete LU decomposition\n\
(default: false)\n\
";
看看最后一個參數 -> ilu!
splu看起來像:
return _superlu.gstrf(N, A.nnz, A.data, A.indices, A.indptr,
csc_construct_func=csc_construct_func,
ilu=False, options=_options)
這表明整個完整與不完整的邏輯被傳遞給 SuperLU。
現在讓我們看一下SuperLU 的手冊:
2.7 不完全 LU 因式分解 (ILU) 預條件子
從 SuperLU 4.0 版開始,我們提供 ILU 例程用作迭代求解器的預處理器。 我們的 ILU 方法可以被認為是最初由 Saad [31] 提出的 ILUTP 方法的變體,它結合了雙重丟棄策略和數值旋轉(“T”代表閾值,“P”代表旋轉)。
參考文獻[31]是:
薩德,優素福。 “ILUT:雙閾值不完全 LU 分解。” 數值線性代數與應用 1.4 (1994): 387-402。
這對我來說看起來像是一種 DIRECT 方法( Eigen 也使用它),但我認為您將能夠查找您需要知道的內容。
此求解方法通過使用A
的不完全分解來近似求解Ax=b
。 這就是為什么您看到它在那些迭代方法中用作預處理器。 求解方法是使用不完整因子的經典稀疏前/后替換算法,但由於它們不完整,因此不太可能給出准確的結果。
添加到 sascha 的答案:
_superlu.gstrf返回的object的solve
_superlu.gstrf
可以在scipy/sparse/linalg/_dsolve/_superluobject.Z4A8A08F09D37B7379563Z903.F中找到主要部分是對gstrs
的調用(注意它是gstr s
而不是gstr f
):
static PyObject *SuperLU_solve(SuperLUObject * self, PyObject * args,
PyObject * kwds)
{
...
gstrs(self->type,
trans, &self->L, &self->U, self->perm_c, self->perm_r,
(SuperMatrix *)&B, (SuperLUStat_t *)&stat, (int *)&info);
...
}
查看SuperLU 的文檔:
DGSTRS solves a system of linear equations A*X=B or A'*X=B
with A sparse and B dense, using the LU factorization computed by
DGSTRF.
所以Python代碼基本上在做的是調用*gstrf
來計算LU分解,然后把它交給*gstrs
來計算系統的解。
查看dgstrs
的源代碼,它看起來只是使用 LU 分解,無論它是否不完整(也沒有允許指定的參數),所以它只會給你一個近似的解決方案不完全分解。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.