Exemple #1
0
        static void Main(string[] args)
        {
            string matrixProduct;
            string inputFile = "";

            if (args.Length < 1)
            {
                Console.WriteLine("Error: No argument received for input file");
                return;
            }
            if (args.Length < 2)
            {
                Console.WriteLine("No argument received for string. String assumed to be the empty string.");
                inputFile     = args[0];
                matrixProduct = "";
            }
            else
            {
                inputFile     = args[0];
                matrixProduct = args[1];
            }

            var symbols = new HashSet <char>(MatrixSolver.Computations.Constants.RegularLanguage.Symbols);

            foreach (var symbol in matrixProduct)
            {
                if (!symbols.Contains(symbol))
                {
                    throw new ArgumentException($"String contained unknown symbol {symbol}");
                }
            }

            // TODO: Duplicate of main function. Expose this procedure somewhere to reduce duplicate code.
            var json = File.ReadAllText(inputFile);
            var data = JsonConvert.DeserializeObject <InputData>(json);

            data.ThrowIfNull();
            var vectorX  = new ImmutableVector2D(data.VectorX);
            var vectorY  = new ImmutableVector2D(data.VectorY);
            var matrices = data.Matrices.Select(m => new ImmutableMatrix2x2(As2DArray(m, 2, 2))).ToArray();

            Console.WriteLine($"Computing matrix product M = {matrixProduct}");
            var M = RegularLanguageHelper.MatrixProductStringToMatrix(matrixProduct);

            Console.WriteLine($"Calculated M = {M}");

            var expectedY = M * vectorX;

            if (expectedY.Equals(vectorY))
            {
                Console.WriteLine($"Mx = y is solved for M = {M}, x = {vectorX}, y = {vectorY}");
            }
            else
            {
                Console.WriteLine($"Expected vector y = {vectorY}, but instead found y = {expectedY}");
            }
        }
Exemple #2
0
        private static ImmutableMatrix2x2 CalculateMatrixA(ImmutableVector2D vector)
        {
            var euclideanAlgorithmValues = MathematicalHelper.ExtendedEuclideanAlgorithm(vector.UnderlyingVector[0].Numerator, vector.UnderlyingVector[1].Numerator);
            var matrix = new BigRational[2, 2];

            matrix[0, 0] = vector.UnderlyingVector[0];
            matrix[1, 0] = vector.UnderlyingVector[1];
            matrix[0, 1] = -euclideanAlgorithmValues.t;
            matrix[1, 1] = euclideanAlgorithmValues.s;
            return(new ImmutableMatrix2x2(matrix));
        }
Exemple #3
0
 private static void ValidateVectorIsNonZeroAndInteger(ImmutableVector2D vector, string vectorName)
 {
     if (vector.UnderlyingVector.Any(e => !e.IsInteger()))
     {
         throw new ArgumentException($"Vector {vectorName} had a non integer element.");
     }
     if (vector.UnderlyingVector[0] == 0 && vector.UnderlyingVector[1] == 0)
     {
         throw new ArgumentException($"Vector {vectorName} was equal to zero");
     }
 }
        public void Constructor_AllowsValidVectors(int value1, int value2)
        {
            var values = new BigRational[]
            {
                value1,
                value2,
            };

            var vector = new ImmutableVector2D(values);

            Assert.Equal(value1, vector.UnderlyingVector[0]);
            Assert.Equal(value2, vector.UnderlyingVector[1]);
        }
