예제 #1
0
        public void SymmetricRandomMatrixCholeskyDecomposition()
        {
            int    d   = 100;
            Random rng = new Random(d);

            ColumnVector[] V = new ColumnVector[d];
            for (int i = 0; i < d; i++)
            {
                V[i] = new ColumnVector(d);
                for (int j = 0; j < d; j++)
                {
                    V[i][j] = rng.NextDouble();
                }
            }

            SymmetricMatrix A = new SymmetricMatrix(d);

            for (int i = 0; i < d; i++)
            {
                for (int j = 0; j <= i; j++)
                {
                    A[i, j] = V[i].Transpose * V[j];
                }
            }

            Stopwatch             s  = Stopwatch.StartNew();
            CholeskyDecomposition CD = A.CholeskyDecomposition();

            s.Stop();
            Console.WriteLine("{0} {1}", d, s.ElapsedMilliseconds);

            Assert.IsTrue(CD != null);
        }
        public MultivariateSample CreateMultivariateNormalSample(ColumnVector M, SymmetricMatrix C, int n)
        {
            int d = M.Dimension;

            MultivariateSample S = new MultivariateSample(d);

            SquareMatrix A = C.CholeskyDecomposition().SquareRootMatrix();

            Random rng = new Random(1);
            ContinuousDistribution normal = new NormalDistribution();


            for (int i = 0; i < n; i++)
            {
                // create a vector of normal deviates
                ColumnVector V = new ColumnVector(d);
                for (int j = 0; j < d; j++)
                {
                    double y = rng.NextDouble();
                    double z = normal.InverseLeftProbability(y);
                    V[j] = z;
                }

                // form the multivariate distributed vector
                ColumnVector X = M + A * V;

                // add it to the sample
                S.Add(X);
            }

            return(S);
        }
예제 #3
0
        private void TestAutocovariance(IList <double> acv)
        {
            // Verify that variance is positive
            Assert.IsTrue(acv[0] >= 0.0);

            // Verify that correlations -1 <= r <= 1
            for (int i = 0; i < acv.Count; i++)
            {
                Assert.IsTrue(Math.Abs(acv[i]) <= acv[0]);
            }

            // Verify that autocovariance is positive definite
            SymmetricMatrix C = new SymmetricMatrix(acv.Count);

            for (int r = 0; r < acv.Count; r++)
            {
                for (int c = 0; c <= r; c++)
                {
                    C[r, c] = acv[r - c];
                }
            }
            CholeskyDecomposition CD = C.CholeskyDecomposition();

            Assert.IsTrue(CD != null);
        }
예제 #4
0
        public static void EigenvaluesAndEigenvectors()
        {
            SymmetricMatrix H = new SymmetricMatrix(3);

            for (int r = 0; r < H.Dimension; r++)
            {
                for (int c = 0; c <= r; c++)
                {
                    H[r, c] = 1.0 / (r + c + 1);
                }
            }

            RealEigendecomposition ed = H.Eigendecomposition();

            SquareMatrix V = ed.TransformMatrix;

            PrintMatrix("V^T V", V.Transpose * V);
            PrintMatrix("V D V^T", V * ed.DiagonalizedMatrix * V.Transpose);

            foreach (RealEigenpair pair in ed.Eigenpairs)
            {
                Console.WriteLine($"Eigenvalue {pair.Eigenvalue}");
                PrintMatrix("Hv", H * pair.Eigenvector);
                PrintMatrix("ev", pair.Eigenvalue * pair.Eigenvector);
            }

            ed.Eigenpairs.Sort(OrderBy.MagnitudeDescending);
            Console.WriteLine($"Largest eigenvalue {ed.Eigenpairs[0].Eigenvalue}");
            ed.Eigenpairs.Sort(OrderBy.ValueAscending);
            Console.WriteLine($"Least eigenvalue {ed.Eigenpairs[0].Eigenvalue}");

            double[] eigenvalues = H.Eigenvalues();

            double sum     = 0.0;
            double product = 1.0;

            foreach (double eigenvalue in eigenvalues)
            {
                sum     += eigenvalue;
                product *= eigenvalue;
            }
            Console.WriteLine($"sum(e) = {sum},  tr(H) = {H.Trace()}");
            Console.WriteLine($"prod(e) = {product}, det(H) = {H.CholeskyDecomposition().Determinant()}");

            SquareMatrix G1 = new SquareMatrix(4);

            G1[0, 3] = 1.0;
            G1[1, 2] = 1.0;
            G1[2, 1] = -1.0;
            G1[3, 0] = -1.0;

            ComplexEigendecomposition ced = G1.Eigendecomposition();

            foreach (ComplexEigenpair pair in ced.Eigenpairs)
            {
                Console.WriteLine(pair.Eigenvalue);
            }
        }
예제 #5
0
        public void GaussianIntegrals()
        {
            Random rng = new Random(1);

            for (int d = 2; d < 4; d++)
            {
                if (d == 4 || d == 5 || d == 6)
                {
                    continue;
                }
                Console.WriteLine(d);

                // Create a symmetric matrix
                SymmetricMatrix A = new SymmetricMatrix(d);
                for (int r = 0; r < d; r++)
                {
                    for (int c = 0; c < r; c++)
                    {
                        A[r, c] = rng.NextDouble();
                    }
                    // Ensure it is positive definite by diagonal dominance
                    A[r, r] = r + 1.0;
                }

                // Compute its determinant, which appears in the analytic value of the integral
                CholeskyDecomposition CD = A.CholeskyDecomposition();
                double detA = CD.Determinant();

                // Compute the integral
                Func <IList <double>, double> f = (IList <double> x) => {
                    ColumnVector v = new ColumnVector(x);
                    double       s = v.Transpose() * (A * v);
                    return(Math.Exp(-s));
                };

                Interval[] volume = new Interval[d];
                for (int i = 0; i < d; i++)
                {
                    volume[i] = Interval.FromEndpoints(Double.NegativeInfinity, Double.PositiveInfinity);
                }

                IntegrationResult I = MultiFunctionMath.Integrate(f, volume);

                // Compare to the analytic result
                Console.WriteLine("{0} ({1}) {2}", I.Value, I.Precision, Math.Sqrt(MoreMath.Pow(Math.PI, d) / detA));
                Assert.IsTrue(TestUtilities.IsNearlyEqual(I.Value, Math.Sqrt(MoreMath.Pow(Math.PI, d) / detA), new EvaluationSettings()
                {
                    AbsolutePrecision = 2.0 * I.Precision
                }));
            }
        }
예제 #6
0
        public void SymmetricMatrixDecomposition()
        {
            for (int d = 1; d <= 4; d++)
            {
                SymmetricMatrix H = TestUtilities.CreateSymmetricHilbertMatrix(d);

                CholeskyDecomposition CD = H.CholeskyDecomposition();
                Assert.IsTrue(CD != null, String.Format("d={0} not positive definite", d));
                Assert.IsTrue(CD.Dimension == d);
                SymmetricMatrix HI = CD.Inverse();
                SquareMatrix    I  = TestUtilities.CreateSquareUnitMatrix(d);
                Assert.IsTrue(TestUtilities.IsNearlyEqual(H * HI, I));
            }
        }
