Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
三对角矩阵算法(TDMA)又名托马斯算法,使用Python和NumPy数组_Python_Arrays_Algorithm_Matlab_Matrix - Fatal编程技术网

三对角矩阵算法(TDMA)又名托马斯算法,使用Python和NumPy数组

三对角矩阵算法(TDMA)又名托马斯算法,使用Python和NumPy数组,python,arrays,algorithm,matlab,matrix,Python,Arrays,Algorithm,Matlab,Matrix,我在MATLAB中找到了thomas算法或TDMA的一个实现 function x = TDMAsolver(a,b,c,d) %a, b, c are the column vectors for the compressed tridiagonal matrix, d is the right vector n = length(b); % n is the number of rows % Modify the first-row coefficients

我在MATLAB中找到了thomas算法或TDMA的一个实现

function x = TDMAsolver(a,b,c,d)
    %a, b, c are the column vectors for the compressed tridiagonal matrix, d is the right vector
    n = length(b); % n is the number of rows

    % Modify the first-row coefficients
    c(1) = c(1) / b(1);    % Division by zero risk.
    d(1) = d(1) / b(1);    % Division by zero would imply a singular matrix.

    for i = 2:n-1
        temp = b(i) - a(i) * c(i-1);
        c(i) = c(i) / temp;
        d(i) = (d(i) - a(i) * d(i-1))/temp;
    end

    d(n) = (d(n) - a(n) * d(n-1))/( b(n) - a(n) * c(n-1));

    % Now back substitute.
    x(n) = d(n);
    for i = n-1:-1:1
        x(i) = d(i) - c(i) * x(i + 1);
    end
end
我需要它在python中使用numpy数组,这是我在python中的第一次尝试

import numpy

aa = (0.,8.,9.,3.,4.)
bb = (4.,5.,9.,4.,7.)
cc = (9.,4.,5.,7.,0.)
dd = (8.,4.,5.,9.,6.)

ary = numpy.array

a = ary(aa)
b = ary(bb)
c = ary(cc)
d = ary(dd)

n = len(b)## n is the number of rows

## Modify the first-row coefficients
c[0] = c[0]/ b[0]    ## risk of Division by zero.
d[0] = d[0]/ b[0]

for i in range(1,n,1):
    temp = b[i] - a[i] * c[i-1]
    c[i] = c[i]/temp
    d[i] = (d[i] - a[i] * d[i-1])/temp

d[-1] = (d[-1] - a[-1] * d[-2])/( b[-1] - a[-1] * c[-2])

## Now back substitute.
x = numpy.zeros(5)
x[-1] = d[-1]
for i in range(-2, -n-1, -1):
    x[i] = d[i] - c[i] * x[i + 1]

它们给出不同的结果,那么我做错了什么呢?

两者之间至少有一个区别:

for i in range(1,n,1):
在Python中,从索引1迭代到最后一个索引
n-1
,而

for i = 2:n-1

从索引
1
(从零开始)迭代到
last-1
索引,因为Matlab有一个基于一的索引。

在循环中,Matlab版本迭代第二个到第二个到最后一个元素。要在Python中执行同样的操作,您需要:

for i in range(1,n-1):

(正如voithos的评论中所指出的,这是因为range函数排除了最后一个索引,所以除了对0索引的更改之外,还需要对此进行更正)。

我这样做是因为python的在线实现都不起作用。我已经用内置的矩阵求逆法对它进行了测试,结果匹配

此处
a=下对角线
b=主对角线
c=上对角线
d=解向量

import numpy as np

def TDMA(a,b,c,d):
    n = len(d)
    w= np.zeros(n-1,float)
    g= np.zeros(n, float)
    p = np.zeros(n,float)
    
    w[0] = c[0]/b[0]
    g[0] = d[0]/b[0]

    for i in range(1,n-1):
        w[i] = c[i]/(b[i] - a[i-1]*w[i-1])
    for i in range(1,n):
        g[i] = (d[i] - a[i-1]*g[i-1])/(b[i] - a[i-1]*w[i-1])
    p[n-1] = g[n-1]
    for i in range(n-1,0,-1):
        p[i-1] = g[i-1] - w[i-1]*p[i]
    return p
要轻松提高大型矩阵的性能,请使用numba!在我的测试中,此代码的性能优于
np.linalg.inv()

import numpy as np
from numba import jit    

@jit
def TDMA(a,b,c,d):
    n = len(d)
    w= np.zeros(n-1,float)
    g= np.zeros(n, float)
    p = np.zeros(n,float)
    
    w[0] = c[0]/b[0]
    g[0] = d[0]/b[0]

    for i in range(1,n-1):
        w[i] = c[i]/(b[i] - a[i-1]*w[i-1])
    for i in range(1,n):
        g[i] = (d[i] - a[i-1]*g[i-1])/(b[i] - a[i-1]*w[i-1])
    p[n-1] = g[n-1]
    for i in range(n-1,0,-1):
        p[i-1] = g[i-1] - w[i-1]*p[i]
    return p

用python编写这样的东西会非常慢。您最好使用LAPACK来进行数字重载,并使用python来处理它周围的所有内容。LAPACK经过编译,因此它的运行速度将比python快得多。它的优化程度也比我们大多数人所能匹配的要高得多

SciPY为LAPACK提供了低级包装,因此您可以非常简单地从python调用它,您正在寻找的包装可以在这里找到:


Python的
range()
函数不包括最后一个索引,因此在这种情况下
for
循环将在n-1之后停止。@瞧:它不包括
n
,但
n-1
是最后一个索引,因为Python的索引是零基的,而Matlab的索引是一基的。啊,这一点不错。我认为一个关键的区别(我没有意识到)是Python的
range()
没有到达指定的结束索引(正如您所说,这是由于Python从0开始索引),而Matlab的
x:x
语法没有经过结束索引。