public void CallNaiveImplemXCheck() { var maturities = GridUtils.RegularGrid(0.1, 5.0, 100); var vols = GridUtils.RegularGrid(0.01, 1.0, 10); var volMoneynesses = GridUtils.RegularGrid(-3, 3, 100); foreach (var mat in maturities) { foreach (var vol in vols) { var sigma = Math.Sqrt(mat) * vol; foreach (var vm in volMoneynesses) { var strike = Math.Exp(vm * sigma); var call = BlackScholesOption.Price(1.0, strike, vol, mat, 1); //Naive implementation of black-scholes formulae var d_plus = -(vm * sigma) / sigma + 0.5 * sigma; var d_minus = d_plus - sigma; var call_xcheck = NormalDistribution.Cumulative(d_plus) - strike * NormalDistribution.Cumulative(d_minus); if (DoubleUtils.EqualZero(call)) { Assert.IsTrue(DoubleUtils.EqualZero(call_xcheck)); } else { var errRelative = (call - call_xcheck) / call_xcheck; Assert.IsTrue(Math.Abs(errRelative) < 1.0e-11); } } } } }
public static DiscountCurve LinearRateInterpol(FinancingId financing, DateTime[] pillars, double[] zcs, ITimeMeasure time) { if (pillars.Length != zcs.Length) throw new Exception("LinearRateDiscountProvider : Incompatible size"); var dates = time[pillars]; var zcRates = new double[pillars.Length]; if (DoubleUtils.EqualZero(dates[0])) { if (!DoubleUtils.MachineEquality(1.0, zcs[0])) throw new Exception("LinearRateInterpol : Discount for refDate must equal to 1.0 "); zcRates[0] = 0.0; } else { zcRates[0] = -Math.Log(zcs[0]) / dates[0]; } for (int i = 1; i < zcs.Length; i++) { zcRates[i] = -Math.Log(zcs[i]) / dates[i]; } return new DiscountCurveFromRate(financing, time, RrFunctions.LinearInterpolation(dates, zcRates)); }
public void CallNaiveImplemXCheck() { var maturities = GridUtils.RegularGrid(0.1, 5.0, 100); var vols = GridUtils.RegularGrid(0.001, 0.015, 10); var volMoneynesses = GridUtils.RegularGrid(-3, 3, 100); foreach (var mat in maturities) { foreach (var vol in vols) { var sigma = Math.Sqrt(mat) * vol; foreach (var vm in volMoneynesses) { var strike = vm * sigma; var call = BachelierOption.Price(0.0, strike, vol, mat, 1); //Naive implementation of bachelier formulae var d = strike / sigma; var call_xcheck = -strike *NormalDistribution.Cumulative(-d) + sigma * NormalDistribution.Density(d); if (DoubleUtils.EqualZero(call)) { Assert.IsTrue(DoubleUtils.EqualZero(call_xcheck)); } else { var errRelative = (call - call_xcheck) / call_xcheck; Assert.IsTrue(Math.Abs(errRelative) < 1.0e-13); } } } } }
public static RrFunction Affine(double slope, double origin) { if (DoubleUtils.EqualZero(slope)) { return(Constant(origin)); } return(Constant(slope).Integral(-origin / slope)); }
public void TestEqualZero() { Assert.IsTrue(DoubleUtils.EqualZero(0.0)); Assert.IsFalse(DoubleUtils.EqualZero(1.0)); Assert.IsFalse(DoubleUtils.EqualZero(1.0e-28)); Assert.IsFalse(DoubleUtils.EqualZero(double.Epsilon)); Assert.IsTrue(DoubleUtils.EqualZero(0.5 * double.Epsilon)); }
public static RrFunction Constant(double value) { if (DoubleUtils.EqualZero(value)) { return(Zero); } return(new ConstantRrFunction(value)); }
public override string ToString() { var firstNonZeroCoeff = new List <double>(Coeffs).FindIndex(x => !DoubleUtils.EqualZero(x)); string desc = ""; bool initialized = false; //Display constant part if (firstNonZeroCoeff == 0) { desc += Coeffs[0].ToString(CultureInfo.InvariantCulture); initialized = true; } //Display degree one part if (firstNonZeroCoeff <= 1 && Coeffs.Length > 1) { if (initialized) { desc += " + "; } if (DoubleUtils.MachineEquality(Coeffs[1], 1.0)) { desc += "X"; } else { desc += string.Format("{0} * X", Coeffs[1]); } initialized = true; } //Display higher degrees for (int i = 2; i < Coeffs.Length; i++) { if (!DoubleUtils.EqualZero(Coeffs[i])) { if (initialized) { desc += " + "; } if (DoubleUtils.MachineEquality(Coeffs[i], 1.0)) { desc += string.Format("X^{0}", i); } else { desc += string.Format("{0} * X^{1}", Coeffs[i], i); } initialized = true; } } return(desc); }
public override RrFunction Integral(double basePoint) { if (DoubleUtils.EqualZero(slope)) { return(RrFunctions.Constant(weight).Integral(basePoint)); } var zeroBaseIntegral = Create(weight / slope, slope); return(zeroBaseIntegral - zeroBaseIntegral.Eval(basePoint)); }
public static RrFunction Add(StepFunction step, ConstantRrFunction cst) { if (DoubleUtils.EqualZero(cst.Value)) { return(step); } var shiftedValues = step.values.Map(v => v + cst.Value); return(new StepFunction(step.abscissae, shiftedValues, step.leftValue + cst.Value)); }
public void CheckSymmetry() { var rand = new Random(1468); for (int i = 0; i < 10000; i++) { var x = rand.NextDouble() * 30.0; // random in [0, 30] var norm_x = NormalDistribution.Cumulative(x); var norm_minusx = NormalDistribution.Cumulative(-x); var err = Math.Abs((norm_x + norm_minusx) - 1.0); Assert.IsTrue(DoubleUtils.EqualZero(err)); } }
public static RrFunction Mult(LinearCombinationRrFunction lc, ConstantRrFunction cst) { if (DoubleUtils.MachineEquality(1.0, cst.Value)) { return(lc); } if (DoubleUtils.EqualZero(cst.Value)) { return(RrFunctions.Zero); } return(LinearCombinationRrFunction.Create(lc.Weights.Map(w => w * cst.Value), lc.Functions)); }
public static RrFunction Create(double weight, double slope) { if (DoubleUtils.EqualZero(weight)) { return(RrFunctions.Zero); } if (DoubleUtils.EqualZero(slope)) { return(RrFunctions.Constant(weight)); } return(new ExpRrFunction(weight, slope)); }
public override RnRFunction Mult(RnRFunction right) { var cst = right as ConstantRnRFunction; if (cst != null) { if (DoubleUtils.EqualZero(cst.Value)) { return(RnRFunctions.Constant(0.0, cst.Dim)); } return(new ExpAffineRnRFunction(cst.Value * add, mults.Map(m => m * cst.Value))); } return(base.Mult(right)); }
public static RrFunction Mult(StepFunction step, ConstantRrFunction cst) { if (DoubleUtils.MachineEquality(cst.Value, 1.0)) { return(step); } if (DoubleUtils.EqualZero(cst.Value)) { return(RrFunctions.Zero); } var multValues = step.values.Map(v => v * cst.Value); return(new StepFunction(step.abscissae, multValues, step.leftValue * cst.Value)); }
public static double rational_cubic_control_parameter_to_fit_second_derivative_at_right_side(double x_l, double x_r, double y_l, double y_r, double d_l, double d_r, double second_derivative_r) { double h = (x_r - x_l), numerator = 0.5 * h * second_derivative_r + (d_r - d_l); if ((DoubleUtils.EqualZero(numerator))) { return(0); } double denominator = d_r - (y_r - y_l) / h; if ((DoubleUtils.EqualZero(denominator))) { return(numerator > 0 ? MaximumRationalCubicControlParameterValue : MinimumRationalCubicControlParameterValue); } return(numerator / denominator); }
public static double minimum_rational_cubic_control_parameter(double d_l, double d_r, double s, bool preferShapePreservationOverSmoothness) { bool monotonic = d_l * s >= 0 && d_r * s >= 0, convex = d_l <= s && s <= d_r, concave = d_l >= s && s >= d_r; if (!monotonic && !convex && !concave) // If 3==r_non_shape_preserving_target, this means revert to standard cubic. { return(MinimumRationalCubicControlParameterValue); } double d_r_m_d_l = d_r - d_l, d_r_m_s = d_r - s, s_m_d_l = s - d_l; double r1 = -double.MaxValue, r2 = r1; // If monotonicity on this interval is possible, set r1 to satisfy the monotonicity condition (3.8). if (monotonic) { if (!DoubleUtils.EqualZero(s)) // (3.8), avoiding division by zero. { r1 = (d_r + d_l) / s; // (3.8) } else if (preferShapePreservationOverSmoothness) { // If division by zero would occur, and shape preservation is preferred, set value to enforce linear interpolation. r1 = MaximumRationalCubicControlParameterValue; // This value enforces linear interpolation. } } if (convex || concave) { if (!(DoubleUtils.EqualZero(s_m_d_l) || DoubleUtils.EqualZero(d_r_m_s))) // (3.18), avoiding division by zero. { r2 = Math.Max(Math.Abs(d_r_m_d_l / d_r_m_s), Math.Abs(d_r_m_d_l / s_m_d_l)); } else if (preferShapePreservationOverSmoothness) { r2 = MaximumRationalCubicControlParameterValue; // This value enforces linear interpolation. } } else if (preferShapePreservationOverSmoothness) { r2 = MaximumRationalCubicControlParameterValue; } // This enforces linear interpolation along segments that are inconsistent with the slopes on the boundaries, e.g., a perfectly horizontal segment that has negative slopes on either edge. return(Math.Max(MinimumRationalCubicControlParameterValue, Math.Max(r1, r2))); }
private static RrFunction BuildXi(MapRawDatas <DateOrDuration, double> sigma, ITimeMeasure time) { var matVars = EnumerableUtils.For(0, sigma.Pillars.Length, i => { var mat = time[sigma.Pillars[i].ToDate(time.RefDate)]; var variance = sigma.Values[i] * sigma.Values[i] * mat; return(new { Mat = mat, Variance = variance }); }).OrderBy(t => t.Mat).ToArray(); if (!DoubleUtils.EqualZero(matVars.First().Mat)) { matVars = matVars.Concat(new[] { new { Mat = 0.0, Variance = 0.0 } }) .OrderBy(t => t.Mat).ToArray(); } var varianceFunc = RrFunctions.LinearInterpolation(matVars.Map(t => t.Mat), matVars.Map(t => t.Variance), 0.0, double.NaN); return(varianceFunc.Derivative()); }
public Polynomial(bool simplify, params double[] coeffs) { Contract.Requires(coeffs.Length > 0); if (simplify) { int degree = coeffs.Length - 1; while (degree > 0) { if (!DoubleUtils.EqualZero(coeffs[degree])) { break; } --degree; } Coeffs = new double[degree + 1]; Array.Copy(coeffs, Coeffs, Coeffs.Length); } else { Coeffs = coeffs; } }
/// <summary> /// Brenth algorithm from scipy /// </summary> public static double Brenth(Func <double, double> f, double xa, double fa, double xb, double fb, double xtol, double rtol, int maxIter, out int funcalls, out int iterations) { double xpre = xa; double xcur = xb; double fpre = fa; double fcur = fb; funcalls = 0; iterations = 0; if (fpre * fcur > 0) { throw new Exception("Brent : root must be bracketed"); } if (DoubleUtils.EqualZero(fpre)) { return(xpre); } if (DoubleUtils.EqualZero(fcur)) { return(xcur); } double xblk = 0.0, fblk = 0.0, spre = 0.0, scur = 0.0; for (int i = 0; i < maxIter; i++) { iterations++; if (fpre * fcur < 0) { xblk = xpre; fblk = fpre; spre = scur = xcur - xpre; } if (Math.Abs(fblk) < Math.Abs(fcur)) { xpre = xcur; xcur = xblk; xblk = xpre; fpre = fcur; fcur = fblk; fblk = fpre; } double tol = xtol + rtol * Math.Abs(xcur); double sbis = (xblk - xcur) / 2.0; if (DoubleUtils.EqualZero(fcur) || Math.Abs(sbis) < tol) { return(xcur); } if (Math.Abs(spre) > tol && Math.Abs(fcur) < Math.Abs(fpre)) { double stry; if (DoubleUtils.MachineEquality(xpre, xblk)) { // interpolate stry = -fcur * (xcur - xpre) / (fcur - fpre); } else { // extrapolate double dpre = (fpre - fcur) / (xpre - xcur); double dblk = (fblk - fcur) / (xblk - xcur); stry = -fcur * (fblk - fpre) / (fblk * dpre - fpre * dblk); } if (2.0 * Math.Abs(stry) < Math.Min(Math.Abs(spre), 3.0 * Math.Abs(sbis) - tol)) { // accept step spre = scur; scur = stry; } else { // bisect spre = sbis; scur = sbis; } } else { // bisect spre = sbis; scur = sbis; } xpre = xcur; fpre = fcur; if (Math.Abs(scur) > tol) { xcur += scur; } else { xcur += (sbis > 0.0 ? tol : -tol); } fcur = f(xcur); funcalls++; } throw new Exception("Brent : max iteration excedeed"); }