public static ModRationalNumber[][] RemoveNullLines(ModRationalNumber[][] convertedAugmentedMatrix)
        {
            var listNotNullLineIndexes = new List <int>();
            int lineIndex = 0;

            foreach (var line in convertedAugmentedMatrix)
            {
                bool isNullLine = true;
                for (int i = 0; i < line.Length - 1; i++)
                {
                    if (line[i].Numerator != 0)
                    {
                        isNullLine = false;
                        break;
                    }
                }
                if (!isNullLine)
                {
                    listNotNullLineIndexes.Add(lineIndex);
                }
                lineIndex++;
            }
            var array = new ModRationalNumber[listNotNullLineIndexes.Count][];
            int k     = 0;

            foreach (var index in listNotNullLineIndexes)
            {
                array[k++] = convertedAugmentedMatrix[index];
            }
            return(array);
        }
예제 #2
0
 public static ModRationalNumber[][] ToTwoDimensionalModRationalNumberArray(BigInteger[][] arr, BigInteger mod)
 {
     ModRationalNumber[][] array = new ModRationalNumber[arr.Length][];
     for (int i = 0; i < arr.Length; i++)
     {
         array[i] = Converter.ToModRationalNumberArray(arr[i], mod);
     }
     return(array);
 }
예제 #3
0
 public static ModRationalNumber[] ToModRationalNumberArray(BigInteger[] arr, BigInteger mod)
 {
     ModRationalNumber[] array = new ModRationalNumber[arr.Length];
     for (int i = 0; i < arr.Length; i++)
     {
         array[i] = new ModRationalNumber(arr[i], 1, mod);
     }
     return(array);
 }
        public static void ReduceFactorBase(ref BigInteger[] factorBase, ref ModRationalNumber[][] matrix)
        {
            var indexes = new List <int>();

            for (int i = 0, j = 0; i - j < matrix.Length; i++)
            {
                if (matrix[i - j][i].Numerator == 0)
                {
                    j++;
                }
                else
                {
                    indexes.Add(i);
                }
            }
            var reducedFactorBase = new BigInteger[indexes.Count];
            var reducedMatrix     = new ModRationalNumber[indexes.Count][];

            for (int i = 0; i < reducedMatrix.Length; i++)
            {
                reducedMatrix[i] = new ModRationalNumber[indexes.Count + 1];
            }
            int k = 0;

            //удаляем незадействованные простые числа из факторной базы и удаляем нулевые столбцы из матрицы (точнее, создаем новые объекты на основе старых)
            foreach (var index in indexes)
            {
                reducedFactorBase[k] = factorBase[index];
                for (int j = 0; j < reducedMatrix.Length; j++)
                {
                    reducedMatrix[j][k] = new ModRationalNumber(factorBase[index], 1, reducedMatrix[j][k].Mod);
                }
                k++;
            }
            //приписываем к новой матрице справа свободные члены
            for (int i = 0; i < reducedMatrix.Length; i++)
            {
                reducedMatrix[i][reducedMatrix[i].Length - 1] = matrix[i][matrix[i].Length - 1];
            }
            factorBase = reducedFactorBase;
            matrix     = reducedMatrix;
        }
        ////тестовая функция
        //public static double[][] ToTriangularForm(double[][] matrix)
        //{
        //    int n = matrix.Length; //количество строк
        //    int m = matrix[0].Length; //количество столбцов
        //    int currentColumn = 0; //текущий рассматриваемый столбец
        //    int currentRow = 0; //текущая рассматриваемая строка
        //    while (currentRow != n - 1 && currentColumn != m)  //currentColumn < m && currentRow <
        //    {
        //        //шаг 1 - находим ненулевой элемент в текущем столбце и меняем с текущей строкой
        //        int leadingRow = -1; //ряд с ведущим элементом
        //        double leadingElement = 1; //ведущий элемент
        //        for (int tempRow = currentRow; tempRow < n; tempRow++) //идем по одному столбцу и всем строчкам
        //            if (matrix[tempRow][currentColumn] != 0)
        //            {
        //                leadingRow = tempRow;
        //                leadingElement = matrix[tempRow][currentColumn];
        //                break;
        //            }
        //        //if (leadingRow == -1) //если -1, то в столбце все нули, пропускаем столб, но у нас такого не бывает, так как все нулевые столбцы удалены
        //        //{
        //        //    currentColumn++;
        //        //    continue;
        //        //}
        //        if (leadingRow != currentRow) //если первый же элемент ненулевой, то ниче не меняем местами
        //        {
        //            for (int tempColumn = currentColumn; tempColumn < m; tempColumn++)
        //            {
        //                var tmp = matrix[leadingRow][tempColumn];
        //                matrix[leadingRow][tempColumn] = matrix[currentRow][tempColumn];
        //                matrix[currentRow][tempColumn] = tmp;
        //            }
        //        }

        //        //убираем шаг 2, он реализуется в шаге 3
        //        //шаг 2 - создаем временную строку, делим её на ведущий элемент
        //        //var tempCurrentRowCopy = new double[m];
        //        //for (int tempColumn = currentColumn; tempColumn < m; tempColumn++)
        //        //{
        //        //    tempCurrentRowCopy[tempColumn] = matrix[currentRow][tempColumn] / leadingElement;
        //        //}
        //        // if (currentRow == n - 1) break;

        //        //шаг 3 - прибавляем ко всем строкам, ниже текущей, текущую строку, деленную на ведущий элемент и умноженую на первый элемент каждой строки с противоположным знаком
        //        for (int tempRow = currentRow + 1; tempRow < n; tempRow++)
        //        {
        //            double coeff = matrix[tempRow][currentColumn] / (1.0 * leadingElement);
        //            //if (c == 0) continue;
        //            for (int tempColumn = currentColumn; tempColumn < m; tempColumn++)
        //            {

        //                //else matrix[tempRow][tempColumn] = matrix[tempRow][tempColumn] - c * matrix[currentRow][tempColumn];
        //                matrix[tempRow][tempColumn] -= coeff * matrix[currentRow][tempColumn];
        //            }
        //        }


        //        //for (int i = 0; i < m; i++)
        //        //    Console.Write(matrix[currentRow][i] + " ");

        //        //Console.WriteLine();

        //        //step 4
        //        currentRow++;
        //        currentColumn++;
        //    }
        //    //Console.WriteLine("colunn row" + currentRow + " " + currentColumn);
        //    return matrix;
        //}

        //главная функция
        public static ModRationalNumber[][] ToTriangularForm(ModRationalNumber[][] matrix)
        {
            var Mod           = matrix[0][0].Mod; // делаем допущение, что все элементы берутся по одному модулю
            int n             = matrix.Length;    //количество строк
            int m             = matrix[0].Length; //количество столбцов
            int currentColumn = 0;                //текущий рассматриваемый столбец
            int currentRow    = 0;                //текущая рассматриваемая строка

            while (currentRow != n - 1 && currentColumn != m)
            {
                //шаг 1 - находим ненулевой элемент в текущем столбце и меняем с текущей строкой
                int leadingRow     = -1;                               //ряд с ведущим элементом
                var leadingElement = new ModRationalNumber(1, 1, Mod); //ведущий элемент
                for (int tempRow = currentRow; tempRow < n; tempRow++) //идем по одному столбцу и всем строчкам
                {
                    if (matrix[tempRow][currentColumn] != 0)
                    {
                        leadingRow     = tempRow;
                        leadingElement = matrix[tempRow][currentColumn];
                        break;
                    }
                }
                if (leadingRow == -1) //если -1, то в столбце все нули, пропускаем столб
                {
                    currentColumn++;
                    continue;
                }
                if (leadingRow != currentRow) //если первый же элемент ненулевой, то ниче не меняем местами
                {
                    for (int tempColumn = currentColumn; tempColumn < m; tempColumn++)
                    {
                        var tmp = matrix[leadingRow][tempColumn];
                        matrix[leadingRow][tempColumn] = matrix[currentRow][tempColumn];
                        matrix[currentRow][tempColumn] = tmp;
                    }
                }

                //убираем шаг 2, он реализуется в шаге 3
                //шаг 2 - создаем временную строку, делим её на ведущий элемент
                //var tempCurrentRowCopy = new double[m];
                //for (int tempColumn = currentColumn; tempColumn < m; tempColumn++)
                //{
                //    tempCurrentRowCopy[tempColumn] = matrix[currentRow][tempColumn] / leadingElement;
                //}
                // if (currentRow == n - 1) break;

                //шаг 3 - прибавляем ко всем строкам, ниже текущей, текущую строку, деленную на ведущий элемент и умноженую на первый элемент каждой строки с противоположным знаком
                for (int tempRow = currentRow + 1; tempRow < n; tempRow++)
                {
                    var coeff = (matrix[tempRow][currentColumn] / leadingElement);
                    for (int tempColumn = currentColumn; tempColumn < m; tempColumn++)
                    {
                        //if (tempColumn == currentColumn)
                        //{
                        //    matrix[tempRow][tempColumn] = new ModRationalNumber(0, 1, Mod);
                        //    continue;
                        //}
                        matrix[tempRow][tempColumn] -= coeff * matrix[currentRow][tempColumn];
                    }
                }


                //for (int i = 0; i < m; i++)
                //    Console.Write(matrix[currentRow][i] + " ");

                //Console.WriteLine();

                //step 4
                currentRow++;
                currentColumn++;
            }
            //Console.WriteLine("colunn row" + currentRow + " " + currentColumn);
            return(matrix);
        }