예제 #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DenseEvd"/> class. This object will compute the
        /// the eigenvalue decomposition when the constructor is called and cache it's decomposition.
        /// </summary>
        /// <param name="matrix">The matrix to factor.</param>
        /// <param name="symmetricity">If it is known whether the matrix is symmetric or not the routine can skip checking it itself.</param>
        /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If EVD algorithm failed to converge with matrix <paramref name="matrix"/>.</exception>
        public static DenseEvd Create(DenseMatrix matrix, Symmetricity symmetricity)
        {
            if (matrix.RowCount != matrix.ColumnCount)
            {
                throw new ArgumentException(Resources.ArgumentMatrixSquare);
            }

            var order = matrix.RowCount;

            // Initialize matrices for eigenvalues and eigenvectors
            var eigenVectors = new DenseMatrix(order);
            var blockDiagonal = new DenseMatrix(order);
            var eigenValues = new LinearAlgebra.Complex.DenseVector(order);

            bool isSymmetric;
            switch (symmetricity)
            {
                case Symmetricity.Symmetric:
                case Symmetricity.Hermitian:
                    isSymmetric = true;
                    break;
                case Symmetricity.Asymmetric:
                    isSymmetric = false;
                    break;
                default:
                    isSymmetric = matrix.IsSymmetric();
                    break;
            }

            Control.LinearAlgebraProvider.EigenDecomp(isSymmetric, order, matrix.Values, eigenVectors.Values, eigenValues.Values, blockDiagonal.Values);

            return new DenseEvd(eigenVectors, eigenValues, blockDiagonal, isSymmetric);
        }