예제 #7
0
        public void GaussianIntegrals()
        {
            Random rng = new Random(1);

            for (int d = 2; d < 8; d++)
            {
                Console.WriteLine(d);

                // Create a symmetric matrix
                SymmetricMatrix A = new SymmetricMatrix(d);
                for (int r = 0; r < d; r++)
                {
                    for (int c = 0; c < r; c++)
                    {
                        A[r, c] = rng.NextDouble();
                    }
                    // Ensure it is positive definite by diagonal dominance
                    A[r, r] = r + 1.0;
                }

                // Compute its determinant, which appears in the analytic value of the integral
                CholeskyDecomposition CD = A.CholeskyDecomposition();
                double detA = CD.Determinant();

                // Compute the integral
                Func <IReadOnlyList <double>, double> f = (IReadOnlyList <double> x) => {
                    ColumnVector v = new ColumnVector(x);
                    double       s = v.Transpose * (A * v);
                    return(Math.Exp(-s));
                };

                Interval[] volume = new Interval[d];
                for (int i = 0; i < d; i++)
                {
                    volume[i] = Interval.FromEndpoints(Double.NegativeInfinity, Double.PositiveInfinity);
                }

                // These are difficult integrals; demand reduced precision.
                IntegrationSettings settings = new IntegrationSettings()
                {
                    RelativePrecision = Math.Pow(10.0, -(4.0 - d / 2.0))
                };

                IntegrationResult I = MultiFunctionMath.Integrate(f, volume, settings);

                // Compare to the analytic result
                Assert.IsTrue(I.Estimate.ConfidenceInterval(0.95).ClosedContains(Math.Sqrt(MoreMath.Pow(Math.PI, d) / detA)));
            }
        }
예제 #8
0
        public void CholeskySolveExample()
        {
            // This is a very simple 3 X 3 problem I just wrote down to test the Cholesky solver
            SymmetricMatrix S = new SymmetricMatrix(3);

            S[0, 0] = 4.0;
            S[1, 0] = -2.0; S[1, 1] = 5.0;
            S[2, 0] = 1.0;  S[2, 1] = 3.0; S[2, 2] = 6.0;
            CholeskyDecomposition CD = S.CholeskyDecomposition();

            ColumnVector b = new ColumnVector(9.0, 7.0, 15.0);
            ColumnVector x = CD.Solve(b);

            Assert.IsTrue(TestUtilities.IsNearlyEqual(S * x, b));
        }
        /// <summary>
        /// Fits the data to an arbitrary parameterized function.
        /// </summary>
        /// <param name="function">The fit function.</param>
        /// <param name="start">An initial guess at the parameters.</param>
        /// <returns>A fit result containing the best-fitting function parameters
        /// and a &#x3C7;<sup>2</sup> test of the quality of the fit.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="function"/> or <paramref name="start"/> are <see langword="null"/>.</exception>
        /// <exception cref="InsufficientDataException">There are fewer data points than fit parameters.</exception>
        /// <exception cref="DivideByZeroException">The curvature matrix is singular, indicating that the data is independent of
        /// one or more parameters, or that two or more parameters are linearly dependent.</exception>
        public FitResult FitToFunction(Func <double[], T, double> function, double[] start)
        {
            if (function == null)
            {
                throw new ArgumentNullException(nameof(function));
            }
            if (start == null)
            {
                throw new ArgumentNullException(nameof(start));
            }

            // you can't do a fit with less data than parameters
            if (this.Count < start.Length)
            {
                throw new InsufficientDataException();
            }

            /*
             * Func<IList<double>, double> function0 = (IList<double> x0) => {
             *  double[] x = new double[x0.Count];
             *  x0.CopyTo(x, 0);
             *  return(function(x));
             * };
             * MultiExtremum minimum0 = MultiFunctionMath.FindMinimum(function0, start);
             */

            // create a chi^2 fit metric and minimize it
            FitMetric <T> metric  = new FitMetric <T>(this, function);
            SpaceExtremum minimum = FunctionMath.FindMinimum(new Func <double[], double>(metric.Evaluate), start);

            // compute the covariance (Hessian) matrix by inverting the curvature matrix
            SymmetricMatrix       A  = 0.5 * minimum.Curvature();
            CholeskyDecomposition CD = A.CholeskyDecomposition(); // should not return null if we were at a minimum

            if (CD == null)
            {
                throw new DivideByZeroException();
            }
            SymmetricMatrix C = CD.Inverse();

            // package up the results and return them
            TestResult test = new TestResult("ChiSquare", minimum.Value, TestType.RightTailed, new ChiSquaredDistribution(this.Count - minimum.Dimension));
            FitResult  fit  = new FitResult(minimum.Location(), C, test);

            return(fit);
        }
예제 #10
0
        public void CatalanHankelMatrixDeterminant()
        {
            for (int d = 1; d <= 8; d++)
            {
                SymmetricMatrix S = new SymmetricMatrix(d);
                for (int r = 0; r < d; r++)
                {
                    for (int c = 0; c <= r; c++)
                    {
                        int n = r + c;
                        S[r, c] = AdvancedIntegerMath.BinomialCoefficient(2 * n, n) / (n + 1);
                    }
                }

                CholeskyDecomposition CD = S.CholeskyDecomposition();
                Assert.IsTrue(TestUtilities.IsNearlyEqual(CD.Determinant(), 1.0));
            }
        }
예제 #11
0
        public void HilbertMatrixCholeskyDecomposition()
        {
            for (int d = 1; d <= 4; d++)
            {
                SymmetricMatrix H = TestUtilities.CreateSymmetricHilbertMatrix(d);

                // Decomposition succeeds
                CholeskyDecomposition CD = H.CholeskyDecomposition();
                Assert.IsTrue(CD != null);
                Assert.IsTrue(CD.Dimension == d);

                // Decomposition works
                SquareMatrix S = CD.SquareRootMatrix();
                Assert.IsTrue(TestUtilities.IsNearlyEqual(S * S.Transpose, H));

                // Inverse works
                SymmetricMatrix HI = CD.Inverse();
                Assert.IsTrue(TestUtilities.IsNearlyEqual(H * HI, UnitMatrix.OfDimension(d)));
            }
        }
예제 #12
0
        internal static DistributionFitResult <ContinuousDistribution> MaximumLikelihoodFit(IReadOnlyList <double> sample, Func <IReadOnlyList <double>, ContinuousDistribution> factory, IReadOnlyList <double> start, IReadOnlyList <string> names)
        {
            Debug.Assert(sample != null);
            Debug.Assert(factory != null);
            Debug.Assert(start != null);
            Debug.Assert(names != null);
            Debug.Assert(start.Count == names.Count);

            // Define a log likelihood function
            Func <IReadOnlyList <double>, double> logL = (IReadOnlyList <double> a) => {
                ContinuousDistribution d = factory(a);
                double lnP = 0.0;
                foreach (double value in sample)
                {
                    double P = d.ProbabilityDensity(value);
                    if (P == 0.0)
                    {
                        throw new InvalidOperationException();
                    }
                    lnP += Math.Log(P);
                }
                return(lnP);
            };

            // Maximize it
            MultiExtremum         maximum = MultiFunctionMath.FindLocalMaximum(logL, start);
            ColumnVector          b       = maximum.Location;
            SymmetricMatrix       C       = maximum.HessianMatrix;
            CholeskyDecomposition CD      = C.CholeskyDecomposition();

            if (CD == null)
            {
                throw new DivideByZeroException();
            }
            C = CD.Inverse();

            ContinuousDistribution distribution = factory(maximum.Location);
            TestResult             test         = sample.KolmogorovSmirnovTest(distribution);

            return(new ContinuousDistributionFitResult(names, b, C, distribution, test));
        }
        /// <summary>
        /// Fits the data to an arbitrary parameterized function.
        /// </summary>
        /// <param name="function">The fit function.</param>
        /// <param name="start">An initial guess at the parameters.</param>
        /// <returns>A fit result containing the best-fitting function parameters
        /// and a &#x3C7;<sup>2</sup> test of the quality of the fit.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="function"/> or <paramref name="start"/> are <see langword="null"/>.</exception>
        /// <exception cref="InsufficientDataException">There are fewer data points than fit parameters.</exception>
        /// <exception cref="DivideByZeroException">The curvature matrix is singular, indicating that the data is independent of
        /// one or more parameters, or that two or more parameters are linearly dependent.</exception>
        public UncertainMeasurementFitResult FitToFunction(Func <double[], T, double> function, double[] start)
        {
            if (function == null)
            {
                throw new ArgumentNullException(nameof(function));
            }
            if (start == null)
            {
                throw new ArgumentNullException(nameof(start));
            }

            // you can't do a fit with less data than parameters
            if (this.Count < start.Length)
            {
                throw new InsufficientDataException();
            }

            // create a chi^2 fit metric and minimize it
            FitMetric <T> metric  = new FitMetric <T>(this, function);
            SpaceExtremum minimum = FunctionMath.FindMinimum(new Func <double[], double>(metric.Evaluate), start);

            // compute the covariance (Hessian) matrix by inverting the curvature matrix
            SymmetricMatrix       A  = 0.5 * minimum.Curvature();
            CholeskyDecomposition CD = A.CholeskyDecomposition(); // should not return null if we were at a minimum

            if (CD == null)
            {
                throw new DivideByZeroException();
            }
            SymmetricMatrix C = CD.Inverse();

            // package up the results and return them
            TestResult          test       = new TestResult("χ²", minimum.Value, new ChiSquaredDistribution(this.Count - minimum.Dimension), TestType.RightTailed);
            ParameterCollection parameters = new ParameterCollection(NumberNames(start.Length), new ColumnVector(minimum.Location(), 0, 1, start.Length, true), C);

            return(new UncertainMeasurementFitResult(parameters, test));
        }
