/// <summary> /// Деление многочленов /// </summary> public static Polynomial Divide(Polynomial p1, Polynomial p2, int order) { Polynomial res = new Polynomial(); // Локальная переменная, обозначающая результат Abduction(ref p1, order); Abduction(ref p2, order); if (p2 == Polynomial.Zero || p2[0] == 0) { throw new DivideByZeroException("Попытка деления на 0."); } if (p2.CoefList.Count == 1) { int inversedNumber = NumbersGCD(p2[0], order)[1]; for (int i = 0; i < p1.CoefList.Count; i++) { res.Add(Multiply(p1[i], inversedNumber, order)); } return(res); } if (p1.Dimension < p2.Dimension) // Если степень делимого меньше степении делителя, то ответ = 0 { return(new Polynomial(new int[1] { 0 })); } // Заведем переменную, обозначающую промежуточное делимое Polynomial temp = new Polynomial(p1.CoefList); // Алгоритм работает до тех пор, пока степень делимого не меньше, чем степень делителя while (temp.Dimension >= p2.Dimension) { int coef = Divide(temp[0], p2[0], order); // Коэффициент для сокращения старшей степени int a = temp.Dimension; for (int i = 0; i <= p2.Dimension; i++) { // В этом цикле уже происходит сдвиг int x = temp[i] - coef * p2[i]; Abduction(ref x, order); temp[i] = x; } Abduction(ref temp, order); // отбросим впереди стоящие нули int b = temp.Dimension; res.Add(coef); for (int i = 0; i < a - b - 1 && res.Dimension < p1.Dimension - p2.Dimension; i++) { res.Add(0); // Нулями заполним промежуток в частном. } } return(res); }
/// <summary> /// Алгоритм Евклида поиска НОД /// </summary> /// <returns>Возвращает список из 3-х элементов: {НОД, u, v}</returns> public static List <Polynomial> PolynomialGCD(Polynomial p1, Polynomial p2, int order) { Polynomial x = new Polynomial(), y = new Polynomial(); Abduction(ref p1, order); Abduction(ref p2, order); if (p1 == Polynomial.Zero || p1.CoefList[0] == 0) { // Базис рекурсии x.Add(0); y.Add(1); return(new List <Polynomial> { p2, x, y }); } Polynomial x1 = new Polynomial(), y1 = new Polynomial(); // Результаты рекурсивного запуска Polynomial mod = Modulus(p2, p1, order); List <Polynomial> ls = PolynomialGCD(mod, p1, order); x1 = ls[1]; y1 = ls[2]; Polynomial p1_copy = new Polynomial(p1.CoefList); Polynomial p2_copy = new Polynomial(p2.CoefList); Polynomial d = Divide(p2_copy, p1_copy, order); // Применение формулы расширенного алгоритма Евклида Polynomial m = Multiply(d, x1, order); x = Substract(y1, m, order); y = x1; return(new List <Polynomial> { ls[0], x, y }); }
public static IPolynomial Sum(IEnumerable <IPolynomial> polys) { IPolynomial result = null; foreach (IPolynomial p in polys) { if (result == null) { result = p; } else { result = Polynomial.Add(result, p); } } return(result); }