예제 #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DenseEvd"/> class. This object will compute the
        /// the eigenvalue decomposition when the constructor is called and cache it's decomposition.
        /// </summary>
        /// <param name="matrix">The matrix to factor.</param>
        /// <param name="symmetricity">If it is known whether the matrix is symmetric or not the routine can skip checking it itself.</param>
        /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If EVD algorithm failed to converge with matrix <paramref name="matrix"/>.</exception>
        public static DenseEvd Create(DenseMatrix matrix, Symmetricity symmetricity)
        {
            if (matrix.RowCount != matrix.ColumnCount)
            {
                throw new ArgumentException(Resource.ArgumentMatrixSquare);
            }

            var order = matrix.RowCount;

            // Initialize matrices for eigenvalues and eigenvectors
            var eigenVectors  = DenseMatrix.CreateIdentity(order);
            var blockDiagonal = new DenseMatrix(order);
            var eigenValues   = new LinearAlgebra.Complex.DenseVector(order);

            bool isSymmetric;

            switch (symmetricity)
            {
            case Symmetricity.Hermitian:
                isSymmetric = true;
                break;

            case Symmetricity.Asymmetric:
                isSymmetric = false;
                break;

            default:
                isSymmetric = matrix.IsHermitian();
                break;
            }

            Control.LinearAlgebraProvider.EigenDecomp(isSymmetric, order, matrix.Values, eigenVectors.Values, eigenValues.Values, blockDiagonal.Values);

            return(new DenseEvd(eigenVectors, eigenValues, blockDiagonal, isSymmetric));
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="DenseEvd"/> class. This object will compute the
        /// the eigenvalue decomposition when the constructor is called and cache it's decomposition.
        /// </summary>
        /// <param name="matrix">The matrix to factor.</param>
        /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If EVD algorithm failed to converge with matrix <paramref name="matrix"/>.</exception>
        public DenseEvd(DenseMatrix matrix)
        {
            if (matrix == null)
            {
                throw new ArgumentNullException("matrix");
            }

            if (matrix.RowCount != matrix.ColumnCount)
            {
                throw new ArgumentException(Resources.ArgumentMatrixSquare);
            }

            var order = matrix.RowCount;

            // Initialize matrices for eigenvalues and eigenvectors
            MatrixEv = matrix.CreateMatrix(order, order);
            MatrixD = matrix.CreateMatrix(order, order);
            VectorEv = new LinearAlgebra.Complex.DenseVector(order);

            IsSymmetric = true;

            for (var i = 0; IsSymmetric && i < order; i++)
            {
                for (var j = 0; IsSymmetric && j < order; j++)
                {
                    IsSymmetric &= matrix.At(i, j) == matrix.At(j, i);
                }
            }

            Control.LinearAlgebraProvider.EigenDecomp(IsSymmetric, order, matrix.Values, ((DenseMatrix) MatrixEv).Values,
                ((LinearAlgebra.Complex.DenseVector)VectorEv).Values, ((DenseMatrix)MatrixD).Values);
        }
예제 #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DenseEvd"/> class. This object will compute the
        /// the eigenvalue decomposition when the constructor is called and cache it's decomposition.
        /// </summary>
        /// <param name="matrix">The matrix to factor.</param>
        /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If EVD algorithm failed to converge with matrix <paramref name="matrix"/>.</exception>
        public static DenseEvd Create(DenseMatrix matrix)
        {
            if (matrix.RowCount != matrix.ColumnCount)
            {
                throw new ArgumentException(Resources.ArgumentMatrixSquare);
            }

            var order = matrix.RowCount;

            // Initialize matrices for eigenvalues and eigenvectors
            var eigenVectors  = new DenseMatrix(order);
            var blockDiagonal = new DenseMatrix(order);
            var eigenValues   = new LinearAlgebra.Complex.DenseVector(order);

            var isSymmetric = true;

            for (var i = 0; isSymmetric && i < order; i++)
            {
                for (var j = 0; isSymmetric && j < order; j++)
                {
                    isSymmetric &= matrix.At(i, j) == matrix.At(j, i);
                }
            }

            Control.LinearAlgebraProvider.EigenDecomp(isSymmetric, order, matrix.Values, eigenVectors.Values, eigenValues.Values, blockDiagonal.Values);

            return(new DenseEvd(eigenVectors, eigenValues, blockDiagonal, isSymmetric));
        }
예제 #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DenseEvd"/> class. This object will compute the
        /// the eigenvalue decomposition when the constructor is called and cache it's decomposition.
        /// </summary>
        /// <param name="matrix">The matrix to factor.</param>
        /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If EVD algorithm failed to converge with matrix <paramref name="matrix"/>.</exception>
        public DenseEvd(DenseMatrix matrix)
        {
            if (matrix == null)
            {
                throw new ArgumentNullException("matrix");
            }

            if (matrix.RowCount != matrix.ColumnCount)
            {
                throw new ArgumentException(Resources.ArgumentMatrixSquare);
            }

            var order = matrix.RowCount;

            // Initialize matrices for eigenvalues and eigenvectors
            MatrixEv = matrix.CreateMatrix(order, order);
            MatrixD  = matrix.CreateMatrix(order, order);
            VectorEv = new LinearAlgebra.Complex.DenseVector(order);

            IsSymmetric = true;

            for (var i = 0; IsSymmetric && i < order; i++)
            {
                for (var j = 0; IsSymmetric && j < order; j++)
                {
                    IsSymmetric &= matrix.At(i, j) == matrix.At(j, i);
                }
            }

            Control.LinearAlgebraProvider.EigenDecomp(IsSymmetric, order, matrix.Values, ((DenseMatrix)MatrixEv).Values,
                                                      ((LinearAlgebra.Complex.DenseVector)VectorEv).Values, ((DenseMatrix)MatrixD).Values);
        }
예제 #6
0
        /// <summary>
        /// Initializes a new instance of the <see cref="UserEvd"/> class. This object will compute the
        /// the eigenvalue decomposition when the constructor is called and cache it's decomposition.
        /// </summary>
        /// <param name="matrix">The matrix to factor.</param>
        /// <param name="symmetricity">If it is known whether the matrix is symmetric or not the routine can skip checking it itself.</param>
        /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If EVD algorithm failed to converge with matrix <paramref name="matrix"/>.</exception>
        public static UserEvd Create(Matrix<Complex32> matrix, Symmetricity symmetricity)
        {
            if (matrix.RowCount != matrix.ColumnCount)
            {
                throw new ArgumentException(Resources.ArgumentMatrixSquare);
            }

            var order = matrix.RowCount;

            // Initialize matricies for eigenvalues and eigenvectors
            var eigenVectors = DenseMatrix.CreateIdentity(order);
            var blockDiagonal = Matrix<Complex32>.Build.SameAs(matrix, order, order);
            var eigenValues = new LinearAlgebra.Complex.DenseVector(order);

            bool isSymmetric;
            switch (symmetricity)
            {
                case Symmetricity.Hermitian:
                    isSymmetric = true;
                    break;
                case Symmetricity.Asymmetric:
                    isSymmetric = false;
                    break;
                default:
                    isSymmetric = matrix.IsHermitian();
                    break;
            }

            if (isSymmetric)
            {
                var matrixCopy = matrix.ToArray();
                var tau = new Complex32[order];
                var d = new float[order];
                var e = new float[order];

                SymmetricTridiagonalize(matrixCopy, d, e, tau, order);
                SymmetricDiagonalize(eigenVectors, d, e, order);
                SymmetricUntridiagonalize(eigenVectors, matrixCopy, tau, order);

                for (var i = 0; i < order; i++)
                {
                    eigenValues[i] = new Complex(d[i], e[i]);
                }
            }
            else
            {
                var matrixH = matrix.ToArray();
                NonsymmetricReduceToHessenberg(eigenVectors, matrixH, order);
                NonsymmetricReduceHessenberToRealSchur(eigenVectors, eigenValues, matrixH, order);
            }

            for (var i = 0; i < eigenValues.Count; i++)
            {
                blockDiagonal.At(i, i, (Complex32) eigenValues[i]);
            }

            return new UserEvd(eigenVectors, eigenValues, blockDiagonal, isSymmetric);
        }
예제 #7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="UserEvd"/> class. This object will compute the
        /// the eigenvalue decomposition when the constructor is called and cache it's decomposition.
        /// </summary>
        /// <param name="matrix">The matrix to factor.</param>
        /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If EVD algorithm failed to converge with matrix <paramref name="matrix"/>.</exception>
        public UserEvd(Matrix<Complex32> matrix)
        {
            if (matrix == null)
            {
                throw new ArgumentNullException("matrix");
            }

            if (matrix.RowCount != matrix.ColumnCount)
            {
                throw new ArgumentException(Resources.ArgumentMatrixSquare);
            }

            var order = matrix.RowCount;

            // Initialize matricies for eigenvalues and eigenvectors
            MatrixEv = DenseMatrix.Identity(order);
            MatrixD = matrix.CreateMatrix(order, order);
            VectorEv = new LinearAlgebra.Complex.DenseVector(order);
           
            IsSymmetric = true;

            for (var i = 0; IsSymmetric && i < order; i++)
            {
                for (var j = 0; IsSymmetric && j < order; j++)
                {
                    IsSymmetric &= matrix.At(i, j) == matrix.At(j, i).Conjugate();
                }
            }

            if (IsSymmetric)
            {
                var matrixCopy = matrix.ToArray();
                var tau = new Complex32[order];
                var d = new float[order];
                var e = new float[order];

                SymmetricTridiagonalize(matrixCopy, d, e, tau, order);
                SymmetricDiagonalize(d, e, order);
                SymmetricUntridiagonalize(matrixCopy, tau, order);

                for (var i = 0; i < order; i++)
                {
                    VectorEv[i] = new Complex(d[i], e[i]);
                }
            }
            else
            {
                var matrixH = matrix.ToArray();
                NonsymmetricReduceToHessenberg(matrixH, order);
                NonsymmetricReduceHessenberToRealSchur(matrixH, order);
            }

            for (var i = 0; i < VectorEv.Count; i++)
            {
                MatrixD.At(i, i, (Complex32)VectorEv[i]);
            }
        }
예제 #8
0
        /// <summary>
        /// Initializes a new instance of the <see cref="UserEvd"/> class. This object will compute the
        /// the eigenvalue decomposition when the constructor is called and cache it's decomposition.
        /// </summary>
        /// <param name="matrix">The matrix to factor.</param>
        /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If EVD algorithm failed to converge with matrix <paramref name="matrix"/>.</exception>
        public UserEvd(Matrix <Complex32> matrix)
        {
            if (matrix == null)
            {
                throw new ArgumentNullException("matrix");
            }

            if (matrix.RowCount != matrix.ColumnCount)
            {
                throw new ArgumentException(Resources.ArgumentMatrixSquare);
            }

            var order = matrix.RowCount;

            // Initialize matricies for eigenvalues and eigenvectors
            MatrixEv = DenseMatrix.Identity(order);
            MatrixD  = matrix.CreateMatrix(order, order);
            VectorEv = new LinearAlgebra.Complex.DenseVector(order);

            IsSymmetric = true;

            for (var i = 0; IsSymmetric && i < order; i++)
            {
                for (var j = 0; IsSymmetric && j < order; j++)
                {
                    IsSymmetric &= matrix.At(i, j) == matrix.At(j, i).Conjugate();
                }
            }

            if (IsSymmetric)
            {
                var matrixCopy = matrix.ToArray();
                var tau        = new Complex32[order];
                var d          = new float[order];
                var e          = new float[order];

                SymmetricTridiagonalize(matrixCopy, d, e, tau, order);
                SymmetricDiagonalize(d, e, order);
                SymmetricUntridiagonalize(matrixCopy, tau, order);

                for (var i = 0; i < order; i++)
                {
                    VectorEv[i] = new Complex(d[i], e[i]);
                }
            }
            else
            {
                var matrixH = matrix.ToArray();
                NonsymmetricReduceToHessenberg(matrixH, order);
                NonsymmetricReduceHessenberToRealSchur(matrixH, order);
            }

            for (var i = 0; i < VectorEv.Count; i++)
            {
                MatrixD.At(i, i, (Complex32)VectorEv[i]);
            }
        }
예제 #9
0
        /// <summary>
        /// Initializes a new instance of the <see cref="UserEvd"/> class. This object will compute the
        /// the eigenvalue decomposition when the constructor is called and cache it's decomposition.
        /// </summary>
        /// <param name="matrix">The matrix to factor.</param>
        /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If EVD algorithm failed to converge with matrix <paramref name="matrix"/>.</exception>
        public static UserEvd Create(Matrix <Complex32> matrix)
        {
            if (matrix.RowCount != matrix.ColumnCount)
            {
                throw new ArgumentException(Resources.ArgumentMatrixSquare);
            }

            var order = matrix.RowCount;

            // Initialize matricies for eigenvalues and eigenvectors
            var eigenVectors  = DenseMatrix.CreateIdentity(order);
            var blockDiagonal = Matrix <Complex32> .Build.SameAs(matrix, order, order);

            var eigenValues = new LinearAlgebra.Complex.DenseVector(order);

            var isSymmetric = true;

            for (var i = 0; isSymmetric && i < order; i++)
            {
                for (var j = 0; isSymmetric && j < order; j++)
                {
                    isSymmetric &= matrix.At(i, j) == matrix.At(j, i).Conjugate();
                }
            }

            if (isSymmetric)
            {
                var matrixCopy = matrix.ToArray();
                var tau        = new Complex32[order];
                var d          = new float[order];
                var e          = new float[order];

                SymmetricTridiagonalize(matrixCopy, d, e, tau, order);
                SymmetricDiagonalize(eigenVectors, d, e, order);
                SymmetricUntridiagonalize(eigenVectors, matrixCopy, tau, order);

                for (var i = 0; i < order; i++)
                {
                    eigenValues[i] = new Complex(d[i], e[i]);
                }
            }
            else
            {
                var matrixH = matrix.ToArray();
                NonsymmetricReduceToHessenberg(eigenVectors, matrixH, order);
                NonsymmetricReduceHessenberToRealSchur(eigenVectors, eigenValues, matrixH, order);
            }

            for (var i = 0; i < eigenValues.Count; i++)
            {
                blockDiagonal.At(i, i, (Complex32)eigenValues[i]);
            }

            return(new UserEvd(eigenVectors, eigenValues, blockDiagonal, isSymmetric));
        }
예제 #10
0
        /// <summary>
        /// Initializes a new instance of the <see cref="UserEvd"/> class. This object will compute the
        /// the eigenvalue decomposition when the constructor is called and cache it's decomposition.
        /// </summary>
        /// <param name="matrix">The matrix to factor.</param>
        /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If EVD algorithm failed to converge with matrix <paramref name="matrix"/>.</exception>
        public static UserEvd Create(Matrix<Complex32> matrix)
        {
            if (matrix.RowCount != matrix.ColumnCount)
            {
                throw new ArgumentException(Resources.ArgumentMatrixSquare);
            }

            var order = matrix.RowCount;

            // Initialize matricies for eigenvalues and eigenvectors
            var eigenVectors = DenseMatrix.CreateIdentity(order);
            var blockDiagonal = matrix.CreateMatrix(order, order);
            var eigenValues = new LinearAlgebra.Complex.DenseVector(order);

            var isSymmetric = true;

            for (var i = 0; isSymmetric && i < order; i++)
            {
                for (var j = 0; isSymmetric && j < order; j++)
                {
                    isSymmetric &= matrix.At(i, j) == matrix.At(j, i).Conjugate();
                }
            }

            if (isSymmetric)
            {
                var matrixCopy = matrix.ToArray();
                var tau = new Complex32[order];
                var d = new float[order];
                var e = new float[order];

                SymmetricTridiagonalize(matrixCopy, d, e, tau, order);
                SymmetricDiagonalize(eigenVectors, d, e, order);
                SymmetricUntridiagonalize(eigenVectors, matrixCopy, tau, order);

                for (var i = 0; i < order; i++)
                {
                    eigenValues[i] = new Complex(d[i], e[i]);
                }
            }
            else
            {
                var matrixH = matrix.ToArray();
                NonsymmetricReduceToHessenberg(eigenVectors, matrixH, order);
                NonsymmetricReduceHessenberToRealSchur(eigenVectors, eigenValues, matrixH, order);
            }

            for (var i = 0; i < eigenValues.Count; i++)
            {
                blockDiagonal.At(i, i, (Complex32) eigenValues[i]);
            }

            return new UserEvd(eigenVectors, eigenValues, blockDiagonal, isSymmetric);
        }
예제 #11
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DenseEvd"/> class. This object will compute the
        /// the eigenvalue decomposition when the constructor is called and cache it's decomposition.
        /// </summary>
        /// <param name="matrix">The matrix to factor.</param>
        /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If EVD algorithm failed to converge with matrix <paramref name="matrix"/>.</exception>
        public DenseEvd(DenseMatrix matrix)
        {
            if (matrix == null)
            {
                throw new ArgumentNullException("matrix");
            }

            if (matrix.RowCount != matrix.ColumnCount)
            {
                throw new ArgumentException(Resources.ArgumentMatrixSquare);
            }

            var order = matrix.RowCount;

            // Initialize matricies for eigenvalues and eigenvectors
            MatrixEv = matrix.CreateMatrix(order, order);
            MatrixD = matrix.CreateMatrix(order, order);
            VectorEv = new LinearAlgebra.Complex.DenseVector(order);
           
            IsSymmetric = true;

            for (var i = 0; i < order & IsSymmetric; i++)
            {
                for (var j = 0; j < order & IsSymmetric; j++)
                {
                    IsSymmetric &= matrix.At(i, j) == matrix.At(j, i);
                }
            }

            var d = new float[order];
            var e = new float[order];

            if (IsSymmetric)
            {
                matrix.CopyTo(MatrixEv);
                d = MatrixEv.Row(order - 1).ToArray();

                SymmetricTridiagonalize(((DenseMatrix)MatrixEv).Values, d, e, order);
                SymmetricDiagonalize(((DenseMatrix)MatrixEv).Values, d, e, order);
            }
            else
            {
                var matrixH = matrix.ToArray();

                NonsymmetricReduceToHessenberg(((DenseMatrix)MatrixEv).Values, matrixH, order);
                NonsymmetricReduceHessenberToRealSchur(((DenseMatrix)MatrixEv).Values, matrixH, d, e, order);
            }

            for (var i = 0; i < order; i++)
            {
                MatrixD.At(i, i, d[i]);

                if (e[i] > 0)
                {
                    MatrixD.At(i, i + 1, e[i]);
                }
                else if (e[i] < 0)
                {
                    MatrixD.At(i, i - 1, e[i]);
                }
            }

            for (var i = 0; i < order; i++)
            {
                VectorEv[i] = new Complex(d[i], e[i]);
            }
        }
예제 #12
0
        /// <summary>
        /// Initializes a new instance of the <see cref="UserEvd"/> class. This object will compute the
        /// the eigenvalue decomposition when the constructor is called and cache it's decomposition.
        /// </summary>
        /// <param name="matrix">The matrix to factor.</param>
        /// <param name="symmetricity">If it is known whether the matrix is symmetric or not the routine can skip checking it itself.</param>
        /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If EVD algorithm failed to converge with matrix <paramref name="matrix"/>.</exception>
        public static UserEvd Create(Matrix <Complex32> matrix, Symmetricity symmetricity)
        {
            if (matrix.RowCount != matrix.ColumnCount)
            {
                throw new ArgumentException("Matrix must be square.");
            }

            var order = matrix.RowCount;

            // Initialize matrices for eigenvalues and eigenvectors
            var eigenVectors  = DenseMatrix.CreateIdentity(order);
            var blockDiagonal = Matrix <Complex32> .Build.SameAs(matrix, order, order);

            var eigenValues = new LinearAlgebra.Complex.DenseVector(order);

            bool isSymmetric;

            switch (symmetricity)
            {
            case Symmetricity.Hermitian:
                isSymmetric = true;
                break;

            case Symmetricity.Asymmetric:
                isSymmetric = false;
                break;

            default:
                isSymmetric = matrix.IsHermitian();
                break;
            }

            if (isSymmetric)
            {
                var matrixCopy = matrix.ToArray();
                var tau        = new Complex32[order];
                var d          = new float[order];
                var e          = new float[order];

                SymmetricTridiagonalize(matrixCopy, d, e, tau, order);
                SymmetricDiagonalize(eigenVectors, d, e, order);
                SymmetricUntridiagonalize(eigenVectors, matrixCopy, tau, order);

                for (var i = 0; i < order; i++)
                {
                    eigenValues[i] = new Complex(d[i], e[i]);
                }
            }
            else
            {
                var matrixH = matrix.ToArray();
                NonsymmetricReduceToHessenberg(eigenVectors, matrixH, order);
                NonsymmetricReduceHessenberToRealSchur(eigenVectors, eigenValues, matrixH, order);
            }

            for (var i = 0; i < eigenValues.Count; i++)
            {
                blockDiagonal.At(i, i, (Complex32)eigenValues[i]);
            }

            return(new UserEvd(eigenVectors, eigenValues, blockDiagonal, isSymmetric));
        }
예제 #13
0
파일: UserEvd.cs 프로젝트: AChE-p/Circulus
        /// <summary>
        /// Initializes a new instance of the <see cref="UserEvd"/> class. This object will compute the
        /// the eigenvalue decomposition when the constructor is called and cache it's decomposition.
        /// </summary>
        /// <param name="matrix">The matrix to factor.</param>
        /// <param name="symmetricity">If it is known whether the matrix is symmetric or not the routine can skip checking it itself.</param>
        /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If EVD algorithm failed to converge with matrix <paramref name="matrix"/>.</exception>
        public static UserEvd Create(Matrix <double> matrix, Symmetricity symmetricity)
        {
            if (matrix.RowCount != matrix.ColumnCount)
            {
                throw new ArgumentException(Resources.ArgumentMatrixSquare);
            }

            var order = matrix.RowCount;

            // Initialize matricies for eigenvalues and eigenvectors
            var eigenVectors = Matrix <double> .Build.SameAs(matrix, order, order);

            var blockDiagonal = Matrix <double> .Build.SameAs(matrix, order, order);

            var eigenValues = new LinearAlgebra.Complex.DenseVector(order);

            bool isSymmetric;

            switch (symmetricity)
            {
            case Symmetricity.Symmetric:
            case Symmetricity.Hermitian:
                isSymmetric = true;
                break;

            case Symmetricity.Asymmetric:
                isSymmetric = false;
                break;

            default:
                isSymmetric = matrix.IsSymmetric();
                break;
            }

            var d = new double[order];
            var e = new double[order];

            if (isSymmetric)
            {
                matrix.CopyTo(eigenVectors);
                d = eigenVectors.Row(order - 1).ToArray();

                SymmetricTridiagonalize(eigenVectors, d, e, order);
                SymmetricDiagonalize(eigenVectors, d, e, order);
            }
            else
            {
                var matrixH = matrix.ToArray();

                NonsymmetricReduceToHessenberg(eigenVectors, matrixH, order);
                NonsymmetricReduceHessenberToRealSchur(eigenVectors, matrixH, d, e, order);
            }

            for (var i = 0; i < order; i++)
            {
                blockDiagonal.At(i, i, d[i]);

                if (e[i] > 0)
                {
                    blockDiagonal.At(i, i + 1, e[i]);
                }
                else if (e[i] < 0)
                {
                    blockDiagonal.At(i, i - 1, e[i]);
                }
            }

            for (var i = 0; i < order; i++)
            {
                eigenValues[i] = new Complex(d[i], e[i]);
            }

            return(new UserEvd(eigenVectors, eigenValues, blockDiagonal, isSymmetric));
        }
예제 #14
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DenseEvd"/> class. This object will compute the
        /// the eigenvalue decomposition when the constructor is called and cache it's decomposition.
        /// </summary>
        /// <param name="matrix">The matrix to factor.</param>
        /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If EVD algorithm failed to converge with matrix <paramref name="matrix"/>.</exception>
        public static DenseEvd Create(DenseMatrix matrix)
        {
            if (matrix.RowCount != matrix.ColumnCount)
            {
                throw new ArgumentException(Resources.ArgumentMatrixSquare);
            }

            var order = matrix.RowCount;

            // Initialize matrices for eigenvalues and eigenvectors
            var eigenVectors = new DenseMatrix(order);
            var blockDiagonal = new DenseMatrix(order);
            var eigenValues = new LinearAlgebra.Complex.DenseVector(order);

            var isSymmetric = true;

            for (var i = 0; isSymmetric && i < order; i++)
            {
                for (var j = 0; isSymmetric && j < order; j++)
                {
                    isSymmetric &= matrix.At(i, j) == matrix.At(j, i);
                }
            }

            Control.LinearAlgebraProvider.EigenDecomp(isSymmetric, order, matrix.Values, eigenVectors.Values, eigenValues.Values, blockDiagonal.Values);

            return new DenseEvd(eigenVectors, eigenValues, blockDiagonal, isSymmetric);
        }
예제 #15
0
        /// <summary>
        /// Initializes a new instance of the <see cref="UserEvd"/> class. This object will compute the
        /// the eigenvalue decomposition when the constructor is called and cache it's decomposition.
        /// </summary>
        /// <param name="matrix">The matrix to factor.</param>
        /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If EVD algorithm failed to converge with matrix <paramref name="matrix"/>.</exception>
        public static UserEvd Create(Matrix <float> matrix)
        {
            if (matrix.RowCount != matrix.ColumnCount)
            {
                throw new ArgumentException(Resources.ArgumentMatrixSquare);
            }

            var order = matrix.RowCount;

            // Initialize matricies for eigenvalues and eigenvectors
            var eigenVectors = Matrix <float> .Build.SameAs(matrix, order, order);

            var blockDiagonal = Matrix <float> .Build.SameAs(matrix, order, order);

            var eigenValues = new LinearAlgebra.Complex.DenseVector(order);

            var isSymmetric = true;

            for (var i = 0; isSymmetric && i < order; i++)
            {
                for (var j = 0; isSymmetric && j < order; j++)
                {
                    isSymmetric &= matrix.At(i, j) == matrix.At(j, i);
                }
            }

            var d = new float[order];
            var e = new float[order];

            if (isSymmetric)
            {
                matrix.CopyTo(eigenVectors);
                d = eigenVectors.Row(order - 1).ToArray();

                SymmetricTridiagonalize(eigenVectors, d, e, order);
                SymmetricDiagonalize(eigenVectors, d, e, order);
            }
            else
            {
                var matrixH = matrix.ToArray();

                NonsymmetricReduceToHessenberg(eigenVectors, matrixH, order);
                NonsymmetricReduceHessenberToRealSchur(eigenVectors, matrixH, d, e, order);
            }

            for (var i = 0; i < order; i++)
            {
                blockDiagonal.At(i, i, d[i]);

                if (e[i] > 0)
                {
                    blockDiagonal.At(i, i + 1, e[i]);
                }
                else if (e[i] < 0)
                {
                    blockDiagonal.At(i, i - 1, e[i]);
                }
            }

            for (var i = 0; i < order; i++)
            {
                eigenValues[i] = new Complex(d[i], e[i]);
            }

            return(new UserEvd(eigenVectors, eigenValues, blockDiagonal, isSymmetric));
        }
예제 #16
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DenseEvd"/> class. This object will compute the
        /// the eigenvalue decomposition when the constructor is called and cache it's decomposition.
        /// </summary>
        /// <param name="matrix">The matrix to factor.</param>
        /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If EVD algorithm failed to converge with matrix <paramref name="matrix"/>.</exception>
        public DenseEvd(DenseMatrix matrix)
        {
            if (matrix == null)
            {
                throw new ArgumentNullException("matrix");
            }

            if (matrix.RowCount != matrix.ColumnCount)
            {
                throw new ArgumentException(Resources.ArgumentMatrixSquare);
            }

            var order = matrix.RowCount;

            // Initialize matricies for eigenvalues and eigenvectors
            MatrixEv = matrix.CreateMatrix(order, order);
            MatrixD  = matrix.CreateMatrix(order, order);
            VectorEv = new LinearAlgebra.Complex.DenseVector(order);

            IsSymmetric = true;

            for (var i = 0; i < order & IsSymmetric; i++)
            {
                for (var j = 0; j < order & IsSymmetric; j++)
                {
                    IsSymmetric &= matrix[i, j] == matrix[j, i];
                }
            }

            var d = new double[order];
            var e = new double[order];

            if (IsSymmetric)
            {
                matrix.CopyTo(MatrixEv);
                d = MatrixEv.Row(order - 1).ToArray();

                SymmetricTridiagonalize(((DenseMatrix)MatrixEv).Data, d, e, order);
                SymmetricDiagonalize(((DenseMatrix)MatrixEv).Data, d, e, order);
            }
            else
            {
                var matrixH = matrix.ToArray();

                NonsymmetricReduceToHessenberg(((DenseMatrix)MatrixEv).Data, matrixH, order);
                NonsymmetricReduceHessenberToRealSchur(((DenseMatrix)MatrixEv).Data, matrixH, d, e, order);
            }

            for (var i = 0; i < order; i++)
            {
                MatrixD[i, i] = d[i];

                if (e[i] > 0)
                {
                    MatrixD.At(i, i + 1, e[i]);
                }
                else if (e[i] < 0)
                {
                    MatrixD.At(i, i - 1, e[i]);
                }
            }

            for (var i = 0; i < order; i++)
            {
                VectorEv[i] = new Complex(d[i], e[i]);
            }
        }
예제 #17
0
        /// <summary>
        /// Initializes a new instance of the <see cref="UserEvd"/> class. This object will compute the
        /// the eigenvalue decomposition when the constructor is called and cache it's decomposition.
        /// </summary>
        /// <param name="matrix">The matrix to factor.</param>
        /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If EVD algorithm failed to converge with matrix <paramref name="matrix"/>.</exception>
        public static UserEvd Create(Matrix<float> matrix)
        {
            if (matrix.RowCount != matrix.ColumnCount)
            {
                throw new ArgumentException(Resources.ArgumentMatrixSquare);
            }

            var order = matrix.RowCount;

            // Initialize matricies for eigenvalues and eigenvectors
            var eigenVectors = Matrix<float>.Build.SameAs(matrix, order, order);
            var blockDiagonal = Matrix<float>.Build.SameAs(matrix, order, order);
            var eigenValues = new LinearAlgebra.Complex.DenseVector(order);

            var isSymmetric = true;

            for (var i = 0; isSymmetric && i < order; i++)
            {
                for (var j = 0; isSymmetric && j < order; j++)
                {
                    isSymmetric &= matrix.At(i, j) == matrix.At(j, i);
                }
            }

            var d = new float[order];
            var e = new float[order];

            if (isSymmetric)
            {
                matrix.CopyTo(eigenVectors);
                d = eigenVectors.Row(order - 1).ToArray();

                SymmetricTridiagonalize(eigenVectors, d, e, order);
                SymmetricDiagonalize(eigenVectors, d, e, order);
            }
            else
            {
                var matrixH = matrix.ToArray();

                NonsymmetricReduceToHessenberg(eigenVectors, matrixH, order);
                NonsymmetricReduceHessenberToRealSchur(eigenVectors, matrixH, d, e, order);
            }

            for (var i = 0; i < order; i++)
            {
                blockDiagonal.At(i, i, d[i]);

                if (e[i] > 0)
                {
                    blockDiagonal.At(i, i + 1, e[i]);
                }
                else if (e[i] < 0)
                {
                    blockDiagonal.At(i, i - 1, e[i]);
                }
            }

            for (var i = 0; i < order; i++)
            {
                eigenValues[i] = new Complex(d[i], e[i]);
            }

            return new UserEvd(eigenVectors, eigenValues, blockDiagonal, isSymmetric);
        }
예제 #18
0
        /// <summary>
        /// Initializes a new instance of the <see cref="UserEvd"/> class. This object will compute the
        /// the eigenvalue decomposition when the constructor is called and cache it's decomposition.
        /// </summary>
        /// <param name="matrix">The matrix to factor.</param>
        /// <param name="symmetricity">If it is known whether the matrix is symmetric or not the routine can skip checking it itself.</param>
        /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If EVD algorithm failed to converge with matrix <paramref name="matrix"/>.</exception>
        public static UserEvd Create(Matrix<double> matrix, Symmetricity symmetricity)
        {
            if (matrix.RowCount != matrix.ColumnCount)
            {
                throw new ArgumentException(Resources.ArgumentMatrixSquare);
            }

            var order = matrix.RowCount;

            // Initialize matricies for eigenvalues and eigenvectors
            var eigenVectors = Matrix<double>.Build.SameAs(matrix, order, order);
            var blockDiagonal = Matrix<double>.Build.SameAs(matrix, order, order);
            var eigenValues = new LinearAlgebra.Complex.DenseVector(order);

            bool isSymmetric;
            switch (symmetricity)
            {
                case Symmetricity.Symmetric:
                case Symmetricity.Hermitian:
                    isSymmetric = true;
                    break;
                case Symmetricity.Asymmetric:
                    isSymmetric = false;
                    break;
                default:
                    isSymmetric = matrix.IsSymmetric();
                    break;
            }

            var d = new double[order];
            var e = new double[order];

            if (isSymmetric)
            {
                matrix.CopyTo(eigenVectors);
                d = eigenVectors.Row(order - 1).ToArray();

                SymmetricTridiagonalize(eigenVectors, d, e, order);
                SymmetricDiagonalize(eigenVectors, d, e, order);
            }
            else
            {
                var matrixH = matrix.ToArray();

                NonsymmetricReduceToHessenberg(eigenVectors, matrixH, order);
                NonsymmetricReduceHessenberToRealSchur(eigenVectors, matrixH, d, e, order);
            }

            for (var i = 0; i < order; i++)
            {
                blockDiagonal.At(i, i, d[i]);

                if (e[i] > 0)
                {
                    blockDiagonal.At(i, i + 1, e[i]);
                }
                else if (e[i] < 0)
                {
                    blockDiagonal.At(i, i - 1, e[i]);
                }
            }

            for (var i = 0; i < order; i++)
            {
                eigenValues[i] = new Complex(d[i], e[i]);
            }

            return new UserEvd(eigenVectors, eigenValues, blockDiagonal, isSymmetric);
        }