예제 #14
0
        /// <summary>
        /// Find the Gumbel distribution that best fit the given sample.
        /// </summary>
        /// <param name="sample">The sample to fit.</param>
        /// <returns>The fit result.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="sample"/> is <see langword="null"/>.</exception>
        /// <exception cref="InsufficientDataException"><paramref name="sample"/> contains fewer than three values.</exception>
        public static GumbelFitResult FitToGumbel(this IReadOnlyList <double> sample)
        {
            if (sample == null)
            {
                throw new ArgumentNullException(nameof(sample));
            }
            if (sample.Count < 3)
            {
                throw new InsufficientDataException();
            }

            // To do a maximum likelihood fit, start from the log probability of each data point and aggregate to
            // obtain the log likelihood of the sample
            //   z_i = \frac{x_i - m}{s}
            //   -\ln p_i = \ln s + ( z_i + e^{-z_i})
            //   \ln L = \sum_i \ln p_i

            // Take derivatives wrt m and s.
            //   \frac{\partial \ln L}{\partial m} = \frac{1}{s} \sum_i ( 1 - e^{-z_i} )
            //   \frac{\partial \ln L}{\partial s} = \frac{1}{s} \sum_i ( -1 + z_i - z_i e^{-z_i} )

            // Set derivatives to zero to get a system of equations for the maximum.
            //    n = \sum_i e^{-z_i}
            //    n = \sum_i ( z_i - z_i e^{-z_i} )
            // that is, <e^z> = 1 and <z> - <z e^z> = 1.

            // To solve this system, pull e^{m/s} out of the sum in the first equation and solve for m
            //    n = e^{m / s} \sum_i e^{-x_i / s}
            //    m = -s \ln \left( \frac{1}{n} \sum_i e^{-x_i / s} \right) = -s \ln <e^{-x/s}>
            // Substituting this result into the second equation gets us to
            //    s = \bar{x} - \frac{ <x e^{-x/s}> }{ <e^{x/s}> }
            // which involves only s. We can use a one-dimensional root-finder to determine s, then determine m
            // from the first equation.

            // To avoid exponentiating potentially large x_i, it's better to write the problem in terms
            // of d_i, where x_i = \bar{x} + d_i.
            //    m = \bar{x} - s \ln <e^{-d/s}>
            //    s = -\frac{ <d e^{-d/s}> }{ <e^{-d/s}> }

            // To get the covariance matrix, we need the curvature matrix at the minimum, so take more derivatives
            //    \frac{\partial^2 \ln L}{\partial m^2} = - \frac{1}{s} \sum_i e^{-z_i} = - \frac{n}{s^2}
            //    \frac{\partial^2 \ln L}{\partial m \partial s} = - \frac{n}{s^2} <z e^{-z}>
            //    \frac{\partial^2 \ln L}{\partial s^2} = - \frac{n}{s^2} ( <z^2 e^{-z}> + 1 )

            // Several crucial pieces of this analysis are taken from Mahdi and Cenac, "Estimating Parameters of Gumbel Distribution
            // "using the method of moments, probability weighted moments, and maximum likelihood", Revista de Mathematica:
            // Teoria y Aplicaciones 12 (2005) 151-156 (http://revistas.ucr.ac.cr/index.php/matematica/article/viewFile/259/239)

            // We will be needed the sample mean and standard deviation
            int    n;
            double mean, stdDev;

            Univariate.ComputeMomentsUpToSecond(sample, out n, out mean, out stdDev);
            stdDev = Math.Sqrt(stdDev / n);

            // Use the method of moments to get an initial estimate of s.
            double s0 = Math.Sqrt(6.0) / Math.PI * stdDev;

            // Define the function to zero
            Func <double, double> fnc = (double s) => {
                double u, v;
                MaximumLikelihoodHelper(sample, n, mean, s, out u, out v);
                return(s + v / u);
            };

            // Zero it to compute the best-fit s
            double s1 = FunctionMath.FindZero(fnc, s0);

            // Compute the corresponding best-fit m
            double u1, v1;

            MaximumLikelihoodHelper(sample, n, mean, s1, out u1, out v1);
            double m1 = mean - s1 * Math.Log(u1);

            // Compute the curvature matrix
            double w1 = 0.0;
            double w2 = 0.0;

            foreach (double x in sample)
            {
                double z = (x - m1) / s1;
                double e = Math.Exp(-z);
                w1 += z * e;
                w2 += z * z * e;
            }
            w1 /= sample.Count;
            w2 /= sample.Count;
            SymmetricMatrix C = new SymmetricMatrix(2);

            C[0, 0] = (n - 2) / (s1 * s1);
            C[0, 1] = (n - 2) / (s1 * s1) * w1;
            C[1, 1] = (n - 2) / (s1 * s1) * (w2 + 1.0);
            SymmetricMatrix CI = C.CholeskyDecomposition().Inverse();
            // The use of (n-2) here in place of n is a very ad hoc attempt to increase accuracy.


            // Compute goodness-of-fit
            GumbelDistribution dist = new GumbelDistribution(m1, s1);
            TestResult         test = sample.KolmogorovSmirnovTest(dist);

            return(new GumbelFitResult(m1, s1, CI[0, 0], CI[1, 1], CI[0, 1], test));
        }
