高斯算法显示出意外的行为

时间:2012-12-01 17:42:43

标签: python algorithm python-2.7

我已经实现了没有旋转的高斯算法。

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)。任何人都可以解释为什么会这样吗?

1 个答案:

答案 0 :(得分:1)

您对Ab的并行更新不正确,因为您使用b值更新A。你需要替换这些行:

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,而第二部分减去0.0来自b[i]的{​​{1}}次b[l]