高斯算法显示意外行为



>我已经实现了没有透视的高斯算法。

import matplotlib.pyplot as plt
import numpy as np
import scipy as sp
def gauss_solve(A,b):
    """
    args: coefficient matrix A of dim(nxn) and vector b of dim(n) 
    of a system of linear equations with n unknowns.
    note: no zeroes on the main diagonal of A allowed!
    returns: vector x of dim(n) which solves the SLE
    """
    while np.ndim(A) != 2 or A.shape[0] != A.shape[1]:
        A = input(["The matrix you entered is not square, specify new input matrix A: "])
#    print "A ok."
    while np.ndim(b) != 1 or A.shape[1] != b.shape[0]:
        b = input(["The dimension of the constant vector b is incorrect, please specify new input vector b"])
#    print "b ok."
    if np.linalg.det(A) == 0:
        return "This linear system doesn't have a single unique solution."
#    print "System does have solution: "
    n = len(b)
    for i in xrange(n): # create triangular matrix
        if A[i,i] == 0:
            return "This implementation doesn't allow A to have zero entries on the main diagonal."
        A[i] = A[i]/float(A[i,i])
        b[i] = b[i]/float(A[i,i])
        for l in xrange(i+1,n):
            A[l] -= A[i]*A[l,i]
            b[l] -= b[i]*A[l,i]
    r = np.zeros(n) # result
    for i in xrange(n):
        r[-(i+1)] = b[-(i+1)] - np.dot(r,A[-(i+1)])
    return r
def test_gauss():
    m = 10
    e = 0.1
    A = sp.rand(m,m)
#    A,b = np.array([[e,1.],[1.,1.]]),np.array([1.,e])
    b = sp.rand(m)
    print gauss_solve(A,b)
    print "Build-in function says: n", np.linalg.solve(A,b)
test_gauss()

测试函数可以为Ab生成随机条目。我认为一切正常,但我这里有一个矩阵,会导致意外的结果:

A = [[e 1] [1 1]]
b = [1 e]

对于e != 1,分析解决方案是

x = [-1 e+1]

但是我尝试了一些e值,但我只是没有得到分析解决方案。甚至内置函数solve(A,b)失败。例如,x的第一个条目总是0(尽管它应该是-1的,完全独立于e)。谁能解释为什么会这样?

您对

Ab的并行更新不正确,因为您正在使用A的新值更新b。 您需要替换以下行:

A[i] = A[i]/float(A[i,i])
b[i] = b[i]/float(A[i,i])

像这样:

divisor = A[i,i]
A[i] = A[i]/float(divisor)
b[i] = b[i]/float(divisor)

同样,这些行:

A[l] -= A[i]*A[l,i]
b[l] -= b[i]*A[l,i]

multiplier = A[l,i]
A[l] -= A[i]*multiplier
b[l] -= b[i]*multiplier

在原始代码中,b行不执行任何操作(忽略浮点精度问题):代码的第一部分将b[i]除以1.0,而第二部分从b[l]中减去b[i] 0.0倍。

最新更新