예제 #15
0
        public double PriceVIXOption(VIXOption Option, Func <double, double> epsilon, double stock_0)
        {
            int    n    = 500;
            double T    = Option.maturity;
            Grid   grid = new Grid(0, T, (int)Math.Abs(T * n));
            int    n_T  = grid.get_timeNmbrStep();

            int kappa = 2;
            //Correlation :
            SymmetricMatrix correl         = MakeCorrel(n, grid);
            SquareMatrix    choleskyCorrel = correl.CholeskyDecomposition().SquareRootMatrix();

            double rho = 0.1;//correlation between the two Brownian
            Func <double, double> payoff;

            switch (Option.type)
            {
            case VIXOption.OptionType.Call:
                payoff = S => Math.Max(S - Option.strike, 0);
                break;

            case VIXOption.OptionType.Put:
                payoff = S => Math.Max(Option.strike - S, 0);
                break;

            default:
                payoff = S => Math.Max(S - Option.strike, 0);
                break;
            }

            double price          = 0.0;
            double McNbSimulation = 1E5;

            for (int mc = 1; mc <= McNbSimulation; mc++)
            {
                // 1-simulation of volterra Hybrid Scheme
                ColumnVector Z;
                ColumnVector volterra;
                //ColumnVector Z_Brownian;

                HybridScheme hybridscheme = new HybridScheme(choleskyCorrel, grid, kappa, H);
                hybridscheme.simulate(out Z, out volterra);

                GaussianSimulator simulator = new GaussianSimulator();
                //Z_Brownian = ExtractBrownian(kappa, n_T, Z, volterra);

                ColumnVector Variance = new ColumnVector(n_T + 1);
                Variance[0] = epsilon(grid.t(0));
                for (int i = 1; i <= grid.get_timeNmbrStep(); i++)
                {
                    Variance[i] = epsilon(grid.t(i)) * Math.Exp(2 * vi * Ch * volterra[i - 1] - Math.Pow(vi * Ch, 2) * Math.Pow(grid.t(i), 2 * H));
                }
                double X = Math.Log(stock_0);
                for (int i = 0; i < n_T; i++)
                {
                    double dW = (rho * Z[i] + Math.Sqrt(1 - Math.Pow(rho, 2)) * Math.Sqrt(grid.get_Step()) * simulator.Next());
                    X = X - 0.5 * Variance[i] * grid.get_Step() + Math.Sqrt(Variance[i]) * dW;
                }

                double S = Math.Exp(X);
                price += payoff(S);
            }
            price /= McNbSimulation;
            return(price);
        }
예제 #16
0
        // routines for maximum likelyhood fitting

        /// <summary>
        /// Computes the Gamma distribution that best fits the given sample.
        /// </summary>
        /// <param name="sample">The sample to fit.</param>
        /// <returns>The best fit parameters.</returns>
        /// <remarks>
        /// <para>The returned fit parameters are the <see cref="ShapeParameter"/> and <see cref="ScaleParameter"/>, in that order.
        /// These are the same parameters, in the same order, that are required by the <see cref="GammaDistribution(double,double)"/> constructor to
        /// specify a new Gamma distribution.</para>
        /// </remarks>
        /// <exception cref="ArgumentNullException"><paramref name="sample"/> is null.</exception>
        /// <exception cref="InvalidOperationException"><paramref name="sample"/> contains non-positive values.</exception>
        /// <exception cref="InsufficientDataException"><paramref name="sample"/> contains fewer than three values.</exception>
        public static FitResult FitToSample(Sample sample)
        {
            if (sample == null)
            {
                throw new ArgumentNullException("sample");
            }
            if (sample.Count < 3)
            {
                throw new InsufficientDataException();
            }

            // The log likelyhood of a sample given k and s is
            //   \log L = (k-1) \sum_i \log x_i - \frac{1}{s} \sum_i x_i - N \log \Gamma(k) - N k \log s
            // Differentiating,
            //   \frac{\partial \log L}{\partial s} = \frac{1}{s^2} \sum_i x_i - \frac{Nk}{s}
            //   \frac{\partial \log L}{\partial k} = \sum_i \log x_i - N \psi(k) - N \log s
            // Setting the first equal to zero gives
            //   k s = N^{-1} \sum_i x_i = <x>
            //   \psi(k) + \log s = N^{-1} \sum_i \log x_i = <log x>
            // Inserting the first into the second gives a single equation for k
            //   \log k - \psi(k) = \log <x> - <\log x>
            // Note the RHS need only be computed once.
            // \log k > \psi(k) for all k, so the RHS had better be positive. They get
            // closer for large k, so smaller RHS will produce a larger k.

            double s = 0.0;

            foreach (double x in sample)
            {
                if (x <= 0.0)
                {
                    throw new InvalidOperationException();
                }
                s += Math.Log(x);
            }
            s = Math.Log(sample.Mean) - s / sample.Count;

            // We can get an initial guess for k from the method of moments
            //   \frac{\mu^2}{\sigma^2} = k

            double k0 = MoreMath.Sqr(sample.Mean) / sample.Variance;

            // Since 1/(2k) < \log(k) - \psi(k) < 1/k, we could get a bound; that
            // might be better to avoid the solver running into k < 0 territory

            double k1 = FunctionMath.FindZero(k => (Math.Log(k) - AdvancedMath.Psi(k) - s), k0);

            double s1 = sample.Mean / k1;

            // Curvature of the log likelyhood is straightforward
            //   \frac{\partial^2 \log L}{\partial s^2} = -\frac{2}{s^3} \sum_i x_i + \frac{Nk}{s^2} = - \frac{Nk}{s^2}
            //   \frac{\partial^2 \log L}{\partial k \partial s} = - \frac{N}{s}
            //   \frac{\partial^2 \log L}{\partial k^2} = - N \psi'(k)
            // This gives the curvature matrix and thus via inversion the covariance matrix.

            SymmetricMatrix B = new SymmetricMatrix(2);

            B[0, 0] = sample.Count * AdvancedMath.Psi(1, k1);
            B[0, 1] = sample.Count / s1;
            B[1, 1] = sample.Count * k1 / MoreMath.Sqr(s1);
            SymmetricMatrix C = B.CholeskyDecomposition().Inverse();

            // Do a KS test for goodness-of-fit
            TestResult test = sample.KolmogorovSmirnovTest(new GammaDistribution(k1, s1));

            return(new FitResult(new double[] { k1, s1 }, C, test));
        }
예제 #17
0
        // the internal linear regression routine, which assumes inputs are entirely valid

        private FitResult LinearRegression_Internal(int outputIndex)
        {
            // to do a fit, we need more data than parameters
            if (Count < Dimension)
            {
                throw new InsufficientDataException();
            }

            // construct the design matrix
            SymmetricMatrix D = new SymmetricMatrix(Dimension);

            for (int i = 0; i < Dimension; i++)
            {
                for (int j = 0; j <= i; j++)
                {
                    if (i == outputIndex)
                    {
                        if (j == outputIndex)
                        {
                            D[i, j] = Count;
                        }
                        else
                        {
                            D[i, j] = storage[j].Mean * Count;
                        }
                    }
                    else
                    {
                        if (j == outputIndex)
                        {
                            D[i, j] = storage[i].Mean * Count;
                        }
                        else
                        {
                            double Dij = 0.0;
                            for (int k = 0; k < Count; k++)
                            {
                                Dij += storage[i][k] * storage[j][k];
                            }
                            D[i, j] = Dij;
                        }
                    }
                }
            }

            // construct the right hand side
            ColumnVector b = new ColumnVector(Dimension);

            for (int i = 0; i < Dimension; i++)
            {
                if (i == outputIndex)
                {
                    b[i] = storage[i].Mean * Count;
                }
                else
                {
                    double bi = 0.0;
                    for (int k = 0; k < Count; k++)
                    {
                        bi += storage[outputIndex][k] * storage[i][k];
                    }
                    b[i] = bi;
                }
            }

            // solve the system for the linear model parameters
            CholeskyDecomposition CD         = D.CholeskyDecomposition();
            ColumnVector          parameters = CD.Solve(b);

            // find total sum of squares, with dof = # points - 1 (minus one for the variance-minimizing mean)
            double totalSumOfSquares = storage[outputIndex].Variance * Count;

            // find remaining unexplained sum of squares, with dof = # points - # parameters
            double unexplainedSumOfSquares = 0.0;

            for (int r = 0; r < Count; r++)
            {
                double y = 0.0;
                for (int c = 0; c < Dimension; c++)
                {
                    if (c == outputIndex)
                    {
                        y += parameters[c];
                    }
                    else
                    {
                        y += parameters[c] * storage[c][r];
                    }
                }
                unexplainedSumOfSquares += MoreMath.Sqr(y - storage[outputIndex][r]);
            }
            int    unexplainedDegreesOfFreedom = Count - Dimension;
            double unexplainedVariance         = unexplainedSumOfSquares / unexplainedDegreesOfFreedom;

            // find explained sum of squares, with dof = # parameters - 1
            double explainedSumOfSquares     = totalSumOfSquares - unexplainedSumOfSquares;
            int    explainedDegreesOfFreedom = Dimension - 1;
            double explainedVariance         = explainedSumOfSquares / explainedDegreesOfFreedom;

            // compute F statistic from sums of squares
            double       F             = explainedVariance / unexplainedVariance;
            Distribution fDistribution = new FisherDistribution(explainedDegreesOfFreedom, unexplainedDegreesOfFreedom);

            SymmetricMatrix covariance = unexplainedVariance * CD.Inverse();

            return(new FitResult(parameters, covariance, new TestResult("F", F, TestType.RightTailed, fDistribution)));
        }
