//  -----------------------------------------------------------------
//  -------  Numerische Mathematik                   ----------------
//  -------  Ib 03                                   ----------------
//  -------  Adaptives Quadratur-Verfahren (Simpson) ----------------
//  -------                                          ----------------
//  -------  2005 Januar 28     Manfred Vogel        ----------------
//  -----------------------------------------------------------------

class AdaptiveQuadraturSimpson {

	static final double  Pi = 3.1415926535;
	
	// Integrationsintervall [a, b]
	static final double a = 0.0;
	static final double b = 10.0;
	
	// # Teilintervalle für die Auswertung des (Teil-)Integrals mit der zusammengesetzten Simpson-Regel
	static final int n = 10;

	// definiert die zu integrierende Funktion f
	static double f(double x)
	{
		if( x==0.0) return 0.0;
		return Math.sin(x*x*x) * Math.exp(-x/Math.exp(1.0));
		// return 0.0;
	}

	// implementiert die zusammengesetzte Simpson'sche Regel
	static double simpson(double a, double b)
	{
		double h = (b-a)/n;
		double sum1=0.0, sum2=0.0;
		for (int i=1; i<=(n/2)-1; i++)
		{
			sum1 += f(a + 2*h*i);
		}
		for (int j=1; j<=n/2; j++)
		{
			sum2 += f(a + h*(2*j-1));
		}
		return h/3 * ( f(a) + f(b) + 2*sum1 + 4*sum2 );
		//return 0.0;	
	}
	
	static double rek(double a, double b, double eps)
	{
		double intTot=0.0, intLeft=0.0, intRight=0.0;
		intTot   = simpson( a      , b      );
		intLeft  = simpson( a      , (a+b)/2);
		intRight = simpson( (a+b)/2, b      );
		if( Math.abs( intTot - intLeft - intRight ) > eps )
		{       
		        return rek(a, (a+b)/2, eps/2.0) + rek((a+b)/2, b, eps/2.0);
		}
		else
		{
		        return intLeft + intRight;	
		}
	}               

	public static void main(String[] args)
	{
		double integral = rek(a, b, 0.00000001);
		
		System.out.println("\n\n");
		System.out.println(" ** Adaptive Quadratur mit Simpson-Verfahren ** " + "\n");
		System.out.print  ("    Integral( f(x), x=a..b ) = " + integral);
		System.out.println("\n\n");
	}
}