public static double ForwardStart(string cpflg, double S0, double t1, double t2, double r, double b, double vol, double a) { double return_value = double.NaN; return_value = DoubleExponentialTransformation.Integrate((y) => { return(Normal.PDF(0, 1, y) * BlackScholesMethod.BlackScholes(cpflg, S0 * Math.Exp((b - 0.5 * vol * vol) * t1 + y * vol * Math.Sqrt(t1)), Math.Max(S0 * Math.Exp((b - 0.5 * vol * vol) * t1 + y * vol * Math.Sqrt(t1)) + a, 0), t2 - t1, r, b, vol)); }, -200, 200, 1e-4); return(return_value); }
/// <summary> /// Approximation of the definite integral of an analytic smooth complex function by double-exponential quadrature. When either or both limits are infinite, the integrand is assumed rapidly decayed to zero as x -> infinity. /// </summary> /// <param name="f">The analytic smooth complex function to integrate, defined on the real domain.</param> /// <param name="intervalBegin">Where the interval starts.</param> /// <param name="intervalEnd">Where the interval stops.</param> /// <param name="targetAbsoluteError">The expected relative accuracy of the approximation.</param> /// <returns>Approximation of the finite integral in the given interval.</returns> public static Complex DoubleExponential(Func <double, Complex> f, double intervalBegin, double intervalEnd, double targetAbsoluteError = 1E-8) { // Reference: // Formula used for variable subsitution from // 1. Shampine, L. F. (2008). Vectorized adaptive quadrature in MATLAB. Journal of Computational and Applied Mathematics, 211(2), 131-140. // 2. quadgk.m, GNU Octave if (intervalBegin > intervalEnd) { return(-DoubleExponential(f, intervalEnd, intervalBegin, targetAbsoluteError)); } // (-oo, oo) => [-1, 1] // // integral_(-oo)^(oo) f(x) dx = integral_(-1)^(1) f(g(t)) g'(t) dt // g(t) = t / (1 - t^2) // g'(t) = (1 + t^2) / (1 - t^2)^2 if (double.IsInfinity(intervalBegin) && double.IsInfinity(intervalEnd)) { Func <double, Complex> u = (t) => { return(f(t / (1 - t * t)) * (1 + t * t) / ((1 - t * t) * (1 - t * t))); }; return(DoubleExponentialTransformation.ContourIntegrate(u, -1, 1, targetAbsoluteError)); } // [a, oo) => [0, 1] // // integral_(a)^(oo) f(x) dx = integral_(0)^(oo) f(a + t^2) 2 t dt // = integral_(0)^(1) f(a + g(s)^2) 2 g(s) g'(s) ds // g(s) = s / (1 - s) // g'(s) = 1 / (1 - s)^2 else if (double.IsInfinity(intervalEnd)) { Func <double, Complex> u = (s) => { return(2 * s * f(intervalBegin + (s / (1 - s)) * (s / (1 - s))) / ((1 - s) * (1 - s) * (1 - s))); }; return(DoubleExponentialTransformation.ContourIntegrate(u, 0, 1, targetAbsoluteError)); } // (-oo, b] => [-1, 0] // // integral_(-oo)^(b) f(x) dx = -integral_(-oo)^(0) f(b - t^2) 2 t dt // = -integral_(-1)^(0) f(b - g(s)^2) 2 g(s) g'(s) ds // g(s) = s / (1 + s) // g'(s) = 1 / (1 + s)^2 else if (double.IsInfinity(intervalBegin)) { Func <double, Complex> u = (s) => { return(-2 * s * f(intervalEnd - s / (1 + s) * (s / (1 + s))) / ((1 + s) * (1 + s) * (1 + s))); }; return(DoubleExponentialTransformation.ContourIntegrate(u, -1, 0, targetAbsoluteError)); } else { return(DoubleExponentialTransformation.ContourIntegrate(f, intervalBegin, intervalEnd, targetAbsoluteError)); } }
public void TestDoubleExponentialTransformationAlgorithm(double targetRelativeError) { Assert.AreEqual( TargetAreaA, DoubleExponentialTransformation.Integrate(TargetFunctionA, StartA, StopA, targetRelativeError), targetRelativeError * TargetAreaA, "DET Adaptive {0}", targetRelativeError); }
public void TestDoubleExponentialTransformationAlgorithm(double targetRelativeError) { var algorithm = new DoubleExponentialTransformation(); Assert.AreApproximatelyEqual( TargetAreaA, algorithm.Integrate(TargetFunctionA, StartA, StopA, targetRelativeError), targetRelativeError * TargetAreaA, "DET Adaptive {0}", targetRelativeError); }
private static void Integrate() { // perform a one-dimensional numerical integration const double x0 = 0.0; const double x1 = 1.0; const double eps = 1e-6; double integral = 2 / Constants.SqrtPi * DoubleExponentialTransformation.Integrate(x => Math.Exp(-x * x), x0, x1, eps); double exact = SpecialFunctions.Erf(x1); Console.WriteLine($"erf({x1}) = {exact}"); Console.WriteLine($"erf({x1}) = {integral} (num approx.)"); }
public void TestDoubleExponentialTransformationAlgorithm() { DoubleExponentialTransformation det = new DoubleExponentialTransformation(); Assert.That( det.Integrate(TargetFunctionA, StartA, StopA, 1e-5), NumericIs.AlmostEqualTo(TargetAreaA, 1e-5), "Adaptive Target 1e-5"); Assert.That( det.Integrate(TargetFunctionA, StartA, StopA, 1e-10), NumericIs.AlmostEqualTo(TargetAreaA, 1e-10), "Adaptive Target 1e-10"); }
public void FindClassificationErrorFullPossibility() { double step = 0.00001; Class1ErrorAssignmentChance = 0; Class1ErrorNotAssignedChance = 0; DoubleRange range1 = NormalDistributionClass1.GetRange(0.99); DoubleRange range2 = NormalDistributionClass2.GetRange(0.99); double begin = range2.Min; double end = FindDistributionEqualityPoint(); double f1(double x) => Chance2 / Math.Sqrt(Variance2 * 2 * Math.PI) * Math.Exp(Math.Pow((x - Mean2), 2) / (-2 * Variance2)); Class1ErrorAssignmentChance = DoubleExponentialTransformation.Integrate(f1, begin, end, 1e-5); begin = end; end = range1.Max; double f2(double x) => Chance1 / Math.Sqrt(Variance1 * 2 * Math.PI) * Math.Exp(Math.Pow((x - Mean1), 2) / (-2 * Variance1)); Class1ErrorNotAssignedChance = DoubleExponentialTransformation.Integrate(f2, begin, end, 1e-5); //double x = Math.Min(range1.Min, range2.Min); //double max = Math.Max(range2.Max, range1.Max); //bool equalityPointPassed = false; //while (x < max) //{ // double dens1 = NormalDistributionClass1.ProbabilityDensityFunction(x); // double dens2 = NormalDistributionClass2.ProbabilityDensityFunction(x); // if (!equalityPointPassed) // Class1ErrorAssignmentChance += dens2 * chance2; // else // Class1ErrorNotAssignedChance += dens1 * chance1; // if (Math.Abs(dens1 - dens2) < 0.00003) // equalityPointPassed = true; // x += step; //} }
/// <summary> /// Approximation of the definite integral of an analytic smooth function on a closed interval. /// </summary> /// <param name="f">The analytic smooth function to integrate.</param> /// <param name="intervalBegin">Where the interval starts, inclusive and finite.</param> /// <param name="intervalEnd">Where the interval stops, inclusive and finite.</param> /// <returns>Approximation of the finite integral in the given interval.</returns> public static double OnClosedInterval(Func <double, double> f, double intervalBegin, double intervalEnd) { return(DoubleExponentialTransformation.Integrate(f, intervalBegin, intervalEnd, 1e-8)); }
/// <summary> /// Approximation of the definite integral of an analytic smooth function on a closed interval. /// </summary> /// <param name="f">The analytic smooth function to integrate.</param> /// <param name="intervalBegin">Where the interval starts, inclusive and finite.</param> /// <param name="intervalEnd">Where the interval stops, inclusive and finite.</param> /// <param name="targetAbsoluteError">The expected relative accuracy of the approximation.</param> /// <returns>Approximation of the finite integral in the given interval.</returns> public static double OnClosedInterval(Func <double, double> f, double intervalBegin, double intervalEnd, double targetAbsoluteError) { return(DoubleExponentialTransformation.Integrate(f, intervalBegin, intervalEnd, targetAbsoluteError)); }
private double Trigamma(double z) { Func <double, double> func = x => Math.Pow(x, z - 1) * Math.Log(x) / (1 - x); return(-DoubleExponentialTransformation.Integrate(func, 0, 1, 1E-5)); }