//		-*- Mode: Java -*-
// Author(s):	J. Robert Buchanan and Zhoude Shao
// Address:	Department of Mathematics
//		Millersville University
//      	P.O. Box 1002
//		Millersville, PA 17551-0302
// Phone:	717-871-7305
// FAX:		717-871-7948
// Email:	Robert.Buchanan@millersville.edu, Zhoude.Shao@millersville.edu
//
// Date:	10/13/2016
//
// Purpose:	SOR method for approximating solution to a linear
//		system of equations. This program generates data for
//		Example 14.8.
//
// To compile:	javac exampleSOR.java
// To execute:	java exampleJSOR
//
import java.io.*;

public class exampleSOR
{
    public static boolean stopcond(
				   int k	,
				   int nelts	,
				   double [][] soln
				   )
    {
	double [] norm = new double[2]	;
	int i	;

	norm[0] = 0.0	;
	norm[1] = 0.0	;
	for ( i=0 ; i<nelts ; i++ ) {
	    norm[0] += (soln[0][i]-soln[1][i])*(soln[0][i]-soln[1][i])	;
	    norm[1] += soln[k%2][i]*soln[k%2][i]	;
	}	// end of for ( i ) loop
	norm[0] = Math.sqrt(norm[0])	;
	norm[1] = Math.sqrt(norm[1])	;

	return( norm[0]/norm[1] < 1.0E-06 )	;

    }	// end of function stopcond( )
    
    public static void main(String args[])
    {
	int i, j, k;	// counter(s)
	int nelts = 5	;	// dimension of linear system
	int maxiters = 20+1;	// hard stop at 10 iterations of method
	//double w = 1.0	;	// SOR parameter, w=1 ==> Gauss-Seidel
	double w = 1.21539	;	// SOR parameter, w=1 ==> Gauss-Seidel
	double [][] a = { {-4.0, 1.0, 0.0, 0.0, 0.0},
			  {1.0, -4.0, 1.0, 0.0, 0.0},
			  {0.0, 1.0, -4.0, 1.0, 0.0},
			  {0.0, 0.0, 1.0, -4.0, 1.0},
			  {0.0, 0.0, 0.0, 1.0, -4.0}
	};	// matrix coefficients
	double [] b = {1.0, 2.0, 3.0, 4.0, 5.0}	;	// RHS of equation
	double [][] soln = new double[2][nelts];// 2 recent approximations

	// Initial approximation
	for ( i=0 ; i<nelts ; i++ ) {
	    soln[0][i] = 0.0	;
	    System.out.printf("%8.4f ", soln[0][i])	;
	}	// end of for ( i ) loop
	System.out.printf("\n")	;
	for ( k=1 ; k<maxiters ; k++ ) {
	    for ( i=0 ; i<nelts ; i++ ) {
		soln[k%2][i] = b[i]	;
		for ( j=0 ; j<i ; j++ ) soln[k%2][i] -= a[i][j]*soln[k%2][j];
		for ( j=i ; j<nelts ; j++ ) soln[k%2][i] -= a[i][j]*soln[(k-1)%2][j];
		soln[k%2][i] *= w/a[i][i]	;
		soln[k%2][i] += soln[(k-1)%2][i];
		System.out.printf("%8.4f ", soln[k%2][i])	;
	    }	// end of for ( i ) loop
	    System.out.printf("\n")	;
	    if ( stopcond(k,nelts,soln) ) return	;
	}	// end of for ( k ) loop
    }	// end of function main( )
}

//
//	EOF
//

