package vorlesungen;

import java.util.Random;

public class Wiener 
{

Random r = null;

public Wiener()
{
	r = new Random(System.currentTimeMillis());	
}

public double[] approxWiener(int n, double[] ts)
{
	double[] result = new double[ts.length];
	
	// Realize random variables Z_n
	double[] zs = new double[(int)Math.floor(getMax(ts)*n)+1];
	for(int i=0; i<zs.length; i++)
	{
		zs[i] = (r.nextDouble()<0.5)?(-1.0):(1.0);
	}
	
	// Find X_t^(n):
	for(int i=0; i<ts.length; i++)
	{
		double nt = ts[i]*n;
		int nt_floor = (int) Math.floor(nt);
		
		result[i]=0;
		for(int j=1; j<=nt_floor; j++)
		{
				result[i] += zs[j-1];
		}
		result[i] = result[i] / Math.sqrt(n);
		
		result[i] += (nt - nt_floor) * zs[nt_floor] / Math.sqrt(n);
	}
	
	return result;
	
}

// Find the mean of a sample
public static double getMean(double[] sample)
{
	double sum = 0;
	if(sample.length>0)
	{
		for(int i=0; i<sample.length; i++)
		{
		  sum += sample[i];
		}
		return(sum/sample.length);
	}
	else
	{
		return 0;
	}
}

// Find the sample variance of a sample
public static double getVar(double[] sample)
{
	double var = 0;
	if(sample.length>1)
	{
		double mean = getMean(sample);
		for(int i=0; i<sample.length; i++)
		{
			var += (sample[i]-mean)*(sample[i]-mean);
		}
		
		var = var / (sample.length - 1);
		return var;
	}
	else
	{
		return 0;
	}
}

// Find the maximum of a sample
public static double getMax(double[] sample)
{
	double max = Double.NEGATIVE_INFINITY;
	
	for(int i=0; i<sample.length; i++)
	{
		if(sample[i]>max)
		{
			max = sample[i];
		}
	}
	
	return max;
}


/**
 *   Hauptprogramm:
 *   Simulation eines Wiener Prozesses
 */
    public static void main(String[] args) 
    {
    	int sampleSize=1000;
    	int order = 1000;
    	int n_stuetz = 1000;
    	double[] sample = new double[sampleSize];
    	
    	// Stuetzstellen bestimmen.
    	double[] stuetzstellen = new double[n_stuetz+1];
    	for(int i=0; i<=n_stuetz; i++)
    	{
    		stuetzstellen[i]=((double)i)/ ((double)n_stuetz);
    		//System.out.println(stuetzstellen[i]);
    	}
    	
    	Wiener w = new Wiener();
    	for(int i=0; i < sample.length; i++)
    	{
    		double[] values = w.approxWiener(order, stuetzstellen);
    		sample[i] = getMax(values);
    	}
    	
    	/* Bestimme Mittelwert und Stichprobenvarianz der Maxima-Approximationen */
    	double mean = getMean(sample); 
    	double var = getVar(sample);
    	System.out.println("Mittelwert: "+mean+"\n");
    	System.out.println("StichprobenVarianz: "+var+"\n");
	 }
}

//Mittelwert: 0.7942376571278901
//StichprobenVarianz: 0.35767021421421363