예제 #18
0
        public ColumnVector VIXfuture_HybridMethod(double T, Func <double, double> epsilon)
        {
            //Result
            ColumnVector VIXFutures;
            //For Exécution Time
            DateTime start = DateTime.Now;
            //Input:
            int kappa = 2;

            // the Gri t_0 ..... t_{100} = T
            int  n    = 500;
            Grid grid = new Grid(0, T, (int)Math.Abs(T * n));

            int n_T = grid.get_timeNmbrStep();

            n_tH = Math.Pow(n_T, H - 0.5); //optimizeMC

            //The second Grid  t_0=T, t_1 ..... t_N = T + Delta
            int Nbstep = 20;

            //Correlation :
            SymmetricMatrix correl         = MakeCorrel(n, grid);
            SquareMatrix    choleskyCorrel = correl.CholeskyDecomposition().SquareRootMatrix();

            int period = 100;

            VIXFutures = new ColumnVector(grid.get_timeNmbrStep() / period);


            //--------------------------------------------------------------------------------------------------------------------------------------------------------------
            //-----------------------------------MC----------------------------------------------------------------------------------------------------------------------
            //-----------------------------------------------------------------------------------------------------------------------------------------------------------
            var          MCnbofSimulation = 3.0E4;
            HybridScheme hybridscheme     = new HybridScheme(choleskyCorrel, grid, kappa, H);

            for (int mc = 1; mc <= MCnbofSimulation; mc++)
            {
                // 1-simulation of volterra Hybrid Scheme
                ColumnVector Z;
                ColumnVector volterra;
                ColumnVector Z_Brownian;

                hybridscheme.simulateFFT(out Z, out volterra);

                //2 - extract the path of the Brownian motion Z driving the Volterra process
                Z_Brownian = ExtractBrownian(kappa, n_T, Z, volterra);

                //Grid secondGrid2 = new Grid(grid.t(n_T), grid.t(n_T) + Delta, 20);
                //ColumnVector volterraT2 = EulerMEthode(grid, secondGrid2, n_T, volterra, Z_Brownian);
                //double VIX_future_i2 = VIX_Calculate(epsilon, secondGrid2, volterraT2);
                //VIXFutures[0] += VIX_future_i2;


                //DateTime starttestM = DateTime.Now;
                //for (int zz = 1; zz <= 1.0E4; zz++)
                //{
                //    hybridscheme.simulateFFT(out Z, out volterra);
                //}
                //TimeSpan timeExecutiontestM = DateTime.Now - starttestM;

                //DateTime starttest = DateTime.Now;
                //for (int zz = 1; zz <= 1.0E4; zz++)
                //{
                //    for (int i = 1; i <= volterra.Count() / period; i++)
                //    {
                //        int N_i2 = i * period;

                //        //3- approximate the continuous-time process V^T by the discrete-time version V^T~ defined via the  forward Euler scheme
                //        double[] volterraT2 = EulerMEthode(grid, secondGrid, N_i2, volterra, Z_Brownian);
                //        //double VIX_future_i2 = VIX_Calculate(epsilon, secondGrid, volterraT2);
                //        //VIXFutures[i - 1] += VIX_future_i2;
                //    }
                //}
                //TimeSpan timeExecutiontest = DateTime.Now - starttest;

                for (int i = 1; i <= volterra.Count() / period; i++)
                {
                    int  N_i        = i * period;
                    Grid secondGrid = new Grid(grid.t(N_i), grid.t(N_i) + Delta, Nbstep);
                    //3- approximate the continuous-time process V^T by the discrete-time version V^T~ defined via the  forward Euler scheme
                    double[] volterraT    = EulerMEthode(grid, secondGrid, N_i, volterra, Z_Brownian);
                    double   VIX_future_i = VIX_Calculate(epsilon, secondGrid, volterraT);
                    VIXFutures[i - 1] += VIX_future_i;
                }
            }// ENd of MC
            //MC Mean
            for (int i = 0; i < VIXFutures.Count(); i++)
            {
                VIXFutures[i] /= MCnbofSimulation;
            }
            TimeSpan timeExecution = DateTime.Now - start;

            return(VIXFutures);
        }
예제 #19
0
        /// <summary>
        /// Finds the Beta distribution that best fits the given sample.
        /// </summary>
        /// <param name="sample">The sample to fit.</param>
        /// <returns>The best fit parameters.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="sample"/> is <see langword="null"/>.</exception>
        /// <exception cref="InsufficientDataException"><paramref name="sample"/> contains fewer than three values.</exception>
        /// <exception cref="InvalidOperationException">Not all the entries in <paramref name="sample" /> lie between zero and one.</exception>
        public static BetaFitResult FitToBeta(this IReadOnlyList <double> sample)
        {
            if (sample == null)
            {
                throw new ArgumentNullException(nameof(sample));
            }
            if (sample.Count < 3)
            {
                throw new InsufficientDataException();
            }

            // maximum likelihood calculation
            //   \log L = \sum_i \left[ (\alpha-1) \log x_i + (\beta-1) \log (1-x_i) - \log B(\alpha,\beta) \right]
            // using \frac{\partial B(a,b)}{\partial a} = \psi(a) - \psi(a+b), we have
            //   \frac{\partial \log L}{\partial \alpha} = \sum_i \log x_i -     N \left[ \psi(\alpha) - \psi(\alpha+\beta) \right]
            //   \frac{\partial \log L}{\partial \beta}  = \sum_i \log (1-x_i) - N \left[ \psi(\beta)  - \psi(\alpha+\beta) \right]
            // set equal to zero to get equations for \alpha, \beta
            //   \psi(\alpha) - \psi(\alpha+\beta) = <\log x>
            //   \psi(\beta) - \psi(\alpha+\beta) = <\log (1-x)>

            // compute the mean log of x and (1-x)
            // these are the (logs of) the geometric means
            double ga = 0.0; double gb = 0.0;

            foreach (double value in sample)
            {
                if ((value <= 0.0) || (value >= 1.0))
                {
                    throw new InvalidOperationException();
                }
                ga += Math.Log(value); gb += Math.Log(1.0 - value);
            }
            ga /= sample.Count; gb /= sample.Count;

            // define the function to zero
            Func <IReadOnlyList <double>, IReadOnlyList <double> > f = delegate(IReadOnlyList <double> x) {
                double pab = AdvancedMath.Psi(x[0] + x[1]);
                return(new double[] {
                    AdvancedMath.Psi(x[0]) - pab - ga,
                    AdvancedMath.Psi(x[1]) - pab - gb
                });
            };

            // guess initial values using the method of moments
            //   M1 = \frac{\alpha}{\alpha+\beta} C2 = \frac{\alpha\beta}{(\alpha+\beta)^2 (\alpha+\beta+1)}
            // implies
            //   \alpha = M1 \left( \frac{M1 (1-M1)}{C2} - 1 \right)
            //   \beta = (1 - M1) \left( \frac{M1 (1-M1)}{C2} -1 \right)
            int    n;
            double m, v;

            ComputeMomentsUpToSecond(sample, out n, out m, out v);
            v = v / n;

            double mm = 1.0 - m;
            double q  = m * mm / v - 1.0;

            double[] x0 = new double[] { m *q, mm *q };

            // find the parameter values that zero the two equations
            ColumnVector ab = MultiFunctionMath.FindZero(f, x0);
            double       a = ab[0]; double b = ab[1];

            // take more derivatives of \log L to get curvature matrix
            //   \frac{\partial^2 \log L}{\partial\alpha^2} = - N \left[ \psi'(\alpha) - \psi'(\alpha+\beta) \right]
            //   \frac{\partial^2 \log L}{\partial\beta^2}  = - N \left[ \psi'(\beta)  - \psi'(\alpha+\beta) \right]
            //   \frac{\partial^2 \log L}{\partial \alpha \partial \beta} = - N \psi'(\alpha+\beta)
            // covariance matrix is inverse of curvature matrix
            SymmetricMatrix C = new SymmetricMatrix(2);
            C[0, 0] = sample.Count * (AdvancedMath.Psi(1, a) - AdvancedMath.Psi(1, a + b));
            C[1, 1] = sample.Count * (AdvancedMath.Psi(1, b) - AdvancedMath.Psi(1, a + b));
            C[0, 1] = sample.Count * AdvancedMath.Psi(1, a + b);
            CholeskyDecomposition CD = C.CholeskyDecomposition();
            if (CD == null)
            {
                throw new DivideByZeroException();
            }
            C = CD.Inverse();

            // do a KS test on the result
            BetaDistribution distribution = new BetaDistribution(a, b);
            TestResult       test         = sample.KolmogorovSmirnovTest(distribution);

            return(new BetaFitResult(ab, C, distribution, test));
        }
