Exemplo n.º 1
0
        /// <summary>
        /// Computes the singular value decomposition of the square matrix.
        /// </summary>
        /// <returns>The singular value decomposition of the matrix.</returns>
        /// <remarks>
        /// <para>Singular value decomposition is an advanced matrix decomposition technique that can be applied
        /// to all matrices, including non-square and singular square matrices.</para>
        /// </remarks>
        public SingularValueDecomposition SingularValueDecomposition()
        {
            double[]          copy = MatrixAlgorithms.Copy(store, offset, rowStride, colStride, dimension, dimension);
            RectangularMatrix r    = new RectangularMatrix(copy, dimension, dimension);

            return(r.SingularValueDecomposition());
        }
Exemplo n.º 2
0
 /// <summary>
 /// Computes a QR decomposition of the matrix.
 /// </summary>
 /// <returns>A QR decomposition of the matrix.</returns>
 /// <seealso cref="Matrices.QRDecomposition"/>
 public SquareQRDecomposition QRDecomposition()
 {
     double[] rStore  = MatrixAlgorithms.Copy(store, offset, rowStride, colStride, dimension, dimension);
     double[] qtStore = SquareMatrixAlgorithms.CreateUnitMatrix(dimension);
     MatrixAlgorithms.QRDecompose(rStore, qtStore, dimension, dimension);
     return(new SquareQRDecomposition(qtStore, rStore, dimension));
 }
Exemplo n.º 3
0
 /// <summary>
 /// Computes the eigenvalues of the matrix.
 /// </summary>
 /// <returns>The eigenvalues of the matrix.</returns>
 /// <seealso cref="Eigendecomposition"/>
 public Complex[] Eigenvalues()
 {
     double[] aStore = MatrixAlgorithms.Copy(store, offset, rowStride, colStride, dimension, dimension);
     SquareMatrixAlgorithms.IsolateCheapEigenvalues(aStore, null, dimension);
     SquareMatrixAlgorithms.ReduceToHessenberg(aStore, null, dimension);
     Complex[] eigenvalues = SquareMatrixAlgorithms.ReduceToRealSchurForm(aStore, null, dimension);
     return(eigenvalues);
 }
