/// <summary> /// Determina o resultado da adição de dois polinómios gerais. /// </summary> /// <param name="left">O primeiro polinómio a ser adicionado.</param> /// <param name="right">O segundo polinómio a ser adicionado.</param> /// <returns>O resultado da soma dos dois polinómios.</returns> /// <exception cref="ArgumentNullException"> /// Se pelo menos um dos argumentos for nulo. /// </exception> public virtual GeneralDegUnivarPolynomNormalForm <CoeffType, DegreeType> Add( GeneralDegUnivarPolynomNormalForm <CoeffType, DegreeType> left, GeneralDegUnivarPolynomNormalForm <CoeffType, DegreeType> right) { if (left == null) { throw new ArgumentNullException("left"); } else if (right == null) { throw new ArgumentNullException("right"); } else { return(left.Add(right, this.ring)); } }
/// <summary> /// Calcula a soma repetida de um polinómio. /// </summary> /// <param name="element">O polinómio a ser somado.</param> /// <param name="times">O número de vezes que a soma é aplicada.</param> /// <returns>O resultado da soma repetida.</returns> /// <exception cref="ArgumentNullException">Se o argumento for nulo.</exception> public virtual GeneralDegUnivarPolynomNormalForm <CoeffType, DegreeType> AddRepeated( GeneralDegUnivarPolynomNormalForm <CoeffType, DegreeType> element, int times) { if (element == null) { throw new ArgumentNullException("element"); } else { var result = new GeneralDegUnivarPolynomNormalForm <CoeffType, DegreeType>( this.variableName, this.integerNumber); foreach (var termsKvp in element) { result = result.Add( this.ring.AddRepeated(termsKvp.Value, times), termsKvp.Key, this.ring); } return(result); } }
/// <summary> /// Obtém o quociente e o resto da divisão entre dois polinómios. /// </summary> /// <param name="dividend">O dividendo.</param> /// <param name="divisor">O divisor.</param> /// <returns>O quociente e o resto.</returns> /// <exception cref="ArgumentNullException">Caso algum dos argumentos seja nulo.</exception> /// <exception cref="ArgumentException">Se os polinómios contiverem variáveis cujos nomes são diferentes.</exception> /// <exception cref="DivideByZeroException">Se o divisor for uma unidade aditiva.</exception> public DomainResult <GeneralDegUnivarPolynomNormalForm <CoeffType, DegreeType> > GetQuotientAndRemainder( GeneralDegUnivarPolynomNormalForm <CoeffType, DegreeType> dividend, GeneralDegUnivarPolynomNormalForm <CoeffType, DegreeType> divisor) { if (dividend == null) { throw new ArgumentNullException("dividend"); } else if (divisor == null) { throw new ArgumentNullException("divisor"); } else if (divisor.VariableName != divisor.VariableName) { throw new ArgumentException("Polynomials must share the same variable name in order to be operated."); } else { if (this.IsAdditiveUnity(divisor)) { throw new DivideByZeroException("Can't divide by the null polynomial."); } else if (this.IsAdditiveUnity(dividend)) { return(new DomainResult <GeneralDegUnivarPolynomNormalForm <CoeffType, DegreeType> >( this.AdditiveUnity, this.AdditiveUnity)); } else if (this.integerNumber.Compare(divisor.Degree, dividend.Degree) > 0) { return(new DomainResult <GeneralDegUnivarPolynomNormalForm <CoeffType, DegreeType> >( new GeneralDegUnivarPolynomNormalForm <CoeffType, DegreeType>( this.variableName, this.integerNumber), dividend)); } else { var remainderSortedCoeffs = dividend.GetOrderedCoefficients(this.integerNumber); var divisorSorteCoeffs = divisor.GetOrderedCoefficients(this.integerNumber); var quotientCoeffs = new GeneralDegUnivarPolynomNormalForm <CoeffType, DegreeType>( this.variableName, this.integerNumber); var remainderLeadingDegree = remainderSortedCoeffs.Keys[remainderSortedCoeffs.Keys.Count - 1]; var divisorLeadingDegree = divisorSorteCoeffs.Keys[divisorSorteCoeffs.Keys.Count - 1]; var inverseDivisorLeadingCoeff = this.field.MultiplicativeInverse(divisorSorteCoeffs[divisorLeadingDegree]); while (this.integerNumber.Compare(remainderLeadingDegree, divisorLeadingDegree) >= 0 && remainderSortedCoeffs.Count > 0) { var remainderLeadingCoeff = remainderSortedCoeffs[remainderLeadingDegree]; var differenceDegree = this.integerNumber.Add(remainderLeadingDegree, this.integerNumber.AdditiveInverse(divisorLeadingDegree)); var factor = this.field.Multiply( remainderLeadingCoeff, inverseDivisorLeadingCoeff); quotientCoeffs = quotientCoeffs.Add(factor, differenceDegree, this.field); remainderSortedCoeffs.Remove(remainderLeadingDegree); for (int i = 0; i < divisorSorteCoeffs.Keys.Count - 1; ++i) { var currentDivisorDegree = divisorSorteCoeffs.Keys[i]; var currentCoeff = this.field.Multiply( divisorSorteCoeffs[currentDivisorDegree], factor); currentDivisorDegree = this.integerNumber.Add(currentDivisorDegree, differenceDegree); var addCoeff = default(CoeffType); if (remainderSortedCoeffs.TryGetValue(currentDivisorDegree, out addCoeff)) { addCoeff = this.field.Add( addCoeff, this.field.AdditiveInverse(currentCoeff)); if (this.field.IsAdditiveUnity(addCoeff)) { remainderSortedCoeffs.Remove(currentDivisorDegree); } else { remainderSortedCoeffs[currentDivisorDegree] = addCoeff; } } else { remainderSortedCoeffs.Add( currentDivisorDegree, this.field.AdditiveInverse(currentCoeff)); } } if (remainderSortedCoeffs.Count > 0) { remainderLeadingDegree = remainderSortedCoeffs.Keys[remainderSortedCoeffs.Keys.Count - 1]; } else { remainderLeadingDegree = this.integerNumber.AdditiveUnity; } } var remainder = new GeneralDegUnivarPolynomNormalForm <CoeffType, DegreeType>( remainderSortedCoeffs, this.variableName, this.field, this.integerNumber); return(new DomainResult <GeneralDegUnivarPolynomNormalForm <CoeffType, DegreeType> >( quotientCoeffs, remainder)); } } }