Exemple #5
0
        private static void ValidateVRPVectors(ImmutableVector2D vectorX, ImmutableVector2D vectorY, out BigRational scalar)
        {
            // Validate vectors
            ValidateVectorIsNonZeroAndInteger(vectorX, "x");
            ValidateVectorIsNonZeroAndInteger(vectorY, "y");
            var xGcd = MathematicalHelper.GCD(vectorX.UnderlyingVector[0].Numerator, vectorX.UnderlyingVector[1].Numerator);
            var yGcd = MathematicalHelper.GCD(vectorY.UnderlyingVector[0].Numerator, vectorY.UnderlyingVector[1].Numerator);

            if (xGcd != yGcd)
            {
                throw new ArgumentException($"Vector X GCD had value {xGcd} which was different to Vector Y GCD of {yGcd}. Therefore, there are no solutions in SL(2,Z)");
            }

            scalar = new BigRational(1, xGcd);
        }
        public void MultiplyConstant_Multiplies()
        {
            var values = new BigRational[]
            {
                5,
                7,
            };
            var scalar = 9;

            var vector = new ImmutableVector2D(values);

            var resultingVector = vector * scalar;

            Assert.Equal(45, resultingVector.UnderlyingVector[0]);
            Assert.Equal(63, resultingVector.UnderlyingVector[1]);
        }
        public void Multiply_MultipliesAMatrixAndVector()
        {
            var matrixValues = new BigRational[2, 2]
            {
                { 3, 4 },
                { 5, 6 }
            };
            var vectorValues = new BigRational[2]
            {
                1,
                5
            };

            var matrix = new ImmutableMatrix2x2(matrixValues);
            var vector = new ImmutableVector2D(vectorValues);

            var resultingVector = matrix * vector;

            Assert.Equal(23, resultingVector.UnderlyingVector[0]);
            Assert.Equal(35, resultingVector.UnderlyingVector[1]);
        }
        public void Subtract_SubtractsValues()
        {
            var values1 = new BigRational[]
            {
                5,
                7,
            };
            var values2 = new BigRational[]
            {
                1,
                9,
            };

            var vector1 = new ImmutableVector2D(values1);
            var vector2 = new ImmutableVector2D(values2);

            var resultingVector = vector1 - vector2;

            Assert.Equal(4, resultingVector.UnderlyingVector[0]);
            Assert.Equal(-2, resultingVector.UnderlyingVector[1]);
        }
        public void Add_AddsValues()
        {
            var values1 = new BigRational[]
            {
                5,
                7,
            };
            var values2 = new BigRational[]
            {
                1,
                9,
            };

            var vector1 = new ImmutableVector2D(values1);
            var vector2 = new ImmutableVector2D(values2);

            var resultingVector = vector1 + vector2;

            Assert.Equal(6, resultingVector.UnderlyingVector[0]);
            Assert.Equal(16, resultingVector.UnderlyingVector[1]);
        }