Exemplo n.º 4
0
        /// <summary>
        /// Computes the eigenvalues and eigenvectors of the matrix.
        /// </summary>
        /// <returns>A representation of the eigenvalues and eigenvectors of the matrix.</returns>
        /// <remarks>
        /// <para>For a generic vector v and matrix M, Mv = u will point in some direction with no particular relationship to v.
        /// The eigenvectors of a matrix M are vectors z that satisfy Mz = &#x3BB;z, i.e. multiplying an eigenvector by a
        /// matrix reproduces the same vector, up to a prortionality constant &#x3BB; called the eigenvalue.</para>
        /// <para>For v to be an eigenvector of M with eigenvalue &#x3BB;, (M - &#x3BB;I)z = 0. But for a matrix to
        /// anihilate any non-zero vector, that matrix must have determinant, so det(M - &#x3BB;I)=0. For a matrix of
        /// order N, this is an equation for the roots of a polynomial of order N. Since an order-N polynomial always has exactly
        /// N roots, an order-N matrix always has exactly N eigenvalues.</para>
        /// <para>Since a polynomial with real coefficients can still have complex roots, a real square matrix can nonetheless
        /// have complex eigenvalues (and correspondly complex eigenvectors). However, again like the complex roots of a real
        /// polynomial, such eigenvalues will always occurs in complex-conjugate pairs.</para>
        /// <para>Although the eigenvalue polynomial ensures that an order-N matrix has N eigenvalues, it can occur that there
        /// are not N corresponding independent eigenvectors. A matrix with fewer eigenvectors than eigenvalues is called
        /// defective. Like singularity, defectiveness represents a delecate balance between the elements of a matrix that can
        /// typically be disturbed by just an infinitesimal perturbation of elements. Because of round-off-error, then, floating-point
        /// algorithms cannot reliably identify defective matrices. Instead, this method will return a full set of eigenvectors,
        /// but some eigenvectors, corresponding to very nearly equal eigenvalues, will be very nearly parallel.</para>
        /// <para>While a generic square matrix can be defective, many subspecies of square matrices are guaranteed not to be.
        /// This includes Markov matrices, orthogonal matrices, and symmetric matrices.</para>
        /// <para>Determining the eigenvalues and eigenvectors of a matrix is an O(N<sup>3</sup>) operation. If you need only the
        /// eigenvalues of a matrix, the <see cref="Eigenvalues"/> method is more efficient.</para>
        /// </remarks>
        public ComplexEigensystem Eigensystem()
        {
            double[] aStore = MatrixAlgorithms.Copy(store, dimension, dimension);

            int[] perm = new int[dimension];
            for (int i = 0; i < perm.Length; i++)
            {
                perm[i] = i;
            }
            SquareMatrixAlgorithms.IsolateCheapEigenvalues(aStore, perm, dimension);
            double[] qStore = MatrixAlgorithms.AllocateStorage(dimension, dimension);
            for (int i = 0; i < perm.Length; i++)
            {
                MatrixAlgorithms.SetEntry(qStore, dimension, dimension, perm[i], i, 1.0);
            }
            //double[] qStore = SquareMatrixAlgorithms.CreateUnitMatrix(dimension);

            // Reduce the original matrix to Hessenberg form
            SquareMatrixAlgorithms.ReduceToHessenberg(aStore, qStore, dimension);

            // Reduce the Hessenberg matrix to real Schur form
            SquareMatrixAlgorithms.ReduceToRealSchurForm(aStore, qStore, dimension);

            //MatrixAlgorithms.PrintMatrix(aStore, dimension, dimension);

            //SquareMatrix A = new SquareMatrix(aStore, dimension);
            SquareMatrix Q = new SquareMatrix(qStore, dimension);

            Complex[] eigenvalues; Complex[][] eigenvectors;

            // Extract the eigenvalues and eigenvectors of the Schur form matrix
            SquareMatrixAlgorithms.SchurEigensystem(aStore, dimension, out eigenvalues, out eigenvectors);

            // transform eigenvectors of schur form into eigenvectors of original matrix
            // while we are at it, normalize so largest component has value 1
            for (int i = 0; i < dimension; i++)
            {
                Complex[] v    = new Complex[dimension];
                double    norm = 0.0;
                for (int j = 0; j < dimension; j++)
                {
                    for (int k = 0; k < dimension; k++)
                    {
                        v[j] += Q[j, k] * eigenvectors[i][k];
                    }
                    norm = Math.Max(norm, Math.Max(Math.Abs(v[j].Re), Math.Abs(v[j].Im)));
                }
                for (int j = 0; j < dimension; j++)
                {
                    v[j] = v[j] / norm;
                }
                eigenvectors[i] = v;
            }

            ComplexEigensystem eigensystem = new ComplexEigensystem(dimension, eigenvalues, eigenvectors);

            return(eigensystem);
        }
Exemplo n.º 5
0
 /// <summary>
 /// Creates a transpose of the matrix.
 /// </summary>
 /// <returns>The matrix transpose M<sup>T</sup>.</returns>
 public SquareMatrix Transpose()
 {
     // To transpose, just copy with
     double[] transpose = MatrixAlgorithms.Copy(store, offset, colStride, rowStride, dimension, dimension);
     return(new SquareMatrix(transpose, dimension));
     //return (new SquareMatrix(store, 0, colStride, rowStride, dimension, false));
     //double[] tStore = MatrixAlgorithms.Transpose(store, dimension, dimension);
     //return (new SquareMatrix(tStore, dimension));
 }
