Inheritance: ICloneable, ISolverDecomposition
        public void CholeskyDecompositionConstructorTest()
        {
            // Based on tests by Ken Johnson

            double[,] value = // positive-definite
            {
               {  2, -1,  0 },
               { -1,  2, -1 },
               {  0, -1,  2 }
            };

            double[,] expected =
            {
                {  1.4142,  0.0000, 0.0000 },
                { -0.7071,  1.2247, 0.0000 },
                {  0.0000, -0.8165, 1.1547 }
            };


            CholeskyDecomposition chol = new CholeskyDecomposition(value);
            double[,] L = chol.LeftTriangularFactor;

            Assert.IsTrue(Matrix.IsEqual(L, expected, 0.0001));

            // Decomposition Identity
            Assert.IsTrue(Matrix.IsEqual(L.Multiply(L.Transpose()), value, 0.001));

            Assert.AreEqual(new LuDecomposition(value).Determinant, chol.Determinant, 1e-10);
            Assert.AreEqual(true, chol.PositiveDefinite);
            Assert.AreEqual(true, chol.Symmetric);
        }
Esempio n. 2
0
        /// <summary>
        ///   Constructs a multivariate Gaussian distribution
        ///   with given mean vector and covariance matrix.
        /// </summary>
        public NormalDistribution(double[] mean, double[,] covariance)
            : base(mean.Length)
        {
            int k = mean.Length;

            this.mean = mean;
            this.covariance = covariance;
            variance = covariance.Diagonal();

            double detSqrt = System.Math.Sqrt(System.Math.Abs(covariance.Determinant()));
            constant = 1.0/(System.Math.Pow(2.0*System.Math.PI, k/2.0)*detSqrt);

            chol = new CholeskyDecomposition(covariance, true);

            if (chol.Determinant == 0)
            {
                // The covariance matrix is singular, use pseudo-inverse
                svd = new SingularValueDecomposition(covariance);
            }
        }
        public void InverseTestNaN()
        {
            int n = 5;

            var I = Matrix.Identity(n);

            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    double[,] value = Matrix.Magic(n);

                    // Make symmetric
                    value = Matrix.Multiply(value, value.Transpose());

                    value[i, j] = double.NaN;
                    value[j, i] = double.NaN;

                    Assert.IsTrue(value.IsSymmetric());

                    bool thrown = false;

                    var target = new CholeskyDecomposition(value);

                    try
                    {
                        target.Solve(I);
                    }
                    catch (Exception)
                    {
                        thrown = true;
                    }

                    Assert.IsTrue(thrown);
                }
            }
        }
        public void SolveTest2()
        {
            double[,] value = // not positive-definite
            {
               {  6, -1,  2,  6 },
               { -1,  3, -3, -2 },
               {  2, -3,  2,  0 },
               {  6, -2,  0,  0 },
            };

            CholeskyDecomposition chol = new CholeskyDecomposition(value, true);
            double[,] L = chol.LeftTriangularFactor;

            double[,] B = Matrix.Identity(4);

            double[,] expected = 
            {
                { 0.4000,    1.2000,    1.4000,   -0.5000 },
                { 1.2000,    3.6000,    4.2000,   -2.0000 },
                { 1.4000,    4.2000,    5.4000,   -2.5000 },
                { -0.5000,  -2.0000,   -2.5000,    1.0000 }, 
            };
            double[,] actual = chol.Solve(B);

            Assert.IsTrue(Matrix.IsEqual(expected, actual, 0.0000000000001));
        }
        public void SolveTest4()
        {
            double[,] value = // not positive-definite
            {
               {  6, -1,  2,  6 },
               { -1,  3, -3, -2 },
               {  2, -3,  2,  0 },
               {  6, -2,  0,  0 },
            };

            CholeskyDecomposition chol = new CholeskyDecomposition(value, true);
            double[,] L = chol.LeftTriangularFactor;

            double[] B = new double[] { 1, 2, 3, 4 };

            double[] expected = { 5, 13, 16, -8 };
            double[] actual = chol.Solve(B);

            Assert.IsTrue(Matrix.IsEqual(expected, actual, 0.0000000000001));
        }