예제 #20
0
        /// <summary>
        /// Computes the Weibull distribution that best fits the given sample.
        /// </summary>
        /// <param name="sample">The sample to fit.</param>
        /// <returns>The best fit parameters.</returns>
        /// <remarks>
        /// <para>The returned fit parameters are the <see cref="ShapeParameter"/> and <see cref="ScaleParameter"/>, in that order.
        /// These are the same parameters, in the same order, that are required by the <see cref="WeibullDistribution(double,double)"/> constructor to
        /// specify a new Weibull distribution.</para>
        /// </remarks>
        /// <exception cref="ArgumentNullException"><paramref name="sample"/> is null.</exception>
        /// <exception cref="InvalidOperationException"><paramref name="sample"/> contains non-positive values.</exception>
        /// <exception cref="InsufficientDataException"><paramref name="sample"/> contains fewer than three values.</exception>
        public static FitResult FitToSample(Sample sample)
        {
            if (sample == null)
            {
                throw new ArgumentNullException("sample");
            }
            if (sample.Count < 3)
            {
                throw new InsufficientDataException();
            }
            if (sample.Minimum <= 0.0)
            {
                throw new InvalidOperationException();
            }

            // The log likelyhood function is
            //   \log L = N \log k + (k-1) \sum_i \log x_i - N K \log \lambda - \sum_i \left(\frac{x_i}{\lambda}\right)^k
            // Taking derivatives, we get
            //   \frac{\partial \log L}{\partial \lambda} = - \frac{N k}{\lambda} + \sum_i \frac{k}{\lambda} \left(\frac{x_i}{\lambda}\right)^k
            //   \frac{\partial \log L}{\partial k} =\frac{N}{k} + \sum_i \left[ 1 - \left(\frac{x_i}{\lambda}\right)^k \right] \log \left(\frac{x_i}{\lambda}\right)
            // Setting the first expression to zero and solving for \lambda gives
            //   \lambda = \left( N^{-1} \sum_i x_i^k \right)^{1/k} = ( < x^k > )^{1/k}
            // which allows us to reduce the problem from 2D to 1D.
            // By the way, using the expression for the moment < x^k > of the Weibull distribution, you can show there is
            // no bias to this result even for finite samples.
            // Setting the second expression to zero gives
            //   \frac{1}{k} = \frac{1}{N} \sum_i \left[ \left( \frac{x_i}{\lambda} \right)^k - 1 \right] \log \left(\frac{x_i}{\lambda}\right)
            // which, given the equation for \lambda as a function of k derived from the first expression, is an implicit equation for k.
            // It cannot be solved in closed form, but we have now reduced our problem to finding a root in one-dimension.

            // We need a starting guess for k.
            // The method of moments equations are not solvable for the parameters in closed form
            // but the scale parameter drops out of the ratio of the 1/3 and 2/3 quantile points
            // and the result is easily solved for the shape parameter
            //   k = \frac{\log 2}{\log\left(\frac{x_{2/3}}{x_{1/3}}\right)}
            double x1 = sample.InverseLeftProbability(1.0 / 3.0);
            double x2 = sample.InverseLeftProbability(2.0 / 3.0);
            double k0 = Global.LogTwo / Math.Log(x2 / x1);
            // Given the shape paramter, we could invert the expression for the mean to get
            // the scale parameter, but since we have an expression for \lambda from k, we
            // dont' need it.
            //double s0 = sample.Mean / AdvancedMath.Gamma(1.0 + 1.0 / k0);

            // Simply handing our 1D function to a root-finder works fine until we start to encounter large k. For large k,
            // even just computing \lambda goes wrong because we are taking x_i^k which overflows. Horst Rinne, "The Weibull
            // Distribution: A Handbook" describes a way out. Basically, we first move to variables z_i = \log(x_i) and
            // then w_i = z_i - \bar{z}. Then lots of factors of e^{k \bar{z}} cancel out and, even though we still do
            // have some e^{k w_i}, the w_i are small and centered around 0 instead of large and centered around \lambda.

            Sample transformedSample = sample.Copy();

            transformedSample.Transform(x => Math.Log(x));
            double zbar = transformedSample.Mean;

            transformedSample.Transform(z => z - zbar);

            // After this change of variable the 1D function to zero becomes
            //   g(k) = \sum_i ( 1 - k w_i ) e^{k w_i}
            // It's easy to show that g(0) = n and g(\infinity) = -\infinity, so it must cross zero. It's also easy to take
            // a derivative
            //   g'(k) = - k \sum_i w_i^2 e^{k w_i}
            // so we can apply Newton's method.

            int    i  = 0;
            double k1 = k0;

            while (true)
            {
                i++;
                double g  = 0.0;
                double gp = 0.0;
                foreach (double w in transformedSample)
                {
                    double e = Math.Exp(k1 * w);
                    g  += (1.0 - k1 * w) * e;
                    gp -= k1 * w * w * e;
                }
                double dk = -g / gp;
                k1 += dk;
                if (Math.Abs(dk) <= Global.Accuracy * Math.Abs(k1))
                {
                    break;
                }
                if (i >= Global.SeriesMax)
                {
                    throw new NonconvergenceException();
                }
            }

            // The corresponding lambda can also be expressed in terms of zbar and w's.

            double t = 0.0;

            foreach (double w in transformedSample)
            {
                t += Math.Exp(k1 * w);
            }
            t /= transformedSample.Count;
            double lambda1 = Math.Exp(zbar) * Math.Pow(t, 1.0 / k1);

            // We need the curvature matrix at the minimum of our log likelyhood function
            // to determine the covariance matrix. Taking more derivatives...
            //    \frac{\partial^2 \log L} = \frac{N k}{\lambda^2} - \sum_i \frac{k(k+1) x_i^k}{\lambda^{k+2}}
            //    = - \frac{N k^2}{\lambda^2}
            // The second expression follows by inserting the first-derivative-equal-zero relation into the first.
            // For k=1, this agrees with the variance formula for the mean of the best-fit exponential.

            // Derivatives involving k are less simple.

            // We end up needing the means < (x/lambda)^k log(x/lambda) > and < (x/lambda)^k log^2(x/lambda) >

            double mpl = 0.0; double mpl2 = 0.0;

            foreach (double x in sample)
            {
                double r   = x / lambda1;
                double p   = Math.Pow(r, k1);
                double l   = Math.Log(r);
                double pl  = p * l;
                double pl2 = pl * l;
                mpl  += pl;
                mpl2 += pl2;
            }
            mpl  = mpl / sample.Count;
            mpl2 = mpl2 / sample.Count;

            // See if we can't do any better here. Transforming to zbar and w's looked ugly, but perhaps it
            // can be simplified? One interesting observation: if we take expectation values (which gives
            // the Fisher information matrix) the entries become simple:
            //   B_{\lambda \lambda} = \frac{N k^2}{\lambda^2}
            //   B_{\lambda k} = -\Gamma'(2) \frac{N}{\lambda}
            //   B_{k k } = [1 + \Gamma''(2)] \frac{N}{k^2}
            // Would it be bad to just use these directly?

            // Construct the curvature matrix and invert it.
            SymmetricMatrix B = new SymmetricMatrix(2);

            B[0, 0] = sample.Count * MoreMath.Sqr(k1 / lambda1);
            B[0, 1] = -sample.Count * k1 / lambda1 * mpl;
            B[1, 1] = sample.Count * (1.0 / MoreMath.Pow2(k1) + mpl2);
            SymmetricMatrix C = B.CholeskyDecomposition().Inverse();

            // Do a KS test to compare sample to best-fit distribution
            Distribution distribution = new WeibullDistribution(lambda1, k1);
            TestResult   test         = sample.KolmogorovSmirnovTest(distribution);

            // return the result
            return(new FitResult(new double[] { lambda1, k1 }, C, test));
        }
