向量化(手动)正向替换

时间:2018-06-21 21:51:20

标签: python numpy vectorization

我是用于求解线性系统的手写代码(我知道NumPy可以使用np.linalg.solve或类似的来为我解决此问题)。我要编写的功能之一是用于正向替换-即为Ly=b求解y,其中L是单位下三角矩阵,而b是列向量。

我想出了以下解决方案

def solve_forward(L, b):
    y = b.copy()
    for r in range(1, L.shape[0]):
        y[r] -= L[r, :r] @ y[:r]
    return y 

我想知道是否可以进行某种减法累加来删除循环,或者是否看起来像是“向量化”的。

1 个答案:

答案 0 :(得分:2)

方程Ly=b的解可以通过对矩阵L求逆并在两边左乘而得到,从而得到:y=L'b,其中L'是逆矩阵L的矩阵。可以用例如np.linalg.inv

在不使用numpy的情况下进行矩阵求逆将是乏味的。但是,我怀疑您可能会做得很好,因为您有一个较低的三角形单位矩阵。

下三角单元矩阵L的逆(1也位于对角线上)可以显示为

def Linv(i,j):
    if i==j:
        return 1
    elif j==i-1:
        return -1

可能有更好的计算方法,但这是一种方法:

import numpy as np
from scipy.linalg import circulant
L=np.tril(np.ones((4,4)))
dim=L.shape[0]
Linv=[np.concatenate([np.array([1,-1]), np.zeros(dim-2)])]
Linv=np.tril(circulant(Linv))
print(Linv)

有关circulant matrix function的更多信息。

现在,把它们放在一起:

import numpy as np
from scipy.linalg import circulant

def L_inv(l_dim):
    Linv=[np.concatenate([np.array([1,-1]), np.zeros(l_dim-2)])]
    Linv=tril(circulant(Linv))

def solve_forward(L, b):
    y = L_inv(L.shape[0]) @ b
    return y

应该能按预期工作。

编辑:在这种情况下,前一个toeplitz无效。用更合适的circulant进行切换。

编辑2 :仅应使用circulant的下三角部分。