Exemplo n.º 6
0
 /// <summary>
 /// Computes the inverse of the original matrix.
 /// </summary>
 /// <returns>A<sup>-1</sup></returns>
 public SquareMatrix Inverse()
 {
     // solve R Q^T column-by-column
     double[] iStore = MatrixAlgorithms.Copy(qtStore);
     for (int c = 0; c < dimension; c++)
     {
         SquareMatrixAlgorithms.SolveUpperRightTriangular(rStore, iStore, dimension * c, dimension);
     }
     return(new SquareMatrix(iStore, dimension));
 }
Exemplo n.º 7
0
        // complicated specific operations

        /// <summary>
        /// Computes the QR decomposition of the matrix.
        /// </summary>
        /// <returns>The QR decomposition of the matrix.</returns>
        /// <remarks>
        /// <para>Only matrices with a number of rows greater than or equal to the number of columns can be QR decomposed. If your
        /// matrix has more columns than rows, you can QR decompose its transpose.</para>
        /// </remarks>
        /// <seealso cref="QRDecomposition"/>
        public QRDecomposition QRDecomposition()
        {
            if (rows < cols)
            {
                throw new InvalidOperationException();
            }

            double[] rStore = MatrixAlgorithms.Copy(store, offset, rowStride, colStride, rows, cols);

            double[] qtStore = SquareMatrixAlgorithms.CreateUnitMatrix(rows);

            MatrixAlgorithms.QRDecompose(rStore, qtStore, rows, cols);

            return(new QRDecomposition(qtStore, rStore, rows, cols));
        }
Exemplo n.º 8
0
        /// <summary>
        /// Computes the singular value decomposition of the matrix.
        /// </summary>
        /// <returns>The SVD of the matrix.</returns>
        public SingularValueDecomposition SingularValueDecomposition()
        {
            if (rows >= cols)
            {
                // copy the matrix so as not to distrub the original
                double[] copy = MatrixAlgorithms.Copy(store, offset, rowStride, colStride, rows, cols);

                // bidiagonalize it
                double[] a, b;
                MatrixAlgorithms.Bidiagonalize(copy, rows, cols, out a, out b);

                // form the U and V matrices
                double[] left  = MatrixAlgorithms.AccumulateBidiagonalU(copy, rows, cols);
                double[] right = MatrixAlgorithms.AccumulateBidiagonalV(copy, rows, cols);

                // find the singular values of the bidiagonal matrix
                MatrixAlgorithms.ExtractSingularValues(a, b, left, right, rows, cols);

                // sort them
                MatrixAlgorithms.SortValues(a, left, right, rows, cols);

                // package it all up
                return(new SingularValueDecomposition(left, a, right, rows, cols));
            }
            else
            {
                double[] scratch = MatrixAlgorithms.Transpose(store, rows, cols);

                double[] a, b;
                MatrixAlgorithms.Bidiagonalize(scratch, cols, rows, out a, out b);

                double[] left  = MatrixAlgorithms.AccumulateBidiagonalU(scratch, cols, rows);
                double[] right = MatrixAlgorithms.AccumulateBidiagonalV(scratch, cols, rows);

                MatrixAlgorithms.ExtractSingularValues(a, b, left, right, cols, rows);

                MatrixAlgorithms.SortValues(a, left, right, cols, rows);

                left  = MatrixAlgorithms.Transpose(left, cols, cols);
                right = MatrixAlgorithms.Transpose(right, rows, rows);

                return(new SingularValueDecomposition(right, a, left, rows, cols));
            }
        }
