// ================================================================
// John Kerl
// kerl.john.r@gmail.com
// 2010-02-18
// ================================================================

import java.util.Random;
import java.lang.Math;

public class BrownianBridge {

	// Rescale a Brownian motion B_t which runs from 0 to T to obtain a
	// bridge process X_t = X_0 + B_t + t/T * (X_T - X_0 - B_T).
	public static void getSeriesFromBM(
		double B[],
		double X[],
		double X0,
		double XT,
		int    nt,
		double dt,
		Random RNG)
	{
		double BT = B[nt-1];
		double T = nt * dt;
		double t;
		int    i;
		double height = XT - X0 - BT;

		for (i = 0, t = 0; i < nt; i++, t+=dt)
			X[i] = X0 + B[i] + t/T * height;
	}

	// SDE: dY_t = (B - Y_t)/(T - t) dt + db_t
	public static void getSeries(
		double X[],
		double X0,
		double XT,
		int    nt,
		double dt,
		Random RNG)
	{
		double sqrtdt = Math.sqrt(dt);
		double T      = nt * dt;
		double t      = 0.0;
		double Bt     = 0.0;
		double dB;

		X[0] = X0;
		for (int i = 1; i < nt; i++) {
			dB = sqrtdt * RNG.nextGaussian();
			X[i] = X[i-1] + (XT - X[i-1]) / (T - t) * dt + dB;
			Bt += dB;
			t  += dt;
		}
	}
}
