Fortran中基本高斯消除的意外行为

时间:2016-04-14 13:48:21

标签: fortran gfortran gaussian

我正在尝试使用许多广泛可用的例程之一来解决矩阵形式的线性方程组,特别是此函数gauss(以及具有已知结果的样本数据),但无论哪个消除策略我使用我一直得到不正确的结果,并且不知道在这一点上转向何处。我的代码:

    MODULE gaussMod
    CONTAINS
    function gauss(a,b) result(x)
        implicit none
        real*8 :: b(:), a(size(b), size(b))
        real*8 :: x(size(b))

        real*8 :: r(size(b))
        integer i,j, neq

        neq = size(b)

        do i =1, neq
            r = a(:,i)/a(i,i)

            do j = i+1, neq
                a(j,:) = a(j,:) - r(j)*a(i,:)
                b(j) = b(j) - r(j)*b(j)
            enddo
        enddo

        do i= neq, 1, -1
            x(i) = (b(i) - sum(a(i, i+1:) * x(i+1:))) / a(i,i)
        enddo
    END function
END MODULE

SUBROUTINE outFile(n,x)
    IMPLICIT none
    INTEGER n
    INTEGER i
    REAL*8, DIMENSION(n) :: x


    OPEN(UNIT=20,FILE="solution.csv",action="write",status="replace")

    DO i=1, n
        WRITE (20,"(1(f0.30,',',:))") x(i)
    END DO
    CLOSE(20)
END SUBROUTINE

PROGRAM elimtest
        USE gaussMod
        IMPLICIT none
        INTEGER, PARAMETER :: coeff_kind = selected_real_kind(p=30, r=99)
        INTEGER n
        REAL*8, DIMENSION(:,:), ALLOCATABLE :: a
        REAL*8, DIMENSION(:), ALLOCATABLE :: b
        REAL*8, DIMENSION(:), ALLOCATABLE :: x
        n = 4

        ALLOCATE(a(n,n))
        ALLOCATE(b(n))
        ALLOCATE(x(n))

            a(1,1) = 18.
            a(1,2) = -6.
            a(1,3) = -6.
            a(1,4) = 0.
            a(2,1) = -6.
            a(2,2) = 12.
            a(2,3) = 0.
            a(2,4) = -6.
            a(3,1) = -6.
            a(3,2) = 0.
            a(3,3) = 12.
            a(3,4) = -6.
            a(4,1) = 0.
            a(4,2) = -6.
            a(4,3) = -6.
            a(4,4) = 18.

            b(1) = 60.
            b(2) = 0.
            b(3) = 20.
            b(4) = 0.


        x = gauss(a,b)
        CALL outFile(n,x)


END PROGRAM

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:2)

看起来像以下一行

b(j) = b(j) - r(j)*b(j)

的错字
b(j) = b(j) - r(j)*b(i)

通过此修改,您的代码可以提供正确的结果(可能!):

x(:) = 8.3333333333333339  6.6666666666666670  8.3333333333333339  5.0000000000000000