Exemplo n.º 9
0
        /*
         * /// <summary>
         * /// Inverts the matrix, in place.
         * /// </summary>
         * /// <remarks>
         * /// <para>This method replaces the elements of M with the elements of M<sup>-1</sup>.</para>
         * /// <para>In place matrix inversion saves memory, since separate storage of M and M<sup>-1</sup> is not required.</para></remarks>
         * private void InvertInPlace () {
         * }
         */

        /// <summary>
        /// Computes the LU decomposition of the matrix.
        /// </summary>
        /// <returns>The LU decomposition of the matrix.</returns>
        /// <remarks>
        /// <para>The LU decomposition of a matrix M is a set of matrices L, U, and P such that LU = PM, where L
        /// is lower-left triangular, U is upper-right triangular, and P is a permutation matrix (so that PM is
        /// a row-wise permutation of M).</para>
        /// <para>The LU decomposition of a square matrix is an O(N<sup>3</sup>) operation.</para>
        /// </remarks>
        public LUDecomposition LUDecomposition()
        {
            // Copy the matrix content
            double[] luStore = MatrixAlgorithms.Copy(store, offset, rowStride, colStride, dimension, dimension);

            // Prepare an initial permutation and parity
            int[] permutation = new int[dimension];
            for (int i = 0; i < permutation.Length; i++)
            {
                permutation[i] = i;
            }
            int parity = 1;

            // Do the LU decomposition
            SquareMatrixAlgorithms.LUDecompose(luStore, permutation, ref parity, dimension);

            // Package it up and return it
            LUDecomposition LU = new LUDecomposition(luStore, permutation, parity, dimension);

            return(LU);
        }
Exemplo n.º 10
0
 /// <summary>
 /// Returns the transpose of the matrix.
 /// </summary>
 /// <returns>M<sup>T</sup></returns>
 public RectangularMatrix Transpose()
 {
     // Just copy with rows <-> columns to get transpose
     double[] transpose = MatrixAlgorithms.Copy(store, offset, colStride, rowStride, cols, rows);
     return(new RectangularMatrix(transpose, cols, rows));
 }
Exemplo n.º 11
0
        // simple specific operations

        /// <summary>
        /// Copies the matrix.
        /// </summary>
        /// <returns>An indpendent copy of the matrix.</returns>
        public RectangularMatrix Copy()
        {
            double[] cStore = MatrixAlgorithms.Copy(store, offset, rowStride, colStride, rows, cols);
            return(new RectangularMatrix(cStore, rows, cols));
        }
Exemplo n.º 12
0
 /// <summary>
 /// Computes the inverse of the matrix.
 /// </summary>
 /// <returns>The matrix inverse M<sup>-1</sup>.</returns>
 /// <remarks>
 /// <para>The inverse of a matrix M is a matrix M<sup>-1</sup> such that M<sup>-1</sup>M = I, where I is the identity matrix.</para>
 /// <para>If the matrix is singular, inversion is not possible. In that case, this method will fail with a <see cref="DivideByZeroException"/>.</para>
 /// <para>The inversion of a matrix is an O(N<sup>3</sup>) operation.</para>
 /// </remarks>
 /// <exception cref="DivideByZeroException">The matrix is singular.</exception>
 public SquareMatrix Inverse()
 {
     double[] iStore = MatrixAlgorithms.Copy(store, offset, rowStride, colStride, dimension, dimension);
     SquareMatrixAlgorithms.GaussJordanInvert(iStore, dimension);
     return(new SquareMatrix(iStore, dimension));
 }
Exemplo n.º 13
0
 /// <summary>
 /// Copies the matrix.
 /// </summary>
 /// <returns>An independent copy of the matrix.</returns>
 public SquareMatrix Copy()
 {
     double[] copyStore = MatrixAlgorithms.Copy(store, offset, rowStride, colStride, dimension, dimension);
     return(new SquareMatrix(copyStore, dimension));
 }
Exemplo n.º 14
0
 /// <summary>
 /// Copies the matrix.
 /// </summary>
 /// <returns>An independent copy of the matrix.</returns>
 public SquareMatrix Copy()
 {
     double[] cStore = MatrixAlgorithms.Copy(store, dimension, dimension);
     return(new SquareMatrix(cStore, dimension));
 }