public virtual void Add(RingPolynomial poly) { if (!poly.IsNull()) { polyCoef *= poly[poly.degree]; if (poly[poly.degree] != 1) { poly /= poly[poly.degree]; } } for (int i = 0; i < divisors.Count; i++) { if (divisors[i].poly == poly) { divisors[i] = new Divisor { poly = divisors[i].poly, count = divisors[i].count + 1 }; return; } } divisors.Add(new Divisor { poly = poly, count = 1 }); }
public virtual void AddRange(RingDecomposeList polys) { foreach (var divisor in polys.divisors) { for (int i = 0; i < divisor.count; i++) { Add(divisor.poly); } } polyCoef *= polys.polyCoef; }
public static RingBint[][] SolveHSLE(RingBint[,] inp) { Program.Log("Начало упрощения Гаусса:"); if (Program.LogEnabled) { PrintMatrix(inp); } int ioffset = 0; // сдвиг вверх от стандартного диагонального элемента for (int i = 0; i < Math.Min(inp.GetLength(0), inp.GetLength(1)); i++) // проход по диагонали { for (int j = i + 1 - ioffset; j < inp.GetLength(0); j++) // проход по столбцу от i { // находим ненулевой элемент в столбце for (int iNot0 = i - ioffset; iNot0 < inp.GetLength(0); iNot0++) { if (inp[iNot0, i] != 0 && iNot0 != i) { // меняем строки местами для получения диагонального вида for (int k = 0; k < inp.GetLength(1); k++) { RingBint tmp; tmp = inp[i - ioffset, k]; inp[i - ioffset, k] = inp[iNot0, k]; inp[iNot0, k] = tmp; } break; } } if (inp[i - ioffset, i] != 0) { RingBint coef = inp[j, i] / inp[i - ioffset, i]; for (int k = 0; k < inp.GetLength(1); k++) { inp[j, k] -= inp[i - ioffset, k] * coef; } } } if (inp[i - ioffset, i] == 0) { ioffset++; } } Program.Log("Конец упрощения Гаусса:"); if (Program.LogEnabled) { PrintMatrix(inp); } //подсчёт пустых строк матрицы int spareArguments = 0; for (int i = inp.GetLength(0) - 1; i >= 0; i--) { bool isBlankLine = true; for (int j = 0; j < inp.GetLength(1); j++) { if (inp[i, j] != 0) { isBlankLine = false; break; } } if (isBlankLine) { spareArguments++; } else { break; } } //подготовка массива ответов int answerSize = inp.GetLength(0); RingBint[][] answer = new RingBint[spareArguments - 1][]; // особый ответ, который встречается при любом решении 1, 0, 0, ... его вычитаем for (int i = 0; i < spareArguments - 1; i++) { answer[i] = new RingBint[answerSize]; for (int j = 0; j < answerSize; j++) { answer[i][j] = 0; } } //Определение базиса системы bool[] in_basis = new bool[inp.GetLength(0)]; in_basis[0] = false; int _j = 0; for (int i = 0; i < inp.GetLength(1); i++) { if (inp[_j, i] == 0) { in_basis[i + 1] = true; } else { in_basis[i + 1] = false; _j++; } } // поиск остальных ответов int basisIndex = 0; for (int answerNum = 0; answerNum < spareArguments - 1; answerNum++) { for (int i = inp.GetLength(1); i > 0; i--) { if (!in_basis[i]) { int matrixRow = i - 1; while (matrixRow >= 0 && inp[matrixRow, i - 1] == 0) { matrixRow--; } basisIndex = 0; for (int j = inp.GetLength(1); j > i; j--) { if (in_basis[j]) { if (basisIndex == answerNum) { answer[answerNum][i] -= inp[matrixRow, j - 1]; answer[answerNum][j] = 1; } basisIndex++; } else { answer[answerNum][i] -= answer[answerNum][j] * inp[matrixRow, j - 1]; } } answer[answerNum][i] /= inp[matrixRow, i - 1]; } } //те же действия для первого элемента решения (сам остается 0, нужный вектор базиса устанавливается в 1) basisIndex = 0; for (int j = inp.GetLength(1); j > 0; j--) { if (in_basis[j] && basisIndex == answerNum) { answer[answerNum][j] = 1; break; } if (in_basis[j]) { basisIndex++; } } } Program.Log("Независимый базис системы:"); if (Program.LogEnabled) { PrintAnswer(answer); } return(answer); }
public void Clear() { divisors.Clear(); polyCoef = 1; }
public RingDecomposeList(RingDecomposeList list) { polyCoef = list.polyCoef; divisors = new List <Divisor>(list.divisors); }
public RingDecomposeList() { polyCoef = 1; divisors = new List <Divisor>(); }
public static RingBint Pow(RingBint fir, RingBint sec) { return(BigInteger.ModPow(fir, sec, mod)); }