コード例 #1
0
        /// <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));
                }
            }
        }