public static Sign[,] GetCanonicalForm(Sign[,] matrix)
        {
            List<Sign> distinctSigns = new List<Sign>();
            foreach (Sign s in matrix)
                if (!distinctSigns.Contains(s))
                    distinctSigns.Add(s);

            //Get sorted array of distinct signs
            Sign[] distinctSignsArray = distinctSigns.ToArray();
            SortLexicoGraphic(distinctSignsArray);

            //Calculate frequency vectors
            int[][] frequencyVectors = new int[matrix.GetLength(0)][];
            for(int i = 0; i < matrix.GetLength(0); i++)
            {
                Sign[] currentRow = new Sign[matrix.GetLength(0)];
                for(int j = 0; j < currentRow.Length; j++)
                    currentRow[j] = matrix[i, j];
                frequencyVectors[i] = GetSignFrequencyVector(currentRow, distinctSignsArray);
            }

            string[] frequencyVectorStrings = new string[frequencyVectors.Length];
            string[] frequencyVectorBackup = new string[frequencyVectors.Length]; //for comparison
            for (int i = 0; i < frequencyVectors.Length; i++)
                frequencyVectorStrings[i] = GetFrequencyVectorString(frequencyVectors[i]);

            Sign[,] canonical = (Sign[,])matrix.Clone();
            SortLexicoGraphic(frequencyVectorStrings);
            for (int i = 0; i < frequencyVectorStrings.Length; i++ )
            {
                //column j=>i; row j=>i
                int j = frequencyVectorBackup.ToList().IndexOf(frequencyVectorStrings[i]);
                frequencyVectorBackup[j] = null;
                SwitchRows(ref canonical, j, i);
                SwitchColumns(ref canonical, j, i);
            }
            return canonical;
        }
 private static void SwitchRows(ref Sign[,] matrix, int row1, int row2)
 {
     for (int i = 0; i < matrix.GetLength(1); i++)
     {
         Sign temp = matrix[row1, i];
         matrix[row1, i] = matrix[row2, i];
         matrix[row2, i] = temp;
     }
 }
 private static void SwitchColumns(ref Sign[,] matrix, int col1, int col2)
 {
     for (int i = 0; i < matrix.GetLength(0); i++)
     {
         Sign temp = matrix[i, col1];
         matrix[i, col1] = matrix[i, col2];
         matrix[i, col2] = temp;
     }
 }
 private static int[] GetSignFrequencyVector(Sign[] row, Sign[] distinct)
 {
     int[] frequency = new int[distinct.Length];
     for (int i = 0; i < frequency.Length; i++)
     {
         int count = 0;
         foreach (Sign s in row)
             if (s.Equals(distinct[i]))
                 count++;
         frequency[i] = count;
     }
     return frequency;
 }
 //Procedure 3.3
 public static void GetSignMatrixAndCanonicalForm(Graph graph, ref Sign[,] matrix, ref Sign[,] canonical)
 {
     matrix = GetSignMatrix(graph);
     canonical = GetCanonicalForm(matrix);
 }
        public static Sign[,] GetSignMatrix(Graph graph)
        {
            Sign[,] signMatrix = new Sign[graph.Vertices.Count, graph.Vertices.Count];

            foreach (Vertice v1 in graph.Vertices)
            {
                foreach (Vertice v2 in graph.Vertices)
                {
                    Sign sign = new Sign();
                    int i = graph.Vertices.IndexOf(v1);
                    int j = graph.Vertices.IndexOf(v2);
                    Graph collaterial = GetCollaterialGraph(graph, new Edge(v1.index, v2.index));
                    List<List<Vertice>> collPaths = GetDijkstraShortestPaths(collaterial, v1);
                    sign.binarySign = GetCollaterialSign(graph, new Edge(v1.index, v2.index));
                    if (collPaths[j] != null && collPaths[j].Count != 0)
                    {
                        sign.collDistance = collPaths[j].Count - 1;
                    }
                    Graph pair = GetPairGraph(graph, v1, v2);
                    sign.pairNumEdges = pair.Edges.Count;
                    sign.pairNumVertices = pair.Vertices.Count;
                    signMatrix[i, j] = sign;
                }
            }
            return signMatrix;
        }
        public static int[,] GetFrequencyMatrix(Sign[,] matrix)
        {
            List<Sign> distinctSigns = new List<Sign>();
            foreach (Sign s in matrix)
                if (!distinctSigns.Contains(s))
                    distinctSigns.Add(s);

            //Get sorted array of distinct signs
            Sign[] distinctSignsArray = distinctSigns.ToArray();
            SortLexicoGraphic(distinctSignsArray);
            int[] row;
            //Calculate frequency vectors
            //Calculate frequency vectors
            int[][] frequencyVectors = new int[matrix.GetLength(0)][];
            for (int i = 0; i < matrix.GetLength(0); i++)
            {
                Sign[] currentRow = new Sign[matrix.GetLength(0)];
                for (int j = 0; j < currentRow.Length; j++)
                    currentRow[j] = matrix[i, j];
                frequencyVectors[i] = GetSignFrequencyVector(currentRow, distinctSignsArray);
            }
            int[,] frequencyVectorsMatrix = new int[matrix.GetLength(0), distinctSignsArray.Length];
            int columnIndex = 0;
            foreach (int[] row2 in frequencyVectors)
            {
                for (int i = 0; i < row2.Length; i++)
                {
                    frequencyVectorsMatrix[columnIndex, i] = row2[i];
                }

            }
            return frequencyVectorsMatrix;
        }