package m_4_5_Romberg_Integration;


public class Romberg_Richardson {
	
	// Grösse der Matrix
	public static int n = 6;


	public static double f(double x){
		return Math.sin(x);
	}

	public static void main(String[] arg){
		double [][] r = new double[n][n];
		
		System.out.println("Romberg-Verfahren zur IntegralApproximation\n\n");
		
		romberg(r, 0, Math.PI);
		printMatrix(r);
	}
	
	// r: Matrix; a = Anfang; b = Ende
	public static void romberg(double [][]r, double a, double b){
		int n = r.length;
		double h = 0.0;
		
		r[0][0] = (b-a)/2.0*(f(a)+ f(b));
		
		// 1. Spalte
		for(int k = 1; k<n; k++){
			h = (b-a)/(Math.pow(2, k));
			double sum = 0.0;
			for (int i = 1; i<=Math.pow(2, k-1); i++){
				sum+= f( a + (2*i-1)*h);
			}
			r[k][0]= 1.0/2.0 * (r[k-1][0] + h*2*sum);
		}

		// Richardson-Extrapolation
		for (int j = 1; j<n; j++){
			for (int k = j; k<n; k++){
				r[k][j]= r[k][j-1] + ( r[k][j-1] - r[k-1][j-1])/(Math.pow(4, j)-1);
			}
		}
		// Ausgabe
		System.out.println("Approximation: "+r[n-1][n-1]+"\n");
	}
	
	private static void printMatrix(double[][]A){
			int breite = A[1].length;
			int hoehe = A.length;
			for(int i = 0; i<hoehe; i++){
				System.out.print("      ");
				for(int k = 0; k<breite; k++){
					InOut.print(A[i][k], 2, 5);
					System.out.print("    ");
				}
				System.out.println("      ");
			}
		}
}