Esempio n. 6
0
 /// <summary>Cholesky decomposition.</summary>
 protected static double[,] chol(double[,] a)
 {
     var chol = new CholeskyDecomposition(a);
     return chol.LeftTriangularFactor;
 }
        private void initialize(double[] m, double[,] cov, CholeskyDecomposition cd)
        {
            int k = m.Length;

            this.mean = m;
            this.covariance = cov;
            this.chol = cd;
            this.invCovariance = covariance.Inverse();

            // Original code:
            //   double det = chol.Determinant;
            //   double detSqrt = System.Math.Sqrt(System.Math.Abs(det));
            //   constant = 1.0 / (System.Math.Pow(2.0 * System.Math.PI, k / 2.0) * detSqrt);

            // Transforming to log operations, we have:
            double lndet = cd.LogDeterminant;

            // Let lndet = log( abs(det) )
            //
            //    detSqrt = sqrt(abs(det)) = sqrt(abs(exp(log(det)))
            //            = sqrt(exp(log(abs(det))) = sqrt(exp(lndet)
            //
            //    log(detSqrt) = log(sqrt(exp(lndet)) = (1/2)*log(exp(lndet))
            //                 = lndet/2.
            //
            //
            // Let lndetsqrt = log(detsqrt) = lndet/2
            //
            //     constant      =       1 / ( ((2PI)^(k/2)) * detSqrt)
            //
            //     log(constant) =  log( 1 / ( ((2PI)^(k/2)) * detSqrt) )
            //                   =  log(1)-log(((2PI)^(k/2)) * detSqrt) )
            //                   = -log(       ((2PI)^(k/2)) * detSqrt) )
            //                   = -log(       ((2PI)^(k/2)) * exp(log(detSqrt))))
            //                   = -log(       ((2PI)^(k/2)) * exp(lndetsqrt)))
            //                   = -log(       ((2PI)^(k/2)) * exp(lndet/2)))
            //                   = -log(       ((2PI)^(k/2))) - log(exp(lndet/2)))
            //                   = -log(       ((2PI)^(k/2))) - lndet/2)
            //                   = -log(         2PI) * (k/2) - lndet/2)
            //                   =(-log(         2PI) *  k    - lndet  ) / 2
            //                   =-(log(         2PI) *  k    + lndet  ) / 2
            //                   =-(log(         2PI) *  k    + lndet  ) / 2
            //                   =-(     LN2PI        *  k    + lndet  ) / 2
            //

            // So the log(constant) could be computed as:
            lnconstant = -(Special.Log2PI * k + lndet) * 0.5;
        }
        /// <summary>
        ///   Constructs a multivariate Gaussian distribution
        ///   with given mean vector and covariance matrix.
        /// </summary>
        /// 
        /// <param name="mean">The mean of the distribution.</param>
        /// <param name="covariance">The covariance for the distribution.</param>
        /// 
        public MultivariateNormalDistribution(double[] mean, double[,] covariance)
            : base(mean.Length)
        {
            int rows = covariance.GetLength(0);
            int cols = covariance.GetLength(1);

            if (rows != cols)
                throw new DimensionMismatchException("covariance", "Covariance matrix should be square.");

            if (mean.Length != rows)
                throw new DimensionMismatchException("covariance", "Covariance matrix should have the same dimensions as mean vector's length.");

            CholeskyDecomposition chol = new CholeskyDecomposition(covariance, false, true);

            if (!chol.PositiveDefinite)
                throw new NonPositiveDefiniteMatrixException("Covariance matrix is not positive definite.");

            initialize(mean, covariance, chol);
        }
        /// <summary>
        ///   Gets the probability density function (pdf) for
        ///   this distribution evaluated at point <c>x</c>.
        /// </summary>
        /// 
        /// <param name="x">A single point in the distribution range.
        ///   For a matrix distribution, such as the Wishart's, this
        ///   should be a positive-definite matrix or a matrix written
        ///   in flat vector form.
        /// </param>
        ///   
        /// <returns>
        ///   The probability of <c>x</c> occurring
        ///   in the current distribution.
        /// </returns>
        /// 
        /// <remarks>
        ///   The Probability Density Function (PDF) describes the
        ///   probability that a given value <c>x</c> will occur.
        /// </remarks>
        /// 
        public double ProbabilityDensityFunction(double[,] x)
        {
            var chol = new CholeskyDecomposition(x);

            double det = chol.Determinant;
            double[,] Vx = chol.Solve(inverseScaleMatrix);

            double z = -0.5 * Vx.Trace();
            double a = Math.Pow(det, power);
            double b = Math.Exp(z);

            return constant * a * b;
        }
        public void InverseTest1()
        {
            double[,] value = // positive-definite
            {
                {  2, -1,  0 },
                { -1,  2, -1 },
                {  0, -1,  2 }
            };

            var chol = new CholeskyDecomposition(value, robust: false);
            Assert.IsTrue(chol.IsPositiveDefinite);
            var L = chol.LeftTriangularFactor;

            float[][] expected =
            {
                new float[] { 0.750f, 0.500f, 0.250f },
                new float[] { 0.500f, 1.000f, 0.500f },
                new float[] { 0.250f, 0.500f, 0.750f },
            };

            double[,] actual = chol.Inverse();
            Assert.IsTrue(actual.IsEqual(expected, 1e-6));

            double[,] inv = chol.Solve(Matrix.Identity(3));
            Assert.IsTrue(inv.IsEqual(expected, 1e-6));
        }
        public void CholeskyDecompositionConstructorTest3()
        {
            double[,] value = // not positive-definite
            {
               {  6, -1,  2,  6 },
               { -1,  3, -3, -2 },
               {  2, -3,  2,  0 },
               {  6, -2,  0,  0 },
            };

            double[,] expected =
            {
                {  1.0000,         0,         0,         0 },
                { -0.1667,    1.0000,         0,         0 },
                {  0.3333,   -0.9412,    1.0000,         0 },
                {  1.0000,   -0.3529,    2.5000,    1.0000 },
            };

            double[,] diagonal =
            {
                { 6.0000,         0,         0,         0 },
                {      0,    2.8333,         0,         0 },
                {      0,         0,   -1.1765,         0 },
                {      0,         0,         0,    1.0000 },
            };

            CholeskyDecomposition chol = new CholeskyDecomposition(value, true);
            double[,] L = chol.LeftTriangularFactor;
            double[,] D = chol.DiagonalMatrix;
            Assert.IsTrue(Matrix.IsEqual(L, expected, 0.001));
            Assert.IsTrue(Matrix.IsEqual(D, diagonal, 0.001));

            // Decomposition Identity
            Assert.IsTrue(Matrix.IsEqual(L.Multiply(D).Multiply(L.Transpose()), value, 0.001));

            Assert.AreEqual(new LuDecomposition(value).Determinant, chol.Determinant, 1e-10);
            Assert.AreEqual(false, chol.PositiveDefinite);
            Assert.AreEqual(true, chol.Symmetric);

        }
        public void SolveTest()
        {
            double[,] value = // positive-definite
            {
               {  2, -1,  0 },
               { -1,  2, -1 },
               {  0, -1,  2 }
            };

            CholeskyDecomposition chol = new CholeskyDecomposition(value);
            double[,] L = chol.LeftTriangularFactor;

            double[,] B = Matrix.ColumnVector(new double[] { 1, 2, 3 });

            double[,] expected = Matrix.ColumnVector(new double[] { 2.5, 4.0, 3.5 });

            double[,] actual = chol.Solve(B);
            Assert.IsTrue(Matrix.IsEqual(expected, actual, 1e-10));
            Assert.AreNotEqual(actual, B);

            actual = chol.Solve(B, true);
            Assert.AreEqual(actual, B);
            Assert.IsTrue(Matrix.IsEqual(expected, B, 1e-10));

            Assert.IsTrue(Matrix.IsEqual(chol.Reverse(), value, 1e-6));
        }
        public void InverseTest()
        {
            double[,] value = // not positive-definite
            {
               {  6, -1,  2,  6 },
               { -1,  3, -3, -2 },
               {  2, -3,  2,  0 },
               {  6, -2,  0,  0 },
            };

            double[,] expected =
            {
                  {  0.40000,  1.20000,  1.40000, -0.50000 },
                  {  1.20000,  3.60000,  4.20000, -2.00000 },
                  {  1.40000,  4.20000,  5.40000, -2.50000 },
                  { -0.50000, -2.00000, -2.50000,  1.00000 },
            };

            var chol = new CholeskyDecomposition(value, robust: true);
            double[,] L = chol.LeftTriangularFactor;
            Assert.IsFalse(chol.IsPositiveDefinite);

            double[,] actual = chol.Inverse();
            Assert.IsTrue(Matrix.IsEqual(expected, actual, 1e-6));

            double[,] inv = Matrix.Inverse(value);
            Assert.IsTrue(Matrix.IsEqual(expected, inv, 1e-10));

            Assert.IsTrue(Matrix.IsEqual(chol.Reverse(), value, 1e-6));
        }
 /// <summary>
 ///   Creates a new object that is a copy of the current instance.
 /// </summary>
 /// <returns>
 ///   A new object that is a copy of this instance.
 /// </returns>
 /// 
 public object Clone()
 {
     var clone = new CholeskyDecomposition();
     clone.L = (double[,])L.Clone();
     clone.D = (double[])D.Clone();
     clone.n = n;
     clone.robust = robust;
     clone.positiveDefinite = positiveDefinite;
     clone.symmetric = symmetric;
     return clone;
 }
        /// <summary>
        ///   Creates a new Cholesky decomposition directly from
        ///   an already computed left triangular matrix <c>L</c>.
        /// </summary>
        /// <param name="leftTriangular">The left triangular matrix from a Cholesky decomposition.</param>
        /// 
        public static CholeskyDecomposition FromLeftTriangularMatrix(double[,] leftTriangular)
        {
            CholeskyDecomposition chol = new CholeskyDecomposition();
            chol.n = leftTriangular.GetLength(0);
            chol.L = leftTriangular;
            chol.symmetric = true;
            chol.positiveDefinite = true;
            chol.robust = false;
            chol.D = Matrix.Vector(chol.n, 1.0);

            return chol;
        }
