Example #1
0
        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 TestMachineEquality()
        {
            Assert.IsTrue(DoubleUtils.MachineEquality(1.0 + DoubleUtils.MachineEpsilon, 1.0));
            Assert.IsTrue(DoubleUtils.MachineEquality(1.00000000000000000000001, 1.0));
            Assert.IsFalse(DoubleUtils.MachineEquality(1.0 + 2.0 * DoubleUtils.MachineEpsilon, 1.0));
            Assert.IsFalse(DoubleUtils.MachineEquality(1.0e-28, 0.0));
            Assert.IsFalse(DoubleUtils.MachineEquality((1.0 + 2 * DoubleUtils.MachineEpsilon) * 1.0e-28, 1.0e-28));
            Assert.IsTrue(DoubleUtils.MachineEquality((1.0 + DoubleUtils.MachineEpsilon) * 1.0e-28, 1.0e-28));
            Assert.IsTrue(DoubleUtils.MachineEquality(1.00000000000000000000000001e-28, 1.0e-28));
            Assert.IsFalse(DoubleUtils.MachineEquality(double.NegativeInfinity, 0.0));
            Assert.IsFalse(DoubleUtils.MachineEquality(double.NegativeInfinity, double.PositiveInfinity));
            Assert.IsTrue(DoubleUtils.MachineEquality(double.NegativeInfinity, double.NegativeInfinity));

            var rand = new Random(255);

            for (int i = 0; i < 1e6; i++)
            {
                var x = rand.NextDouble();
                Assert.IsTrue(DoubleUtils.MachineEquality(x, x));
                Assert.IsTrue(DoubleUtils.MachineEquality(-x, -x));
                Assert.IsTrue(DoubleUtils.MachineEquality(100.0 * x, 100.0 * x));
                Assert.IsTrue(DoubleUtils.MachineEquality(-100.0 * x, -100.0 * x));
                Assert.IsTrue(DoubleUtils.MachineEquality(10000000000.0 * x, 10000000000.0 * x));
                Assert.IsTrue(DoubleUtils.MachineEquality(-10000000000.0 * x, -10000000000.0 * x));
            }
        }
Example #3
0
        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);
        }
Example #4
0
        public static RrFunction ZcRateCoeffFunction(double maturity, double meanReversion)
        {
            var expMat = Math.Exp(-meanReversion * maturity);

            if (DoubleUtils.MachineEquality(1.0, expMat))
            {
                return(RrFunctions.Affine(1.0, -maturity));
            }

            return((expMat / meanReversion) * RrFunctions.Exp(meanReversion) - (1.0 / meanReversion));
        }
Example #5
0
        public void TestIntegral(double[] pillars, double[] vals, double leftVal, double[] refIntegralVals)
        {
            var stepFunc = new StepFunction(pillars, vals, leftVal);
            var integral = stepFunc.Integral(pillars[0]);

            Assert.IsTrue(integral is SplineInterpoler);
            for (int i = 0; i < pillars.Length - 1; i++)
            {
                var integralVal = integral.Eval(pillars[i]);
                Assert.IsTrue(DoubleUtils.MachineEquality(integralVal, refIntegralVals[i]));
            }
        }
Example #6
0
        private static bool Bracket(Func <double, double> f, double x1, double x2,
                                    out double xa, out double fa,
                                    out double xb, out double fb)
        {
            const int    NTRY   = 50;
            const double FACTOR = 1.6;

            if (DoubleUtils.MachineEquality(x1, x2))
            {
                throw new Exception("Bracket : bad initial range");
            }
            xa = x1;
            xb = x2;
            fa = f(xa);
            fb = f(xb);

            double last  = double.NaN;
            double lastf = double.NaN;

            for (int j = 0; j < NTRY; j++)
            {
                if (fa * fb < 0.0)
                {
                    if (lastf * fa < 0.0)
                    {
                        xb = last;
                        fb = lastf;
                    }
                    if (lastf * fb < 0.0)
                    {
                        xa = last;
                        fa = lastf;
                    }
                    return(true);
                }
                if (Math.Abs(fa) < Math.Abs(fb))
                {
                    last  = xa;
                    lastf = fa;
                    xa   += FACTOR * (xa - xb);
                    fa    = f(xa);
                }
                else
                {
                    last  = xb;
                    lastf = fb;
                    xb   += FACTOR * (xb - xa);
                    fb    = f(xb);
                }
            }
            return(false);
        }
        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));
        }
Example #8
0
        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));
        }
Example #9
0
        public void TestMult()
        {
            var          pillars1 = new[] { 0.0, 1.0, 2.0 };
            var          vals1    = new[] { 0.007, 0.004, 0.0065 };
            const double left1    = 2.0;
            var          step1    = new StepFunction(pillars1, vals1, left1);

            var          pillars2 = new[] { -0.8, 0.2, 1.0, 1.5, 2.0, 3.55 };
            var          vals2    = new[] { 0.005, 0.003, -0.1, 0.0, -0.08, 10.0 };
            const double left2    = -1.89;
            var          step2    = new StepFunction(pillars2, vals2, left2);

            var prod = step1 * step2;

            Assert.IsTrue(prod is StepFunction);

            var allPillars = pillars1.Union(pillars2).OrderBy(p => p).ToArray();

            for (int i = 0; i < allPillars.Length; i++)
            {
                double x       = allPillars[i];
                var    val1    = step1.Eval(x);
                var    val2    = step2.Eval(x);
                var    prodVal = prod.Eval(x);

                Assert.IsTrue(DoubleUtils.MachineEquality(prodVal, val1 * val2));
            }
            Assert.IsTrue(DoubleUtils.MachineEquality(prod.Eval(double.NegativeInfinity),
                                                      step1.Eval(double.NegativeInfinity) * step2.Eval(double.NegativeInfinity)));

            var    rand = new Random(123);
            double a    = allPillars.Max() - allPillars.Min();
            double b    = allPillars.Min();

            for (int i = 0; i < 1000; i++)
            {
                var x       = rand.NextDouble() * a * 3.0 + b - 0.1 * a;
                var val1    = step1.Eval(x);
                var val2    = step2.Eval(x);
                var prodVal = prod.Eval(x);

                Assert.IsTrue(DoubleUtils.MachineEquality(prodVal, val1 * val2));
            }
        }
