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); }
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); }
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); }