Esempio n. 16
0
        static void Main(string[] args)
        {
            Console.WriteLine("Please take a look at the source for examples!");
            Console.ReadKey();

            #region 1. Declaring matrices

            // 1.1 Using standard .NET declaration
            double[,] A = 
            {
                {1, 2, 3},
                {6, 2, 0},
                {0, 0, 1}
            };

            double[,] B = 
            {
                {2, 0, 0},
                {0, 2, 0},
                {0, 0, 2}
            };

            {
                // 1.2 Using Accord extension methods
                double[,] Bi = Matrix.Identity(3).Multiply(2);
                double[,] Bj = Matrix.Diagonal(3, 2.0); // both are equal to B

                // 1.2 Using Accord extension methods with implicit typing
                var I = Matrix.Identity(3);
            }
            #endregion



            #region 2. Matrix Operations
            {
                // 2.1 Addition
                var C = A.Add(B);

                // 2.2 Subtraction
                var D = A.Subtract(B);

                // 2.3 Multiplication
                {
                    // 2.3.1 By a scalar
                    var halfM = A.Multiply(0.5);

                    // 2.3.2 By a vector
                    double[] m = A.Multiply(new double[] { 1, 2, 3 });

                    // 2.3.3 By a matrix
                    var M = A.Multiply(B);

                    // 2.4 Transposing
                    var At = A.Transpose();
                }
            }


            // 2.5 Elementwise operations

            // 2.5.1 Elementwise multiplication
            A.ElementwiseMultiply(B); // A.*B

            // 2.5.1 Elementwise division
            A.ElementwiseDivide(B); // A./B

            #endregion



            #region 3. Matrix characteristics
            {
                // 3.1 Calculating the determinant
                double det = A.Determinant();

                // 3.2 Calculating the trace
                double tr = A.Trace();

                // 3.3 Computing the sum vector
                {
                    double[] sumVector = A.Sum();

                    // 3.3.1 Computing the total sum of elements
                    double sum = sumVector.Sum();

                    // 3.3.2 Computing the sum along the rows
                    sumVector = A.Sum(0); // Equivalent to Octave's sum(A, 1)

                    // 3.3.2 Computing the sum along the columns
                    sumVector = A.Sum(1); // Equivalent to Octave's sum(A, 2)
                }
            }
            #endregion



            #region 4. Linear Algebra
            {
                // 4.1 Computing the inverse
                var invA = A.Inverse();

                // 4.2 Computing the pseudo-inverse
                var pinvA = A.PseudoInverse();

                // 4.3 Solving a linear system (Ax = B)
                var x = A.Solve(B);
            }
            #endregion



            #region 5. Special operators
            {
                // 5.1 Finding the indices of elements
                double[] v = { 5, 2, 2, 7, 1, 0 };
                int[] idx = v.Find(e => e > 2); // finding the index of every element in v higher than 2.

                // 5.2 Selecting elements by index
                double[] u = v.Submatrix(idx); // u is { 5, 7 }

                // 5.3 Converting between different matrix representations
                double[][] jaggedA = A.ToArray(); // from multidimensional to jagged array

                // 5.4 Extracting a column or row from the matrix
                double[] a = A.GetColumn(0); // retrieves the first column
                double[] b = B.GetRow(1); // retrieves the second row

                // 5.5 Taking the absolute of a matrix
                var absA = A.Abs();

                // 5.6 Applying some function to every element
                var newv = v.Apply(e => e + 1);
            }
            #endregion



            #region 7. Vector operations
            {
                double[] u = { 1, 2, 3 };
                double[] v = { 4, 5, 6 };

                var w1 = u.InnerProduct(v);
                var w2 = u.OuterProduct(v);
                var w3 = u.CartesianProduct(v);


                double[] m = { 1, 2, 3, 4 };
                double[,] M = Matrix.Reshape(m, 2, 2);
            }
            #endregion


            #region Decompositions
            {
                // Singular value decomposition
                {
                    SingularValueDecomposition svd = new SingularValueDecomposition(A);
                    var U = svd.LeftSingularVectors;
                    var S = svd.Diagonal;
                    var V = svd.RightSingularVectors;
                }
                // or (please see documentation for details)
                {
                    SingularValueDecomposition svd = new SingularValueDecomposition(A.Transpose());
                    var U = svd.RightSingularVectors;
                    var S = svd.Diagonal;
                    var V = svd.LeftSingularVectors;
                }

                // Eigenvalue decomposition
                {
                    EigenvalueDecomposition eig = new EigenvalueDecomposition(A);
                    var V = eig.Eigenvectors;
                    var D = eig.DiagonalMatrix;
                }

                // QR decomposition
                {
                    QrDecomposition qr = new QrDecomposition(A);
                    var Q = qr.OrthogonalFactor;
                    var R = qr.UpperTriangularFactor;
                }

                // Cholesky decomposition
                {
                    CholeskyDecomposition chol = new CholeskyDecomposition(A);
                    var R = chol.LeftTriangularFactor;
                }

                // LU decomposition
                {
                    LuDecomposition lu = new LuDecomposition(A);
                    var L = lu.LowerTriangularFactor;
                    var U = lu.UpperTriangularFactor;
                }

            }
            #endregion

        }
        public void InverseTest()
        {
            double[,] value = // not positive-definite
            {
               {  6, -1,  2,  6 },
               { -1,  3, -3, -2 },
               {  2, -3,  2,  0 },
               {  6, -2,  0,  0 },
            };

            CholeskyDecomposition chol = new CholeskyDecomposition(value, true);
            double[,] L = chol.LeftTriangularFactor;

            double[,] expected = Matrix.Inverse(value);
            double[,] actual = chol.Inverse();

            Assert.IsTrue(Matrix.IsEqual(expected, actual, 1e-10));
        }
        public void LogDeterminantTest()
        {
            CholeskyDecomposition chol = new CholeskyDecomposition(bigmatrix);
            Assert.AreEqual(0.0, chol.Determinant);
            Assert.AreEqual(-2224.8931093738875, chol.LogDeterminant);
            Assert.IsTrue(chol.PositiveDefinite);
            Assert.IsTrue(chol.Symmetric);
            Assert.IsTrue(chol.Nonsingular);

        }
        public void CholeskyDecompositionConstructorTest2()
        {
            double[,] value = // positive-definite
            {
               {  2, -1,  0 },
               { -1,  2, -1 },
               {  0, -1,  2 }
            };


            double[,] expected =
            {
                 {  1.0000,  0.0000,  0.0000 },
                 { -0.5000,  1.0000,  0.0000 },
                 {  0.0000, -0.6667,  1.0000 }
            };

            double[,] diagonal =
            {
                 {  2.0000,  0.0000,  0.0000 },
                 {  0.0000,  1.5000,  0.0000 },
                 {  0.0000,  0.0000,  1.3333 },
            };



            CholeskyDecomposition chol = new CholeskyDecomposition(value, true);
            double[,] L = chol.LeftTriangularFactor;
            double[,] D = chol.DiagonalMatrix;
            Assert.IsTrue(Matrix.IsEqual(L, expected, 0.001));
            Assert.IsTrue(Matrix.IsEqual(D, diagonal, 0.001));

            // Decomposition Identity
            Assert.IsTrue(Matrix.IsEqual(L.Multiply(D).Multiply(L.Transpose()), value, 0.001));

            Assert.AreEqual(new LuDecomposition(value).Determinant, chol.Determinant, 1e-10);
            Assert.AreEqual(true, chol.PositiveDefinite);
            Assert.AreEqual(true, chol.Symmetric);
        }
        public void LogDeterminantTest2()
        {
            double[,] value =
            {
               {  6, -1,  2,  1 },
               { -1,  9, -3, -2 },
               {  2, -3,  8,  1 },
               {  1, -2,  1,  7 },
            };

            CholeskyDecomposition chol = new CholeskyDecomposition(value);
            Assert.AreEqual(2232, chol.Determinant, 1e-12);

            double expected = System.Math.Log(2232);
            double actual = chol.LogDeterminant;

            Assert.AreEqual(expected, actual, 1e-10);
        }
        public void CholeskyDecompositionConstructorTest4()
        {
            // Based on tests by Ken Jhonson

            double[,] value = // positive-definite
            {
               {  2,  0,  0 },
               { -1,  2,  0 },
               {  0, -1,  2 }
            };

            double[,] expected =
            {
                {  1.4142,  0.0000, 0.0000 },
                { -0.7071,  1.2247, 0.0000 },
                {  0.0000, -0.8165, 1.1547 }
            };


            CholeskyDecomposition chol = new CholeskyDecomposition(value, false, true);
            double[,] L = chol.LeftTriangularFactor;

            Assert.IsTrue(Matrix.IsEqual(L, expected, 0.0001));
            Assert.AreEqual(4, chol.Determinant, 1e-10);
            Assert.AreEqual(true, chol.PositiveDefinite);
            Assert.AreEqual(true, chol.Symmetric);


            double[,] expected2 =
            {
                 {  1.0000,  0.0000,  0.0000 },
                 { -0.5000,  1.0000,  0.0000 },
                 {  0.0000, -0.6667,  1.0000 }
            };

            chol = new CholeskyDecomposition(value, true, true);
            L = chol.LeftTriangularFactor;

            Assert.IsTrue(Matrix.IsEqual(L, expected2, 0.0001));
            Assert.AreEqual(4, chol.Determinant, 1e-10);
            Assert.AreEqual(true, chol.PositiveDefinite);
            Assert.AreEqual(true, chol.Symmetric);
        }
        /// <summary>
        ///   Gets the probability density function (pdf) for
        ///   this distribution evaluated at point <c>x</c>.
        /// </summary>
        /// 
        /// <param name="x">A single point in the distribution range.</param>
        /// 
        /// <returns>
        ///   The probability of <c>x</c> occurring
        ///   in the current distribution.
        /// </returns>
        /// 
        /// <remarks>
        ///   The Probability Density Function (PDF) describes the
        ///   probability that a given value <c>x</c> will occur.
        /// </remarks>
        /// 
        public override double ProbabilityDensityFunction(double[] x)
        {
            // http://www.buch-kromann.dk/tine/nonpar/Nonparametric_Density_Estimation_multidim.pdf
            // http://sfb649.wiwi.hu-berlin.de/fedc_homepage/xplore/ebooks/html/spm/spmhtmlnode18.html

            double sum = 0;

            CholeskyDecomposition chol = new CholeskyDecomposition(smoothing);

            double[] delta = new double[Dimension];
            for (int i = 0; i < samples.Length; i++)
            {
                for (int j = 0; j < x.Length; j++)
                    delta[j] = (x[j] - samples[i][j]);

                sum += kernel.Function(chol.Solve(delta));
            }

            return sum / (samples.Length * determinant);
        }
        public void DeterminantTest()
        {
            double[,] value =
            {
               {  6, -1,  2,  1 },
               { -1,  9, -3, -2 },
               {  2, -3,  8,  1 },
               {  1, -2,  1,  7 },
            };

            CholeskyDecomposition chol = new CholeskyDecomposition(value);
            Assert.AreEqual(2232, chol.Determinant, 1e-12);
            Assert.IsTrue(chol.Nonsingular);
            Assert.IsTrue(chol.Symmetric);
        }
        public void CholeskyDecompositionConstructorTest4()
        {
            // Based on tests by Ken Johnson

            double[,] value = // positive-definite
            {
               {  2,  0,  0 },
               { -1,  2,  0 },
               {  0, -1,  2 }
            };

            double[,] expected =
            {
                {  1.4142,  0.0000, 0.0000 },
                { -0.7071,  1.2247, 0.0000 },
                {  0.0000, -0.8165, 1.1547 }
            };


            var chol = new CholeskyDecomposition(value, false, valueType: MatrixType.LowerTriangular);
            double[,] L = chol.LeftTriangularFactor;

            Assert.IsTrue(Matrix.IsEqual(L, expected, 1e-4));
            Assert.AreEqual(4, chol.Determinant, 1e-10);
            Assert.IsTrue(chol.IsPositiveDefinite);
            Assert.IsTrue(Matrix.IsEqual(chol.Reverse(), value.GetSymmetric(type: MatrixType.LowerTriangular), 1e-4));


            double[,] expected2 =
            {
                 {  1.0000,  0.0000,  0.0000 },
                 { -0.5000,  1.0000,  0.0000 },
                 {  0.0000, -0.6667,  1.0000 }
            };

            chol = new CholeskyDecomposition(value, robust: true, valueType: MatrixType.LowerTriangular);
            L = chol.LeftTriangularFactor;

            Assert.IsTrue(Matrix.IsEqual(L, expected2, 1e-4));
            Assert.IsTrue(Matrix.IsEqual(chol.Reverse(), value.GetSymmetric(type: MatrixType.LowerTriangular), 1e-6));
            Assert.IsTrue(chol.IsPositiveDefinite);

            Assert.AreEqual(4, chol.Determinant, 1e-10);
        }
        /// <summary>
        ///   Creates a new Inverse Wishart distribution.
        /// </summary>
        /// 
        /// <param name="degreesOfFreedom">The degrees of freedom v.</param>
        /// <param name="inverseScale">The inverse scale matrix Ψ (psi).</param>
        /// 
        public InverseWishartDistribution(double degreesOfFreedom, double[,] inverseScale)
            : base(inverseScale.Length)
        {

            if (inverseScale.GetLength(0) != inverseScale.GetLength(1))
                throw new DimensionMismatchException("inverseScale", "Matrix must be square.");

            this.inverseScaleMatrix = inverseScale;
            this.size = inverseScale.GetLength(0);
            this.v = degreesOfFreedom;

            if (degreesOfFreedom <= size - 1)
                throw new ArgumentOutOfRangeException("degreesOfFreedom", "Degrees of freedom must be greater "
                + "than or equal to the number of rows in the inverse scale matrix.");

            var chol = new CholeskyDecomposition(inverseScale);

            if (!chol.PositiveDefinite)
                throw new NonPositiveDefiniteMatrixException("scale");
            if (!chol.Symmetric)
                throw new NonSymmetricMatrixException("scale");

            double a = Math.Pow(chol.Determinant, v / 2.0);
            double b = Math.Pow(2, (v * size) / 2.0);
            double c = Gamma.Multivariate(v / 2.0, size);

            this.constant = a / (b * c);
            this.power = -(v + size + 1) / 2.0;
        }
        public void LogDeterminantTest()
        {
            var chol = new CholeskyDecomposition(bigmatrix);
            Assert.AreEqual(0.0, chol.Determinant);
            Assert.AreEqual(-2224.8931093738875, chol.LogDeterminant, 1e-10);
            Assert.IsTrue(chol.IsPositiveDefinite);
            Assert.IsTrue(chol.Nonsingular);

            Assert.IsTrue(Matrix.IsEqual(chol.Reverse(), bigmatrix, 1e-6));
        }
        /// <summary>
        ///   Gets the probability density function (pdf) for
        ///   this distribution evaluated at point <c>x</c>.
        /// </summary>
        /// 
        /// <param name="x">A single point in the distribution range.
        ///   For a matrix distribution, such as the Wishart's, this
        ///   should be a positive-definite matrix or a matrix written
        ///   in flat vector form.
        /// </param>
        ///   
        /// <returns>
        ///   The probability of <c>x</c> occurring
        ///   in the current distribution.
        /// </returns>
        /// 
        /// <remarks>
        ///   The Probability Density Function (PDF) describes the
        ///   probability that a given value <c>x</c> will occur.
        /// </remarks>
        /// 
        public double LogProbabilityDensityFunction(double[,] x)
        {
            var chol = new CholeskyDecomposition(x);

            double det = chol.Determinant;
            double[,] Vx = chol.Solve(inverseScaleMatrix);

            double z = -0.5 * Vx.Trace();

            return Math.Log(constant) + power * Math.Log(det) + z;
        }
        public void DeterminantTest2()
        {
            double[,] value =
            {
               {  6, -1,  2,  1 },
               {  0,  9, -3, -2 },
               {  0,  0,  8,  1 },
               {  0,  0,  0,  7 },
            };

            var chol = new CholeskyDecomposition(value);
            //var L = chol.LeftTriangularFactor;
            //var det = L.Determinant();
            Assert.IsTrue(chol.IsPositiveDefinite);
            Assert.AreEqual(2232, chol.Determinant, 1e-12);
            Assert.IsTrue(chol.Nonsingular);
            //Assert.IsTrue(chol.Symmetric);
        }