Exemple #10
0
        internal static string GetVectorReachabilityProblemRegex(ImmutableVector2D vectorX, ImmutableVector2D vectorY)
        {
            // Validate input data
            ValidateVRPVectors(vectorX, vectorY, out BigRational scalar);

            // Scale down by gcd(x1, x2) = gcd(y1, y2) = d
            var scaledVectorX = scalar * vectorX;
            var scaledVectorY = scalar * vectorY;
            // Calcualte A(x)^-1, A(y)
            var AxInverse = CalculateMatrixA(scaledVectorX).Inverse();
            var Ay        = CalculateMatrixA(scaledVectorY);

            // Convert each matrix we require for the final form into a canonical string
            var AyAsCanonicalString       = MathematicalHelper.ConvertMatrixToCanonicalString(Ay);
            var AxAsCanonicalString       = MathematicalHelper.ConvertMatrixToCanonicalString(AxInverse);
            var TAsCanonicalString        = String.Join("", Constants.Matrices.GeneratorMatrixIdentifierLookup[GeneratorMatrixIdentifier.T]);
            var TInverseAsCanonicalString = String.Join("", Constants.Matrices.GeneratorMatrixIdentifierLookup[GeneratorMatrixIdentifier.TInverse]);

            string matrixSolutionRegex = String.Format("{0}(({1})*|({2})*){3}",
                                                       AyAsCanonicalString, TAsCanonicalString, TInverseAsCanonicalString, AxAsCanonicalString);

            return(matrixSolutionRegex);
        }
        protected override void OnStartup(StartupEventArgs e)
        {
            // Application is running
            // Process command line args
            var args = e.Args;

            if (args.Length == 0)
            {
                Console.WriteLine("Expected a file path as an argument but received no arguments");
                Shutdown();
                return;
            }
            var    file = args[0];
            string json;

            try
            {
                json = File.ReadAllText(file);
            }
            catch
            {
                Console.WriteLine($"An error occured while reading file {file}");
                Shutdown();
                return;
            }

            InputData data;

            try
            {
                data = JsonConvert.DeserializeObject <InputData>(json);
                data.ThrowIfNull();
            }
            catch
            {
                Console.WriteLine($"File {file} contained invalid data. Please make sure all parameters are set correctly");
                Shutdown();
                return;
            }

            try
            {
                var vectorX  = new ImmutableVector2D(data.VectorX);
                var vectorY  = new ImmutableVector2D(data.VectorY);
                var matrices = data.Matrices.Select(m => new ImmutableMatrix2x2(As2DArray(m, 2, 2))).ToArray();

                Console.WriteLine("Vector Reachability Problem Input data: ");
                Console.WriteLine("-------------------------");
                Console.WriteLine($"M1, ..., Mn =  {String.Join(", ", matrices.Select(m => m.ToString()))}");
                Console.WriteLine($"x =  {vectorX}");
                Console.WriteLine($"y =  {vectorY}");
                Console.WriteLine("-------------------------");

                // Solve equation
                var sw        = Stopwatch.StartNew();
                var automaton = MatrixEquationSolutionFinder.SolveVectorReachabilityProblem(matrices, vectorX, vectorY);
                sw.Stop();
                Console.WriteLine($"Solution found in {sw.ElapsedMilliseconds}ms");

                // Create main application window, starting minimized if specified
                MainWindow mainWindow = new MainWindow(automaton);
                mainWindow.Show();
            }
            catch (ArgumentException exc)
            {
                Console.WriteLine($"VRP data provided from file {file} was invalid: \n{exc.Message}");
                Shutdown();
                return;
            }
            catch (Exception)
            {
                Console.WriteLine("An unexpected error occured while running");
                Shutdown();
                return;
            }
        }
Exemple #12
0
        public static Automaton SolveGeneralisedVectorReachabilityProblem(string languageRegex, string languageName, ImmutableVector2D vectorX, ImmutableVector2D vectorY)
        {
            string matrixSolutionRegex = TimedFunction(() => GetVectorReachabilityProblemRegex(vectorX, vectorY), "Calculate Lvrp regex");

            Console.WriteLine($"Solutions of Mx = y as a regex are of the form:  Lvrp = {matrixSolutionRegex}");
            Console.WriteLine($"Solution intersected with language: {languageName} = {languageRegex}");

            var matrixSolutionAsCanonicalDfa = RegularLanguageRegexToCanonicalWordAcceptingDfa(matrixSolutionRegex, "Lvrp");
            var languageAsCanonicalDfa       = RegularLanguageRegexToCanonicalWordAcceptingDfa(languageRegex, "Lsemigr");

            var intersectedDFA = TimedFunction(() => Constants.Automaton.Canonical
                                               .IntersectionWithDFA(matrixSolutionAsCanonicalDfa)
                                               .IntersectionWithDFA(languageAsCanonicalDfa), $"Intersection of Lcan, Lvrp, {languageName}")
            ;
            var minimizedDfa = TimedFunction(() => intersectedDFA.MinimizeDFA(), "DFA minimization");

            return(minimizedDfa);
        }
Exemple #13
0
        /// <summary>
        /// Finds a solution if it exists to the vector reachability problem.
        /// I.e. given a list of matrices
        /// </summary>
        public static Automaton SolveVectorReachabilityProblem(ImmutableMatrix2x2[] matrices, ImmutableVector2D vectorX, ImmutableVector2D vectorY)
        {
            // Validate input data
            ValidateMatrixList(matrices);
            string matrixProductRegex = TimedFunction(() => GetMatrixSemigroupRegex(matrices), "Calculate Lsemigr regex");

            return(SolveGeneralisedVectorReachabilityProblem(matrixProductRegex, "Lsemigr", vectorX, vectorY));
        }