Example #10
0
        public void SinglePathIncrementCovariance(double[] dates, double epsilon, double precision)
        {
            var brownian   = BrownianBridge.Create(dates);
            var dim        = brownian.GaussianSize(1);
            var jacobian   = FiniteDifferenceUtils.CenteredJacobian(x => PathInc1D(brownian, x), dim, new double[dim], epsilon);
            var covariance = jacobian.Prod(jacobian.Tranpose());

            for (int i = 0; i < dates.Length; i++)
            {
                var error = Math.Abs(covariance[i, i] - (i == 0 ? dates[0] : dates[i] - dates[i - 1]));
                Assert.LessOrEqual(error, precision);

                for (int j = 0; j < i; j++)
                {
                    var errorij = Math.Abs(covariance[i, j]);
                    Assert.LessOrEqual(errorij, precision);
                    Assert.IsTrue(DoubleUtils.MachineEquality(covariance[i, j], covariance[j, i]));
                }
            }
        }
Example #11
0
        /// <summary>
        /// Brownian bridge constructor
        /// </summary>
        /// <param name="dates"> Simulation dates, assumed to be sorted and strictly positive </param>
        /// <param name="importantIndexes"> Indexes of Dates that should choose first in brownian bridge construction </param>
        public static BrownianBridge Create(double[] dates, int[] importantIndexes)
        {
            if (importantIndexes.Any(index => index > dates.Length))
            {
                throw new Exception("BrownianBridge : importantIndexes contain an index higher that dates.Length !");
            }

            if (!EnumerableUtils.IsSorted(dates))
            {
                throw new Exception("BrownianBridge : dates must be sorted ! ");
            }

            if (dates[0] < 0.0)
            {
                throw new Exception("BrownianBridge : First date must be positive");
            }

            int[]    simulationIndexes = EnumerableUtils.ConstantArray(int.MinValue, dates.Length);
            int[]    leftIndex         = EnumerableUtils.ConstantArray(-1, dates.Length);
            int[]    rightIndex        = EnumerableUtils.ConstantArray(dates.Length, dates.Length);
            double[] simulVariance     = EnumerableUtils.ConstantArray(double.NaN, dates.Length);

            double[] dateVariances        = dates.Map(d => d);
            var      importantIndexesList = new List <int>(importantIndexes);

            for (int k = 0; k < dates.Length; ++k)
            {
                int currentIndex;
                if (importantIndexes.Count() > 0)
                {
                    double maxVariance = importantIndexesList.Select(i => dateVariances[i]).Max();
                    currentIndex = importantIndexesList.First(i => DoubleUtils.MachineEquality(dateVariances[i], maxVariance));
                    importantIndexesList.Remove(currentIndex);
                }
                else
                {
                    double maxVariance = dateVariances.Max();
                    currentIndex = dateVariances.Select((v, i) => new { Var = v, Index = i })
                                   .Where(v => DoubleUtils.MachineEquality(v.Var, maxVariance))
                                   .Select(v => v.Index)
                                   .First();
                }

                var currentVariance = dateVariances[currentIndex];
                simulationIndexes[k] = currentIndex;
                simulVariance[k]     = currentVariance;

                int    currentLeftIndex  = leftIndex[currentIndex];
                int    currentRightIndex = rightIndex[currentIndex];
                double leftDate          = currentLeftIndex == -1 ? 0.0 : dates[currentLeftIndex];
                double currentDate       = dates[currentIndex];
                double rightDate         = dates[Math.Min(currentRightIndex, dates.Length - 1)];

                for (int j = currentLeftIndex + 1; j < currentIndex; ++j)
                {
                    dateVariances[j] = (dates[j] - leftDate) * (currentDate - dates[j]) / (currentDate - leftDate);
                    rightIndex[j]    = currentIndex;
                }
                dateVariances[currentIndex] = 0.0;
                for (int j = currentIndex + 1; j < currentRightIndex; ++j)
                {
                    dateVariances[j] = (rightDate - dates[j]) * (dates[j] - currentDate) / (rightDate - currentDate);
                    leftIndex[j]     = currentIndex;
                }
            }
            var simulationStdDevs = simulVariance.Select(Math.Sqrt).ToArray();

            return(new BrownianBridge(dates, simulationIndexes, simulationStdDevs, leftIndex, rightIndex));
        }
Example #12
0
 public static bool IsUnity(this Polynomial p)
 {
     return(DoubleUtils.MachineEquality(p.Coeffs[0], 1.0) &&
            p.Coeffs.Skip(1).All(DoubleUtils.EqualZero));
 }
Example #13
0
        /// <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");
        }