Esempio n. 29
0
        /// <summary>
        ///   Creates a new Wishart distribution.
        /// </summary>
        /// 
        /// <param name="degreesOfFreedom">The degrees of freedom n.</param>
        /// <param name="scale">The positive-definite matrix scale matrix V.</param>
        /// 
        public WishartDistribution(double degreesOfFreedom, double[,] scale)
            : base(scale.Length)
        {
            if (scale.GetLength(0) != scale.GetLength(1))
                throw new DimensionMismatchException("scale", "Matrix must be square.");

            this.scaleMatrix = scale;
            this.n = degreesOfFreedom;
            this.size = scale.GetLength(0);

            if (degreesOfFreedom <= size - 1)
                throw new ArgumentOutOfRangeException("degreesOfFreedom", "Degrees of freedom must be greater "
                + "than or equal to the number of rows in the scale matrix.");

            this.chol = new CholeskyDecomposition(scale);

            if (!chol.PositiveDefinite)
                throw new NonPositiveDefiniteMatrixException("scale");
            if (!chol.Symmetric)
                throw new NonSymmetricMatrixException("scale");

            double a = Math.Pow(chol.Determinant, n / 2.0);
            double b = Math.Pow(2, (n * size) / 2.0);
            double c = Gamma.Multivariate(n / 2.0, size);

            this.constant = 1.0 / (a * b * c);
            this.lnconstant = Math.Log(constant);

            this.power = (n - size - 1) / 2.0;
        }
        public void SolveTest3()
        {
            double[,] value = // positive-definite
            {
               {  2, -1,  0 },
               { -1,  2, -1 },
               {  0, -1,  2 }
            };

            CholeskyDecomposition chol = new CholeskyDecomposition(value);
            double[,] L = chol.LeftTriangularFactor;

            double[] B = new double[] { 1, 2, 3 };

            double[] expected = new double[] { 2.5, 4.0, 3.5 };
            double[] actual = chol.Solve(B);

            Assert.IsTrue(Matrix.IsEqual(expected, actual, 0.0000000000001));

            actual = chol.Solve(B, true);
            Assert.AreEqual(actual, B);
            Assert.IsTrue(Matrix.IsEqual(expected, B, 0.0000000000001));
        }