/// <summary> /// Creates an instance. /// <para> /// If the size of the domain is very small or very large, consider re-scaling first. /// If this value is too small, the result will most likely be dominated by noise. /// Use around 10<sup>-5</sup> times the domain size. /// /// </para> /// </summary> /// <param name="differenceType"> the differencing type to be used in calculating the gradient function </param> /// <param name="eps"> the step size used to approximate the derivative </param> public VectorFieldFirstOrderDifferentiator(FiniteDifferenceType differenceType, double eps) { ArgChecker.notNull(differenceType, "differenceType"); this.differenceType = differenceType; this.eps = eps; this.twoEps = 2 * eps; }
/// <summary> /// Creates an instance that approximates the derivative of a scalar function by finite difference. /// <para> /// If the size of the domain is very small or very large, consider re-scaling first. /// If this value is too small, the result will most likely be dominated by noise. /// Use around 10<sup>-5</sup> times the domain size. /// /// </para> /// </summary> /// <param name="differenceType"> the type, forward, backward or central. In most situations, central is best </param> /// <param name="eps"> the step size used to approximate the derivative </param> public ScalarFieldFirstOrderDifferentiator(FiniteDifferenceType differenceType, double eps) { ArgChecker.notNull(differenceType, "differenceType"); ArgChecker.isTrue(eps >= MIN_EPS, "eps of {} is too small. Please choose a value > {}, such as 1e-5*size of domain", eps, MIN_EPS); this.differenceType = differenceType; this.eps = eps; this.twoEps = 2 * eps; }
/// <summary> /// Creates an instance using the default value of eps (10<sup>-5</sup>). /// </summary> /// <param name="differenceType"> the differencing type to be used in calculating the gradient function </param> public VectorFieldFirstOrderDifferentiator(FiniteDifferenceType differenceType) : this(differenceType, DEFAULT_EPS) { }
//------------------------------------------------------------------------- /// <summary> /// Create an instance of the finite difference calculator. /// </summary> /// <param name="fdType"> the finite difference type </param> /// <param name="shift"> the shift to be applied to the curves </param> private CurveGammaCalculator(FiniteDifferenceType fdType, double shift) { this.fd = new VectorFieldFirstOrderDifferentiator(fdType, shift); }
/// <summary> /// Creates an instance using the default value of eps (10<sup>-5</sup>). /// </summary> /// <param name="differenceType"> the differencing type to be used in calculating the gradient function </param> public ScalarFirstOrderDifferentiator(FiniteDifferenceType differenceType) : this(differenceType, DEFAULT_EPS) { }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @SuppressWarnings("null") private double fdSensitivity(com.opengamma.strata.pricer.impl.option.EuropeanVanillaOption optionData, double forward, SabrFormulaData sabrData, SabrParameter param, double delta) private double fdSensitivity(EuropeanVanillaOption optionData, double forward, SabrFormulaData sabrData, SabrParameter param, double delta) { System.Func <SabrFormulaData, double> funcC = null; System.Func <SabrFormulaData, double> funcB = null; System.Func <SabrFormulaData, double> funcA = null; SabrFormulaData dataC = null; SabrFormulaData dataB = sabrData; SabrFormulaData dataA = null; System.Func <SabrFormulaData, double> func = getVolatilityFunction(optionData, forward); FiniteDifferenceType fdType = null; switch (param) { case com.opengamma.strata.pricer.impl.volatility.smile.SabrHaganVolatilityFunctionProviderTest.SabrParameter.Strike: double strike = optionData.Strike; if (strike >= delta) { fdType = FiniteDifferenceType.CENTRAL; funcA = getVolatilityFunction(withStrike(optionData, strike - delta), forward); funcC = getVolatilityFunction(withStrike(optionData, strike + delta), forward); } else { fdType = FiniteDifferenceType.FORWARD; funcA = func; funcB = getVolatilityFunction(withStrike(optionData, strike + delta), forward); funcC = getVolatilityFunction(withStrike(optionData, strike + 2 * delta), forward); } dataC = sabrData; dataB = sabrData; dataA = sabrData; break; case com.opengamma.strata.pricer.impl.volatility.smile.SabrHaganVolatilityFunctionProviderTest.SabrParameter.Forward: if (forward > delta) { fdType = FiniteDifferenceType.CENTRAL; funcA = getVolatilityFunction(optionData, forward - delta); funcC = getVolatilityFunction(optionData, forward + delta); } else { fdType = FiniteDifferenceType.FORWARD; funcA = func; funcB = getVolatilityFunction(optionData, forward + delta); funcC = getVolatilityFunction(optionData, forward + 2 * delta); } dataC = sabrData; dataB = sabrData; dataA = sabrData; break; case com.opengamma.strata.pricer.impl.volatility.smile.SabrHaganVolatilityFunctionProviderTest.SabrParameter.Alpha: double a = sabrData.Alpha; if (a >= delta) { fdType = FiniteDifferenceType.CENTRAL; dataA = sabrData.withAlpha(a - delta); dataC = sabrData.withAlpha(a + delta); } else { fdType = FiniteDifferenceType.FORWARD; dataA = sabrData; dataB = sabrData.withAlpha(a + delta); dataC = sabrData.withAlpha(a + 2 * delta); } funcC = func; funcB = func; funcA = func; break; case com.opengamma.strata.pricer.impl.volatility.smile.SabrHaganVolatilityFunctionProviderTest.SabrParameter.Beta: double b = sabrData.Beta; if (b >= delta) { fdType = FiniteDifferenceType.CENTRAL; dataA = sabrData.withBeta(b - delta); dataC = sabrData.withBeta(b + delta); } else { fdType = FiniteDifferenceType.FORWARD; dataA = sabrData; dataB = sabrData.withBeta(b + delta); dataC = sabrData.withBeta(b + 2 * delta); } funcC = func; funcB = func; funcA = func; break; case com.opengamma.strata.pricer.impl.volatility.smile.SabrHaganVolatilityFunctionProviderTest.SabrParameter.Nu: double n = sabrData.Nu; if (n >= delta) { fdType = FiniteDifferenceType.CENTRAL; dataA = sabrData.withNu(n - delta); dataC = sabrData.withNu(n + delta); } else { fdType = FiniteDifferenceType.FORWARD; dataA = sabrData; dataB = sabrData.withNu(n + delta); dataC = sabrData.withNu(n + 2 * delta); } funcC = func; funcB = func; funcA = func; break; case com.opengamma.strata.pricer.impl.volatility.smile.SabrHaganVolatilityFunctionProviderTest.SabrParameter.Rho: double r = sabrData.Rho; if ((r + 1) < delta) { fdType = FiniteDifferenceType.FORWARD; dataA = sabrData; dataB = sabrData.withRho(r + delta); dataC = sabrData.withRho(r + 2 * delta); } else if ((1 - r) < delta) { fdType = FiniteDifferenceType.BACKWARD; dataA = sabrData.withRho(r - 2 * delta); dataB = sabrData.withRho(r - delta); dataC = sabrData; } else { fdType = FiniteDifferenceType.CENTRAL; dataC = sabrData.withRho(r + delta); dataA = sabrData.withRho(r - delta); } funcC = func; funcB = func; funcA = func; break; default: throw new MathException("enum not found"); } if (fdType != null) { switch (fdType) { case FiniteDifferenceType.FORWARD: return((-1.5 * funcA(dataA) + 2.0 * funcB(dataB) - 0.5 * funcC(dataC)) / delta); case FiniteDifferenceType.BACKWARD: return((0.5 * funcA(dataA) - 2.0 * funcB(dataB) + 1.5 * funcC(dataC)) / delta); case FiniteDifferenceType.CENTRAL: return((funcC(dataC) - funcA(dataA)) / 2.0 / delta); default: throw new MathException("enum not found"); } } throw new MathException("enum not found"); }