Esempio n. 1
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);
        }
Esempio n. 2
0
 public void IsSymmetricTest()
 {
     double[,] data = null; // TODO: инициализация подходящего значения
     Matrix target = new Matrix(data); // TODO: инициализация подходящего значения
     bool expected = false; // TODO: инициализация подходящего значения
     bool actual;
     actual = target.IsSymmetric();
     Assert.AreEqual(expected, actual);
     Assert.Inconclusive("Проверьте правильность этого метода теста.");
 }