package net.finmath.finitedifference.models;

import java.util.function.DoubleUnaryOperator;

import net.finmath.finitedifference.solvers.FDMThetaMethod;

/**
 * Black Scholes model using finite difference method.
 *
 * @author Ralph Rudd
 * @author Christian Fries
 * @author Jörg Kienitz
 * @version 1.0
 */
public class FDMBlackScholesModel implements FiniteDifference1DModel {
	private final double initialValue;
	private final double riskFreeRate;
	private final double volatility;

	/*
	 * Solver properties - will be moved to solver.
	 */
	private final int numTimesteps;
	private final int numSpacesteps;
	private final int numStandardDeviations;
	private final double center;
	private final double theta;

	public FDMBlackScholesModel(
			int numTimesteps,
			int numSpacesteps,
			int numStandardDeviations,
			double center,
			double theta,
			double initialValue,
			double riskFreeRate,
			double volatility) {
		this.initialValue = initialValue;
		this.riskFreeRate = riskFreeRate;
		this.volatility = volatility;

		this.numTimesteps = numTimesteps;
		this.numSpacesteps = numSpacesteps;
		this.numStandardDeviations = numStandardDeviations;
		this.center = center;
		this.theta = theta;
	}

	/* (non-Javadoc)
	 * @see net.finmath.finitedifference.models.FiniteDifference1DModel#varianceOfStockPrice(double)
	 */
	@Override
	public double varianceOfStockPrice(double time) {
		return Math.pow(initialValue, 2) * Math.exp(2 * riskFreeRate * time)
				* (Math.exp(Math.pow(volatility, 2) * time) - 1);
	}

	/* (non-Javadoc)
	 * @see net.finmath.finitedifference.models.FiniteDifference1DModel#getForwardValue(double)
	 */
	@Override
	public double getForwardValue(double time) {
		return initialValue * Math.exp(riskFreeRate * time);
	}

	/* (non-Javadoc)
	 * @see net.finmath.finitedifference.models.FiniteDifference1DModel#getRiskFreeRate()
	 */
	@Override
	public double getRiskFreeRate() {
		return riskFreeRate;
	}

	public double getInitialValue() {
		return initialValue;
	}

	@Override
	public double getVolatility() {
		return volatility;
	}

	@Override
	public double getLocalVolatility(double assetValue, double time) { return volatility; }

	@Override
	public int getNumTimesteps() {
		return numTimesteps;
	}

	@Override
	public int getNumSpacesteps() {
		return numSpacesteps;
	}

	@Override
	public double getNumStandardDeviations() {
		return numStandardDeviations;
	}

	/* (non-Javadoc)
	 * @see net.finmath.finitedifference.models.FiniteDifference1DModel#valueOptionWithThetaMethod(net.finmath.finitedifference.products.FDMEuropeanCallOption, double)
	 */
	@Override
	public double[][] getValue(double evaluationTime, double time, DoubleUnaryOperator values, FiniteDifference1DBoundary boundary) {
		final FDMThetaMethod solver = new FDMThetaMethod(this, boundary, time, center, theta);
		return solver.getValue(evaluationTime, time, values);
	}

}

@@ -737,24 +737,30 @@
 esModel(%0A%09%09%09
+final 
 int numTimes
@@ -760,32 +760,38 @@
 umTimesteps,%0A%09%09%09
+final 
 int numSpacestep
@@ -796,16 +796,22 @@
 eps,%0A%09%09%09
+final 
 int numS
@@ -828,24 +828,30 @@
 iations,%0A%09%09%09
+final 
 double cente
@@ -852,24 +852,30 @@
  center,%0A%09%09%09
+final 
 double theta
@@ -875,24 +875,30 @@
 e theta,%0A%09%09%09
+final 
 double initi
@@ -905,24 +905,30 @@
 alValue,%0A%09%09%09
+final 
 double riskF
@@ -939,16 +939,22 @@
 ate,%0A%09%09%09
+final 
 double v
@@ -1253,129 +1253,8 @@
 %09%7D%0A%0A
-%09/* (non-Javadoc)%0A%09 * @see net.finmath.finitedifference.models.FiniteDifference1DModel#varianceOfStockPrice(double)%0A%09 */%0A
 %09@Ov
@@ -1296,16 +1296,22 @@
 ckPrice(
+final 
 double t
@@ -1450,124 +1450,8 @@
 %09%7D%0A%0A
-%09/* (non-Javadoc)%0A%09 * @see net.finmath.finitedifference.models.FiniteDifference1DModel#getForwardValue(double)%0A%09 */%0A
 %09@Ov
@@ -1484,24 +1484,30 @@
 orwardValue(
+final 
 double time)
@@ -1572,118 +1572,8 @@
 %09%7D%0A%0A
-%09/* (non-Javadoc)%0A%09 * @see net.finmath.finitedifference.models.FiniteDifference1DModel#getRiskFreeRate()%0A%09 */%0A
 %09@Ov
@@ -1850,17 +1850,19 @@
  time) %7B
- 
+%0A%09%09
 return v
@@ -1871,17 +1871,18 @@
 atility;
- 
+%0A%09
 %7D%0A%0A%09@Ove
@@ -2113,196 +2113,8 @@
 %09%7D%0A%0A
-%09/* (non-Javadoc)%0A%09 * @see net.finmath.finitedifference.models.FiniteDifference1DModel#valueOptionWithThetaMethod(net.finmath.finitedifference.products.FDMEuropeanCallOption, double)%0A%09 */%0A
 %09@Ov
@@ -2148,16 +2148,22 @@
 etValue(
+final 
 double e
@@ -2171,21 +2171,28 @@
 aluation
+n
 Time,
+ final
  double 
@@ -2196,16 +2196,22 @@
 le time,
+ final
  DoubleU
@@ -2230,16 +2230,22 @@
  values,
+ final
  FiniteD
@@ -2400,16 +2400,17 @@
 aluation
+n
 Time, ti

Clean up.