private static Func <double, SquareMatrix> GetJordanFormExpM(SquareMatrix jordanForm)
        {
            var eigenvalues = jordanForm.Eigenvalues();

            var l1 = eigenvalues[0].Re;
            var l2 = eigenvalues[1].Re;

            // Если l1 и l2 разные.
            if ((l1 - l2).IsNotZero())
            {
                return(t => { return new SquareMatrix(new [, ]
                    {
                        { Math.Exp(l1 * t), 0.0 },
                        { 0.0, Math.Exp(l2 * t) }
                    }); });
            }
            if (jordanForm.GetGeometricMultiplicity(l1) == 2)
            {
                return(t => { return new SquareMatrix(new [, ]
                    {
                        { Math.Exp(l1 * t), 0.0 },
                        { 0.0, Math.Exp(l1 * t) }
                    }); });
            }

            return(t => { return new SquareMatrix(new [, ]
                {
                    { Math.Exp(l1 * t), t * Math.Exp(l1 * t) },
                    { 0.0, Math.Exp(l1 * t) }
                }); });
        }
        /// <summary>
        /// Получить собственные (и присоединённые) векторы матрицы.
        /// </summary>
        /// <param name="originMatrix">Входная матрица.</param>
        /// <returns>Матрица, состоящая из комплексных чисел.</returns>
        public static SquareMatrix GetEigenvectors(this SquareMatrix originMatrix)
        {
            var eigenvalues = originMatrix.Eigenvalues();

            if (eigenvalues.Any(v => v.Im != 0))
            {
                throw new ComplexEigenvaluesException("Комплексные собственные значения не поддерживаются.");
            }

            const double max = 1.0;
            const double min = 0.0;

            var eigenvectors   = new SquareMatrix(originMatrix.Dimension);
            var identityMatrix = SquareMatrixHelper.GetIdentityMatrix(originMatrix.Dimension);

            // Два различных собственных значения.
            if (!(eigenvalues[0] - eigenvalues[1]).Re.IsZero())
            {
                var eigenSol1 = originMatrix - eigenvalues[0].Re * identityMatrix;
                var eigenSol2 = originMatrix - eigenvalues[1].Re * identityMatrix;

                if (!eigenSol1.Row(0).IsZero())
                {
                    eigenvectors = new SquareMatrix(new [, ]
                    {
                        { eigenSol1[0, 1], eigenSol2[0, 1] },
                        { -eigenSol1[0, 0], -eigenSol2[0, 0] }
                    });
                }
                else
                {
                    eigenvectors = new SquareMatrix(new [, ]
                    {
                        { eigenSol1[1, 1], eigenSol2[0, 1] },
                        { -eigenSol1[1, 0], -eigenSol2[0, 0] }
                    });
                }
            }
            else if ((eigenvalues[0] - eigenvalues[1]).Re.IsZero())
            {
                while (true)
                {
                    if ((originMatrix - eigenvalues[1].Re * identityMatrix).GetRank() != 0)
                    {
                        var possibleAttachedVectorEntries = GetRandomColumnVector(max, min);
                        var possibleAttachedVector        = new ColumnVector(possibleAttachedVectorEntries);
                        var possibleEigenvector           = (originMatrix - eigenvalues[1].Re * identityMatrix) * possibleAttachedVector;

                        if (originMatrix * possibleAttachedVector == eigenvalues[1].Re * possibleAttachedVector)
                        {
                            continue;
                        }

                        if (possibleEigenvector.OneNorm().IsZero())
                        {
                            continue;
                        }
                        if (((originMatrix - eigenvalues[0].Re * identityMatrix) * possibleEigenvector).OneNorm().IsZero())
                        {
                            eigenvectors = new SquareMatrix(new [, ]
                            {
                                { possibleEigenvector[0], possibleAttachedVector[0] },
                                { possibleEigenvector[1], possibleAttachedVector[1] }
                            });
                            break;
                        }
                    }
                    eigenvectors = new SquareMatrix(new [, ]
                    {
                        { 1.0, 0.0 },
                        { 0.0, 1.0 }
                    });
                    break;
                }
            }

            return(eigenvectors);
        }
Exemplo n.º 3
0
        public void DifficultEigenvalue()
        {
            SquareMatrix A = new SquareMatrix(4);
            A[0, 0] = 0.0; A[0, 1] = 2.0; A[0, 2] = 0.0; A[0, 3] = -1.0;
            A[1, 0] = 1.0; A[1, 1] = 0.0; A[1, 2] = 0.0; A[1, 3] = 0.0;
            A[2, 0] = 0.0; A[2, 1] = 1.0; A[2, 2] = 0.0; A[2, 3] = 0.0;
            A[3, 0] = 0.0; A[3, 1] = 0.0; A[3, 2] = 1.0; A[3, 3] = 0.0;

            Complex[] zs = A.Eigenvalues();
            foreach (Complex z in zs) {
                Console.WriteLine("{0} ({1} {2})", z, ComplexMath.Abs(z), ComplexMath.Arg(z));
            }
        }
Exemplo n.º 4
0
        public void TimedEigenvalues()
        {
            int n = 200;
            Random rng = new Random(1);

            SquareMatrix A = new SquareMatrix(n);
            for (int r = 0; r < n; r++) {
                for (int c = 0; c < n; c++) {
                    A[r, c] = rng.NextDouble();
                }
            }

            Stopwatch s = Stopwatch.StartNew();
            Complex[] eigenvalues = A.Eigenvalues();
            s.Stop();
            Console.WriteLine(s.ElapsedMilliseconds);
        }
Exemplo n.º 5
0
        public void KnownEigenvalues()
        {
            // This example is presented in http://people.inf.ethz.ch/arbenz/ewp/Lnotes/chapter3.pdf
            // It has eigenvalues 1 \pm 2i, 3, 4, 5 \pm 6i

            double[,] souce = new double[,] {
                { 7, 3, 4, -11, -9, -2},
                {-6, 4, -5, 7, 1, 12},
                {-1, -9, 2, 2, 9, 1},
                {-8, 0, -1, 5, 0, 8},
                {-4, 3, -5, 7, 2, 10},
                {6, 1, 4, -11, -7, -1}
            };

            SquareMatrix A = new SquareMatrix(6);
            for (int r = 0; r < souce.GetLength(0); r++) {
                for (int c = 0; c < souce.GetLength(1); c++) {
                    A[r, c] = souce[r, c];
                }
            }

            Complex[] eigenvalues = A.Eigenvalues();

            foreach (Complex eigenvalue in eigenvalues) {
                Console.WriteLine(eigenvalue);
            }
        }