예제 #21
0
        public void TestCorrelatedSimulation()//for Hybrid Methode
        {
            StreamWriter Z_text  = new StreamWriter("C:\\Users\\Marouane\\Desktop\\M2IF\\rough volatility\\FileZ.txt");
            StreamWriter Z1_text = new StreamWriter("C:\\Users\\Marouane\\Desktop\\M2IF\\rough volatility\\FileZ1.txt");
            StreamWriter Z2_text = new StreamWriter("C:\\Users\\Marouane\\Desktop\\M2IF\\rough volatility\\FileZ2.txt");

            rBergomiVIXfuture model = new rBergomiVIXfuture();
            int    n    = 500;
            double T    = 0.5;
            Grid   grid = new Grid(0, T, (int)Math.Abs(T * n));

            //Correl
            SymmetricMatrix correl = model.MakeCorrel(n, grid);

            SquareMatrix choleskyCorrel = correl.CholeskyDecomposition().SquareRootMatrix();

            //Gaussian Simulator
            var    simulator = new GaussianSimulator();
            double mc        = 1.0E5;

            ColumnVector Z_test   = new ColumnVector((int)mc);
            ColumnVector Z_test_1 = new ColumnVector((int)mc);
            ColumnVector Z_test_2 = new ColumnVector((int)mc);
            ColumnVector G        = new ColumnVector((int)mc);

            for (int i = 1; i <= mc; i++)
            {
                DoubleVector      Z   = new DoubleVector(grid.get_timeNmbrStep());
                RectangularMatrix Z_k = new RectangularMatrix(2, grid.get_timeNmbrStep());

                HybridScheme hybridscheme = new HybridScheme(choleskyCorrel, grid, 2, 0.07);

                hybridscheme.SimulateCorrelated(Z, Z_k);//Simulate 3 Correlated Gaussians Z_i; Z_k_{1,i}; Z_k_{2,i}  i:= 0, ..., n_T
                int mid = (int)grid.get_timeNmbrStep() / 2;

                G[i - 1] = simulator.Next();

                Z_test[i - 1]   = Z[mid];
                Z_test_1[i - 1] = Z_k[0, mid];
                Z_test_2[i - 1] = Z_k[1, mid];

                string Ztext_  = "";
                string Ztext1_ = "";
                string Ztext2_ = "";
                for (int k = 0; k < Z.RowCount; k++)
                {
                    Ztext_  += (Z[k].ToString() + "; ");
                    Ztext1_ += (Z_k[0, k].ToString() + "; ");
                    Ztext2_ += (Z_k[1, k].ToString() + "; ");
                }
                Z_text.WriteLine(Ztext_);
                Z1_text.WriteLine(Ztext1_);
                Z2_text.WriteLine(Ztext2_);
            }

            Z_text.Close();
            Z1_text.Close();
            Z2_text.Close();

            BivariateSample mybivariate = new BivariateSample();

            mybivariate.Add(Z_test, Z_test_2);

            double correlcoef = mybivariate.CorrelationCoefficient;
            double correlreal = correl[2, 0];

            Sample mysample = new Sample(Z_test);
            double mean     = mysample.Mean;     //must be =0
            double variance = mysample.Variance; //must be =1/n
            var    result   = mysample.KolmogorovSmirnovTest(new NormalDistribution());

            Sample mysampleG = new Sample(G);
            var    result2   = mysampleG.KolmogorovSmirnovTest(new NormalDistribution());
        }
