The Gauss-Seidal Method is another iterative method used to solve a system of linear equations. It is also known as the method of successive displacement.It converges only if the matrix is strictly diagonally dominant or symmetric and positive definite. Let us see how to use this method to solve linear equations.
- We will need to give the number of variables or the size of the coefficient matrix. The column order will be m=n+2. This is because we will add two more columns, one that will be part of the augmented matrix(the R.H.S or constants in the equations) and another which will store the initial guesses for the solutions x1 through xn.
- Next we set maxcount, the maximum number iterations, at the terminal. Then we read the input file and display it on the screen.
- We call a subroutine to solve the equation. The subroutine first tests the coefficient matrix for strict diagonal dependence. And , gives a go ahead only if it satisfies this condition. Else, the method fails. To test for diagonal dependence we simply sum the absolute values of all elements other than those on the diagonal for every row. We then test if the absolute value of diagonal elements in each row is greater than the sum of absolute values of all other elements in that row.
- We set an array b(:)=a(:,n+1), which is the R.H.S of the actual equations. And we set the array x=0, our initial guesses.
- In a DO loop, we set oldx=0 and start changing values of x(i) using two more DO loops. At the end of these loops , we check diff=abs(x-oldx) and error=sum(diff). If error<eps, we return and display results in the main program. If not, we continue running the two DO loops till this is attained.
- Sometimes, the method does not converge. In this case we display "maximum number of iterations exceeded" if pcount>maxcount.
Gauss-Seidal Method for a System of 3 Linear Equations |
Now for the Fortran Program,
module seidal
real, allocatable, dimension (:) :: a(:,:),x(:),b(:)
end module seidal
!To find solutions for a system of linear equations using the Gauss Seidal Method
program seidal_main
use seidal
implicit none
integer :: m,i,j,flag,n,maxcount
write(*,*) "Give the row order of matrix"
read (*,*) n
write(*,*) "The row order of the matrix is",n
m=n+2
write(*,*) "The column order of the matrix is ",m
write(*,*) !To read the maximum number of iterations
write(*,*) "Give the maximum count of iterations"
read (*,*) maxcount
write (*,*) "The maximum number of iterations is", maxcount
allocate (a(n,m),x(n),b(n))
write(*,*) "The augmented matrix is given below along with initial estimates:"
open (unit=1,file="gs111.dat")
do i=1,n
read (1,*) (a(i,j),j=1,m)
end do
do i=1,n
write (*,*) (a(i,j),j=1,m)
end do
call linear (m,flag,maxcount)
if (flag==0) then
write(*,*) "The coefficient matrix does not possess strict diagonal dominance. Hence, the Gause Seidal method fails."
else
write(*,*) "The matrix containing x values i.e. x1...xn"
do i=1,n
write(*,*) x(i)
end do
write(*,*) "The x values obtained satisfy the equations"
end if
end program seidal_main
subroutine linear (m,flag,maxcount)
use seidal
implicit none
integer:: i,j,flag, pcount,m,maxcount,n
real:: error,eps,sumrow,absD,sumND,sumax
real, allocatable::oldx(:), diff(:)
eps=10.0e-15
n=m-2
allocate (oldx(n),diff(n))
do i=1,n !To check the validity of the method (strict diagonal dominance)
sumrow=sum(abs(a(i,1:n)))
absD=abs(a(i,i))
sumND=sumrow-absD
if (absD.le.sumND) then
flag=0
return
else
flag=1
end if
end do
pcount=0
b(:)=a(:,n+1)
x=0
do !To begin the iteration
oldx=x
do i=1,n
sumax=0.0
do j=1,n
if (j<i) then
sumax=sumax+a(i,j)*x(j)
end if
if (j>i) then
sumax=sumax+a(i,j)*oldx(j)
end if
end do
x(i)=(b(i)-sumax)/a(i,i)
end do
diff=abs(x-oldx) !To find the sum of errors
error=sum(diff)
if (error<eps) exit
pcount=pcount+1
if (pcount>maxcount) then
write(*,*) "No. of iterations exceeded the maximum no. of iterations"
stop
end if
end do
end subroutine linear
module seidal
real, allocatable, dimension (:) :: a(:,:),x(:),b(:)
end module seidal
!To find solutions for a system of linear equations using the Gauss Seidal Method
program seidal_main
use seidal
implicit none
integer :: m,i,j,flag,n,maxcount
write(*,*) "Give the row order of matrix"
read (*,*) n
write(*,*) "The row order of the matrix is",n
m=n+2
write(*,*) "The column order of the matrix is ",m
write(*,*) !To read the maximum number of iterations
write(*,*) "Give the maximum count of iterations"
read (*,*) maxcount
write (*,*) "The maximum number of iterations is", maxcount
allocate (a(n,m),x(n),b(n))
write(*,*) "The augmented matrix is given below along with initial estimates:"
open (unit=1,file="gs111.dat")
do i=1,n
read (1,*) (a(i,j),j=1,m)
end do
do i=1,n
write (*,*) (a(i,j),j=1,m)
end do
call linear (m,flag,maxcount)
if (flag==0) then
write(*,*) "The coefficient matrix does not possess strict diagonal dominance. Hence, the Gause Seidal method fails."
else
write(*,*) "The matrix containing x values i.e. x1...xn"
do i=1,n
write(*,*) x(i)
end do
write(*,*) "The x values obtained satisfy the equations"
end if
end program seidal_main
subroutine linear (m,flag,maxcount)
use seidal
implicit none
integer:: i,j,flag, pcount,m,maxcount,n
real:: error,eps,sumrow,absD,sumND,sumax
real, allocatable::oldx(:), diff(:)
eps=10.0e-15
n=m-2
allocate (oldx(n),diff(n))
do i=1,n !To check the validity of the method (strict diagonal dominance)
sumrow=sum(abs(a(i,1:n)))
absD=abs(a(i,i))
sumND=sumrow-absD
if (absD.le.sumND) then
flag=0
return
else
flag=1
end if
end do
pcount=0
b(:)=a(:,n+1)
x=0
do !To begin the iteration
oldx=x
do i=1,n
sumax=0.0
do j=1,n
if (j<i) then
sumax=sumax+a(i,j)*x(j)
end if
if (j>i) then
sumax=sumax+a(i,j)*oldx(j)
end if
end do
x(i)=(b(i)-sumax)/a(i,i)
end do
diff=abs(x-oldx) !To find the sum of errors
error=sum(diff)
if (error<eps) exit
pcount=pcount+1
if (pcount>maxcount) then
write(*,*) "No. of iterations exceeded the maximum no. of iterations"
stop
end if
end do
end subroutine linear
Sample Output for Gauss Seidal Method for a System of 3 Linear Equations |
No comments:
Post a Comment