Exemplo n.º 1
0
        /// <summary>
        /// Точка входа в программу.
        /// </summary>
        /// <param name="args">Аргументы командной строки.</param>
        public static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                Console.WriteLine("Run application with --help");
                Environment.Exit(-1);
            }

            var parser       = new Parser(with => with.HelpWriter = null);
            var parserResult = parser.ParseArguments <CommandLineOptions>(args);

            parserResult
            .WithParsed(options => commandLineOptions = options)
            .WithNotParsed(errs => DisplayHelp(parserResult));

            if (args.Any(a => a.Contains("help") || a.Contains("--version")))
            {
                Environment.Exit(-1);
            }

            Console.WriteLine("#### Program started ####\n");
            var matrix = SquareMatrixHelper.SquareMatrix(commandLineOptions.SquareMatrixEntries.ToArray());

            var x0 = new ColumnVector(commandLineOptions.InitVector.ToArray());
            var t0 = commandLineOptions.InitTime.ToList()[0];
            var t1 = commandLineOptions.InitTime.ToList()[1];
            var n  = commandLineOptions.N;

            var frames = commandLineOptions.Frames;
            var dt     = (t1 - t0) / frames;

            PlotByNMath(frames, matrix, x0, n, t0, dt);
            // PlotByPython(frames, matrix, x0, n, t0, dt);
            Console.WriteLine("#### Program finished ####");
        }
Exemplo n.º 2
0
        /// <summary>
        /// Вычислить значения опорной функции для множества достижимости.
        /// </summary>
        /// <param name="matrix">Исходная матрица</param>
        /// <param name="x0">Начальное положение.</param>
        /// <param name="n">Количество точек для расчёта.</param>
        /// <param name="t0">Начальный момент времени.</param>
        /// <param name="t">Конечный момент времени.</param>
        /// <param name="psiFunc">Фунция для вычисления значений векторов направлений.</param>
        /// <param name="psi">Массив векторов.</param>
        /// <param name="supportingFunctionValues">Массив значений опорной функции множества достижимости.</param>
        private static void CalculateSupportingFunctionOfReachableSet(SquareMatrix matrix, ColumnVector x0, int n,
                                                                      double t0, double t, Func <double, ColumnVector> psiFunc, out ColumnVector[] psi, out double[] supportingFunctionValues)
        {
            supportingFunctionValues = new double[n];

            var dx = 2 * PI / n;

            psi = new ColumnVector[n];
            for (var i = 0; i < n; i++)
            {
                psi[i] = psiFunc(i * dx);
            }
            var expMFunc = SquareMatrixHelper.ExpM(matrix);

            for (var i = 0; i < n; i++)
            {
                supportingFunctionValues[i] = VectorHelper.Prod(expMFunc(t - t0) * x0, psi[i])
                                              + Integrate(expMFunc, psi[i], t0, t, n);
            }
        }
        /// <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);
        }
        /// <summary>
        /// Получить геометрическую кратность собственного значения матрицы.
        /// </summary>
        /// <param name="originMatrix">Исходная матрица.</param>
        /// <param name="eigenvalue">Собственное значение.</param>
        /// <returns></returns>
        public static int GetGeometricMultiplicity(this SquareMatrix originMatrix, double eigenvalue)
        {
            var identityMatrix = SquareMatrixHelper.GetIdentityMatrix(originMatrix.Dimension);

            return(originMatrix.Dimension - (originMatrix - eigenvalue * identityMatrix).GetRank());
        }