예제 #22
0
        public double VIXfuture_TruncatedChlsky(double T, Func <double, double> epsilon)
        {
            DateTime start = DateTime.Now;
            //StreamWriter sw = new StreamWriter("C:\\Users\\Marouane\\Desktop\\M2IF\\rough volatility\\rBergomiFile.txt");
            //Grid
            int  N    = 100;
            int  S    = 7;
            Grid grid = new Grid(T, T + Delta, N);

            #region  Correlation "Correl Matrix Construction"
            // Small Covariance Matrix t_0 , ... , t_7
            SymmetricMatrix covM_Small = new SymmetricMatrix(S);
            //the full Covariance Matrix
            SymmetricMatrix covM = new SymmetricMatrix(N + 1);
            //Setting for integrale approximations
            EvaluationSettings settings = new EvaluationSettings();
            settings.AbsolutePrecision = 1.0E-7;
            settings.RelativePrecision = 0.0;

            // Small Covariance Calcul t_0,.....,t_7
            for (int i = 0; i < S; i++)
            {
                covM_Small[i, i] = (Math.Pow(grid.t(i), 2 * H) - Math.Pow(grid.t(i) - T, 2 * H)) / (2 * H);
                for (int j = 0; j < i; j++)
                {
                    Func <double, double> covfunc     = t => Math.Pow((grid.t(j) - t) * (grid.t(i) - t), H - 0.5);
                    IntegrationResult     integresult = FunctionMath.Integrate(covfunc, Meta.Numerics.Interval.FromEndpoints(0.0, T), settings);
                    covM_Small[i, j] = integresult.Value;
                }
            }
            // full COrrelation Calcul
            for (int i = 0; i <= N; i++)
            {
                covM[i, i] = (Math.Pow(grid.t(i), 2 * H) - Math.Pow(grid.t(i) - T, 2 * H)) / (2 * H);
                for (int j = 0; j < i; j++)
                {
                    Func <double, double> covfunc     = t => Math.Pow((grid.t(j) - t) * (grid.t(i) - t), H - 0.5);
                    IntegrationResult     integresult = FunctionMath.Integrate(covfunc, Meta.Numerics.Interval.FromEndpoints(0.0, T), settings);
                    covM[i, j] = integresult.Value;
                }
            }

            Func <int, int, double> corrf_Small  = (i, j) => covM_Small[i, j] / (Math.Sqrt(covM_Small[i, i] * covM_Small[j, j]));
            SymmetricMatrix         Correl_Small = new SymmetricMatrix(S);
            Correl_Small.Fill(corrf_Small);

            Func <int, int, double> corrf  = (i, j) => covM[i, j] / (Math.Sqrt(covM[i, i] * covM[j, j]));
            SymmetricMatrix         Correl = new SymmetricMatrix(N + 1);
            Correl.Fill(corrf);
            #endregion

            CholeskyDecomposition cholesky             = Correl_Small.CholeskyDecomposition();
            SquareMatrix          choleskyCorrel_Small = new SquareMatrix(S);
            choleskyCorrel_Small = cholesky.SquareRootMatrix();

            GaussianSimulator simulator = new GaussianSimulator();
            double            VIX       = 0.0;
            var MC = 1.0E5;
            for (int mc = 1; mc < MC; mc++)
            {
                ColumnVector GaussianVector = new ColumnVector(S);
                // Simulating Volterra at 8 first steps on [T, T+Delta]
                for (int i = 0; i < S; i++)
                {
                    GaussianVector[i] = simulator.Next();
                }
                ColumnVector Volterra_small = choleskyCorrel_Small * GaussianVector;
                //Adjusting the variance of Volterra Processus
                for (int i = 0; i < S; i++)
                {
                    Volterra_small[i] = Volterra_small[i] * Math.Sqrt((Math.Pow(grid.t(i), 2 * H) - Math.Pow(grid.t(i) - grid.t(0), 2 * H)) / (2 * H));
                }

                // Simulating VOlterra on t_8 ... t_N with the truncated Formula
                double[] Volterra = new double[N + 1];
                for (int i = 0; i <= N; i++)
                {
                    if (i < S)
                    {
                        Volterra[i] = Volterra_small[i];
                    }
                    //Tranceted Formula
                    else
                    {
                        Volterra[i] = Math.Sqrt(covM[i, i]) * (Correl[i, i - 1] * Volterra[i - 1] / Math.Sqrt(covM[i - 1, i - 1]) + Math.Sqrt(1 - Math.Pow(Correl[i, i - 1], 2)) * simulator.Next());
                    }
                }

                double VIX_ = VIX_Calculate(epsilon, grid, Volterra);
                VIX += VIX_;
            }
            //sw.Close();
            VIX /= MC;
            TimeSpan dur = DateTime.Now - start;
            return(VIX);
        }
        // We need a goodness-of-fit measurement

        internal LinearLogisticRegressionResult(IReadOnlyList <double> x, IReadOnlyList <bool> y)
        {
            Debug.Assert(x != null);
            Debug.Assert(y != null);
            Debug.Assert(x.Count == y.Count);

            // check size of data set
            int n = x.Count;

            if (n < 3)
            {
                throw new InsufficientDataException();
            }

            // The linear logistic model is:
            //   p_i = \sigma(t_i) \quad t_i = a + b x_i
            // So the log likelihood of the data set under the model is:
            //   \ln L = \sum_{{\rm true} i} \ln p_i + \sum_{{\rm false} i} \ln (1 - p_i)
            //         = \sum_{{\rm true} i} \ln \sigma(t_i) + \sum_{{\rm false} i} \ln (1 - \sigma(t_i))
            // Taking derivatives:
            //   \frac{\partial L}{\partial a} = \sum_{{\rm true} i} \frac{\sigma'(t_i)}{\sigma(t_i)}
            //     + \sum_{{\rm false} i} \frac{-\sigma'(t_i)}{1 - \sigma(t_i)}
            //   \frac{\partial L}{\partial b} = \sum_{{\rm true} i} \frac{\sigma'(t_i)}{\sigma(t_i)} x_i
            //     + \sum_{{\rm false} i} \frac{-\sigma'(t_i)}{1 - \sigma(t_i)} x_i
            // Using \sigma(t) = \frac{1}{1 + e^{-t}}, we can derive:
            //   \frac{\sigma'(t)}{\sigma(t)} = \sigma(-t)
            //   \frac{\sigma'(t)}{1 - \sigma(t)} = \sigma(t)
            // So this becomes
            //   \frac{\partial L}{\partial a} = \sum_i \pm \sigma(\mp t_i)
            //   \frac{\partial L}{\partial b} = \sum_i \pm \sigma(\mp t_i) x_i
            // where the upper sign is for true values and the lower sign is for false values.
            // Find the simultaneous zeros of these equations to obtain the likelihood-maximizing a, b.

            // To get the curvature matrix, we need the second derivatives.
            //   \frac{\partial^2 L}{\partial a^2} = - \sum_i \sigma'(\mp t_i)
            //   \frac{\partial^2 L}{\partial a \partial b} = - \sum_i \sigma'(\mp t_i) x_i
            //   \frac{\partial^2 L}{\partial b^2} = - \sum_i \sigma'(\mp t_i) x_i^2

            // We need an initial guess at the parameters. Begin with the Ansatz of the logistic model:
            //    \frac{p}{1-p} = e^{\alpha + \beta x}
            // Differentiate and do some algebra to get:
            //    \frac{\partial p}{\partial x} = \beta p ( 1 - p)
            // Evaluating at means, and noting that p (1 - p) = var(y) and that, in a development around the means,
            //    cov(p, x) = \frac{\partial p}{\partial x} var(x)
            // we get
            //    \beta = \frac{cov(y, x)}{var(x) var(y)}
            // This approximation gets the sign right, but it looks like it usually gets the magnitude quite wrong.
            // The problem with the approach is that var(y) = p (1 - p) assumes y are chosen with fixed p, but they aren't.
            // We need to re-visit this analysis.

            double xMean, yMean, xxSum, yySum, xySum;

            Bivariate.ComputeBivariateMomentsUpToTwo(x, y.Select(z => z ? 1.0 : 0.0), out n, out xMean, out yMean, out xxSum, out yySum, out xySum);
            double p  = yMean;
            double b0 = xySum / xxSum / yySum * n;
            double a0 = Math.Log(p / (1.0 - p)) - b0 * xMean;

            Func <IReadOnlyList <double>, IReadOnlyList <double> > J = (IReadOnlyList <double> a) => {
                double dLda = 0.0;
                double dLdb = 0.0;
                for (int i = 0; i < n; i++)
                {
                    double t = a[0] + a[1] * x[i];
                    if (y[i])
                    {
                        double s = Sigma(-t);
                        dLda += s;
                        dLdb += s * x[i];
                    }
                    else
                    {
                        double s = Sigma(t);
                        dLda -= s;
                        dLdb -= s * x[i];
                    }
                }
                return(new double[] { dLda, dLdb });
            };

            ColumnVector b = MultiFunctionMath.FindZero(J, new double[] { a0, b0 });

            SymmetricMatrix C = new SymmetricMatrix(2);

            for (int i = 0; i < n; i++)
            {
                double t = b[0] + b[1] * x[i];
                if (y[i])
                {
                    t = -t;
                }
                double e  = Math.Exp(-t);
                double sp = e / MoreMath.Sqr(1.0 + e);
                C[0, 0] += sp;
                C[0, 1] += sp * x[i];
                C[1, 1] += sp * x[i] * x[i];
            }
            CholeskyDecomposition CD = C.CholeskyDecomposition();

            if (CD == null)
            {
                throw new DivideByZeroException();
            }
            C = CD.Inverse();

            best       = b;
            covariance = C;
        }