private static void swapRows(MyMatrix matrix, int row1, int row2)
 {
     if (row1 == row2)
     {
         return;
     }
     for (int i = 0; i < matrix.columnCount; i++)
     {
         double tmp = matrix[row1, i];
         matrix[row1, i] = matrix[row2, i];
         matrix[row2, i] = tmp;
     }
     return;
 }
        private static int findBiggestValueInColumn(MyMatrix AB, int index)
        {
            double max      = AB[0, index];
            int    rowIndex = index;

            for (int i = 0; i < AB.rowCount; i++)
            {
                if (Math.Abs(AB[i, index]) > max)
                {
                    max      = Math.Abs(AB[i, index]);
                    rowIndex = i;
                }
            }
            return(rowIndex);
        }
        private static void launchZad4()
        {
            string          fileName       = "results2.txt";
            int             polynomialRank = 3;
            ResultsFunction results        = FileHelper.readResultsFromFile(fileName);
            MyMatrix        matrix         = MyMatrix.generateAproxMatrix(polynomialRank, results);
            //Console.Write(matrix.ToString());
            MyMatrix vector = MyMatrix.getVectorFromAproxMatrix(matrix);
            //Console.Write(vector.ToString());
            MyMatrix matrixForGauss = MyMatrix.createMatrixFromVector(polynomialRank, vector);
            //Console.Write(matrixForGauss);
            MyMatrix resultVector = MyMatrix.gauss(matrixForGauss, 1, false);

            Console.Write(resultVector);
        }
        private static MyMatrix countVariables(MyMatrix AB)
        {
            int      n = AB.rowCount;
            MyMatrix X = new MyMatrix(AB.rowCount, 1);

            for (int i = n - 1; i >= 0; i--)
            {
                X[i, 0] = AB[i, n] / AB[i, i];
                for (int k = i - 1; k >= 0; k--)
                {
                    AB[k, n] -= AB[k, i] * X[i, 0];
                }
            }
            return(X);
        }
        public static MyMatrix getVectorFromAproxMatrix(MyMatrix matrix)
        {
            MyMatrix vector = new MyMatrix(1, matrix.columnCount - 2);

            for (int col = 2; col < matrix.columnCount; col++)
            {
                double sum = 0;
                for (int row = 0; row < matrix.rowCount; row++)
                {
                    sum += matrix[row, col];
                }
                vector[0, col - 2] = sum;
            }
            return(vector);
        }
        public static MyMatrix jacobiIterative(MyMatrix A, MyMatrix B)
        {
            int n = A.rowCount;

            if (A.rowCount != B.rowCount || A.rowCount != A.columnCount)
            {
                throw new Exception("Matrix A must be n*n! A rowCount must be equal B rowCount!");
            }
            MyMatrix X_NEW = new MyMatrix(n, 1);
            MyMatrix X_OLD = new MyMatrix(n, 1);
            double   sum   = 0.0;
            int      iter  = 0;

            while (true)
            {
                for (int i = 0; i < n; i++)
                {
                    for (int j = 0; j < n; j++)
                    {
                        if (j != i)
                        {
                            sum -= A[i, j] * X_OLD[j, 0];
                        }
                    }
                    if (A[i, i] == 0.0)
                    {
                        int row = findBiggestValueInColumn(A, i);
                        swapRows(A, i, row);
                        swapRows(B, i, row);
                    }
                    X_NEW[i, 0] = (B[i, 0] + sum) / A[i, i];
                    sum         = 0.0;
                }
                double norm1 = (B - (A * X_NEW)).countNorm();
                double norm2 = B.countNorm();
                if ((norm1 / norm2) < epsilon)
                {
                    break;
                }
                for (int i = 0; i < n; i++)
                {
                    X_OLD[i, 0] = X_NEW[i, 0];
                }
                iter++;
            }
            Console.WriteLine("Jacobi: {0}", iter);
            return(X_NEW);
        }
        private MyMatrix resultByQueue(MyMatrix vector, List <int> queue)
        {
            MyMatrix tmp = new MyMatrix(vector.rowCount, 1);

            for (int i = 0; i < vector.rowCount; i++)
            {
                for (int j = 0; j < vector.columnCount; j++)
                {
                    tmp[i, j] = vector[i, j];
                }
            }
            for (int i = 0; i < vector.rowCount; i++)
            {
                vector[queue[i], 0] = tmp[i, 0];
            }
            return(vector);
        }
        public static MyMatrix createMatrixFromVector(int polynomialRank, MyMatrix vector)
        {
            MyMatrix matrix = new MyMatrix(polynomialRank + 1, polynomialRank + 2);

            for (int row = 0; row < matrix.rowCount; row++)
            {
                for (int col = 0; col < matrix.columnCount; col++)
                {
                    matrix[row, col] = vector[0, row + col];
                }
            }
            for (int row = 0; row < matrix.rowCount; row++)
            {
                matrix[row, matrix.columnCount - 1] = vector[0, 3 + 2 * (polynomialRank - 1) + row];
            }
            return(matrix);
        }
        private static void swapColumns(MyMatrix matrix, int column1, int column2, List <int> queue)
        {
            if (column1 == column2)
            {
                return;
            }
            int tmp = queue[column1];

            queue[column1] = queue[column2];
            queue[column2] = tmp;
            for (int i = 0; i < matrix.rowCount; i++)
            {
                double Tmp = matrix[i, column1];
                matrix[i, column1] = matrix[i, column2];
                matrix[i, column2] = Tmp;
            }
            return;
        }
        public static MyMatrix operator +(MyMatrix a, MyMatrix b)
        {
            if (a.rowCount != b.rowCount || a.columnCount != b.columnCount)
            {
                Console.WriteLine("Matrices sizes are incorrect for operation : a + b!");
                return(null);
            }

            MyMatrix c = new MyMatrix(a.rowCount, a.columnCount);

            for (int i = 0; i < a.rowCount; i++)
            {
                for (int j = 0; j < a.columnCount; j++)
                {
                    c.matrix[i, j] = a.matrix[i, j] + b.matrix[i, j];
                }
            }
            return(c);
        }
        private static void findBiggestValue(MyMatrix AB, int index, List <int> queue)
        {
            //size :  n x (n+1) / 'AB' Matrix
            double max         = AB[index, index];
            int    rowIndex    = index;
            int    columnIndex = index;

            for (int i = index; i < AB.rowCount; i++)
            {
                for (int j = index; j < AB.columnCount - 1; j++)   //columnCount - 1 , to only look at nxn matrix
                {
                    if (Math.Abs(AB[i, j]) > max)
                    {
                        max         = Math.Abs(AB[i, j]);
                        rowIndex    = i;
                        columnIndex = j;
                    }
                }
            }
            swapRows(AB, index, rowIndex);
            swapColumns(AB, index, columnIndex, queue);
        }
        public static MyMatrix operator *(MyMatrix a, MyMatrix b)
        {
            if (a.columnCount != b.rowCount)
            {
                Console.WriteLine("Matrices sizes are incorrect for operation : a * b!");
                return(null);
            }
            MyMatrix c = new MyMatrix(a.rowCount, b.columnCount);

            for (int i = 0; i < a.rowCount; i++)
            {
                for (int j = 0; j < b.columnCount; j++)
                {
                    c.matrix[i, j] = default(double);
                    for (int k = 0; k < b.rowCount; k++)
                    {
                        c.matrix[i, j] += a.matrix[i, k] * b.matrix[k, j];
                    }
                }
            }
            return(c);
        }
        public static MyMatrix gauss(MyMatrix AB, int version, bool optimise)
        {
            if (AB.rowCount != AB.columnCount - 1)
            {
                throw new Exception("Matrix N x (N+1) is required for Gaussian Eliminations!");
            }
            int        n     = AB.rowCount;
            List <int> queue = new List <int>();

            if (version == 1)   //base
            {
                for (int i = 0; i < n; i++)
                {
                    for (int k = i + 1; k < n; k++)
                    {
                        double c = (default(double) - AB[k, i]) / AB[i, i];
                        for (int j = i; j < n + 1; j++)
                        {
                            if (i == j)
                            {
                                AB[k, j] = default(double);
                            }
                            else
                            {
                                AB[k, j] += c * (dynamic)AB[i, j];
                            }
                        }
                    }
                }
            }
            else if (version == 2)     //partial
            {
                for (int i = 0; i < n; i++)
                {
                    double max    = Math.Abs(AB[i, i]);
                    int    maxRow = i;
                    for (int k = i + 1; k < n; k++)
                    {
                        if (Math.Abs(AB[k, i]) > max)
                        {
                            max    = Math.Abs(AB[k, i]);
                            maxRow = k;
                        }
                    }
                    for (int k = i; k < n + 1; k++)
                    {
                        double tmp = AB[maxRow, k];
                        AB[maxRow, k] = AB[i, k];
                        AB[i, k]      = tmp;
                    }

                    for (int k = i + 1; k < n; k++)
                    {
                        double c = (default(double) - AB[k, i]) / AB[i, i];
                        if (optimise == true && c == default(double))
                        {
                            continue;
                        }
                        for (int j = i; j < n + 1; j++)
                        {
                            if (i == j)
                            {
                                AB[k, j] = default(double);
                            }
                            else
                            {
                                AB[k, j] += c * AB[i, j];
                            }
                        }
                    }
                }
            }
            else if (version == 3)     //full
            {
                for (int i = 0; i < n; i++)
                {
                    queue.Add(i);
                }
                for (int i = 0; i < n; i++)
                {
                    findBiggestValue(AB, i, queue);
                    for (int k = i + 1; k < n; k++)
                    {
                        double c = (default(double) - AB[k, i]) / AB[i, i];

                        for (int j = i; j < n + 1; j++)
                        {
                            if (i == j)
                            {
                                AB[k, j] = default(double);
                            }
                            else
                            {
                                AB[k, j] += c * AB[i, j];
                            }
                        }
                    }
                }
            }
            else
            {
                throw new Exception("Unknown Gauss elimination version! 1 - base, 2 - partial, 3 - full");
            }
            MyMatrix X = countVariables(AB);

            if (version == 3)
            {
                X.resultByQueue(X, queue);
            }
            return(X);
        }
        private static void launchGrzybki()
        {
            for (int test = 0; test < amountOfTests; test++)
            {
                Data data = FileHelper.loadData("input/input" + test.ToString() + ".txt");
                Console.WriteLine(data);
                GameStateGenerator gameStateGenerator = new GameStateGenerator();
                gameStateGenerator.generateMatrix(data);
                List <GameState> allStates = gameStateGenerator.allStates;
                int      size   = allStates.Count;
                MyMatrix matrix = new MyMatrix(size, size);
                MyMatrix vector = new MyMatrix(size, 1);
                foreach (GameState state in allStates)
                {
                    if (state.equation.Count == data.cubeSize)
                    {
                        foreach (GameState stateTmp in state.equation)
                        {
                            matrix[state.index, stateTmp.index] = (double)countStatesProbabilities(state.equation, stateTmp, data) / data.probabilitySum;
                        }
                    }
                }
                foreach (GameState state in allStates)
                {
                    vector[state.index, 0] = state.win;
                    if (state.win == 0)
                    {
                        matrix[state.index, state.index] = -1.0;
                    }
                    else if (state.win == 1)
                    {
                        matrix[state.index, state.index] = 1.0;
                    }
                }

                File.WriteAllText("output/matrixOutput" + test.ToString() + ".txt", matrix.ToString());
                File.WriteAllText("output/vectorOutput" + test.ToString() + ".txt", vector.ToString());

                //GameState firstState = new GameState(1, data.playerOnePos, data.playerTwoPos);
                //MonteCarlo monteCarlo = new MonteCarlo(firstState, data);
                //Console.WriteLine(monteCarlo.simulate(1000000));

                Stopwatch stopWatch = new Stopwatch();
                stopWatch.Start();
                MyMatrix result = MyMatrix.gauss(MyMatrix.matrixJoinVector(matrix, vector), 2, false);
                stopWatch.Stop();
                Console.WriteLine("{0} {1}", result[0, 0], stopWatch.Elapsed);

                stopWatch.Start();
                MyMatrix result2 = MyMatrix.gauss(MyMatrix.matrixJoinVector(matrix, vector), 2, true);
                stopWatch.Stop();
                Console.WriteLine("{0} {1}", result2[0, 0], stopWatch.Elapsed);

                stopWatch.Start();
                MyMatrix result3 = MyMatrix.jacobiIterative(new MyMatrix(matrix), new MyMatrix(vector));
                stopWatch.Stop();
                Console.WriteLine("{0} {1}", result3[0, 0], stopWatch.Elapsed);

                stopWatch.Start();
                MyMatrix result4 = MyMatrix.gaussSeidelIterative(new MyMatrix(matrix), new MyMatrix(vector));
                stopWatch.Stop();
                Console.WriteLine("{0} {1}", result4[0, 0], stopWatch.Elapsed);
            }
        }
Пример #15
0
 public static void saveMatrix(string filename, MyMatrix matrix)
 {
     File.WriteAllText(filename, matrix.ToString());
     return;
 }