Esempio n. 1
0
        /// <summary>
        /// Subtrai dois polinómios.
        /// </summary>
        /// <param name="left">O primeiro polinómio.</param>
        /// <param name="right">O segundo polinómio.</param>
        /// <returns>O polinómio resultante.</returns>
        protected virtual ParsePolynomialItem <T> Subtract(ParsePolynomialItem <T> left, ParsePolynomialItem <T> right)
        {
            var result = new ParsePolynomialItem <T>();

            if (left.ValueType == EParsePolynomialValueType.COEFFICIENT)
            {
                if (right.ValueType == EParsePolynomialValueType.COEFFICIENT)
                {
                    result.Coeff = this.ring.Add(left.Coeff, this.ring.AdditiveInverse(right.Coeff));
                }
                else if (right.ValueType == EParsePolynomialValueType.INTEGER)
                {
                    var rightConversion = this.conversion.InverseConversion(right.Degree);
                    result.Coeff = this.ring.Add(left.Coeff, this.ring.AdditiveInverse(rightConversion));
                }
                else if (right.ValueType == EParsePolynomialValueType.POLYNOMIAL)
                {
                    result.Polynomial = right.Polynomial.Subtract(left.Coeff, this.ring);
                }
            }
            else if (left.ValueType == EParsePolynomialValueType.INTEGER)
            {
                if (right.ValueType == EParsePolynomialValueType.COEFFICIENT)
                {
                    var leftConverted = this.conversion.InverseConversion(left.Degree);
                    result.Coeff = this.ring.Add(leftConverted, this.ring.AdditiveInverse(right.Coeff));
                }
                else if (right.ValueType == EParsePolynomialValueType.INTEGER)
                {
                    result.Degree = this.integerRing.Add(left.Degree, this.integerRing.AdditiveInverse(right.Degree));
                }
                else if (right.ValueType == EParsePolynomialValueType.POLYNOMIAL)
                {
                    var leftConverted = this.conversion.InverseConversion(left.Degree);
                    result.Polynomial.Subtract(leftConverted, this.ring);
                }
            }
            else if (left.ValueType == EParsePolynomialValueType.POLYNOMIAL)
            {
                if (right.ValueType == EParsePolynomialValueType.COEFFICIENT)
                {
                    result.Polynomial = left.Polynomial.Subtract(right.Coeff, this.ring);
                }
                else if (right.ValueType == EParsePolynomialValueType.INTEGER)
                {
                    var rightConverted = this.conversion.InverseConversion(right.Degree);
                    result.Polynomial.Subtract(rightConverted, this.ring);
                }
                else if (right.ValueType == EParsePolynomialValueType.POLYNOMIAL)
                {
                    result.Polynomial = left.Polynomial.Subtract(right.Polynomial, this.ring);
                }
            }

            return(result);
        }
Esempio n. 2
0
        /// <summary>
        /// Obtém o simétrico de um polinómio.
        /// </summary>
        /// <param name="pol">O polinómio.</param>
        /// <returns>O polinómio resultante.</returns>
        protected virtual ParsePolynomialItem <T> Symmetric(ParsePolynomialItem <T> pol)
        {
            var result = new ParsePolynomialItem <T>();

            if (pol.ValueType == EParsePolynomialValueType.COEFFICIENT)
            {
                result.Coeff = this.ring.AdditiveInverse(pol.Coeff);
            }
            else if (pol.ValueType == EParsePolynomialValueType.INTEGER)
            {
                result.Degree = this.integerRing.AdditiveInverse(pol.Degree);
            }
            else if (pol.ValueType == EParsePolynomialValueType.POLYNOMIAL)
            {
                result.Polynomial = pol.Polynomial.GetSymmetric(this.ring);
            }

            return(result);
        }
Esempio n. 3
0
        /// <summary>
        /// Realiza a leitura.
        /// </summary>
        /// <remarks>
        /// Se a leitura não for bem-sucedida, os erros de leitura serão registados no diário
        /// e será retornado o objecto por defeito.
        /// </remarks>
        /// <param name="symbolListToParse">O vector de símbolos a ser lido.</param>
        /// <param name="errorLogs">O objecto que irá manter o registo do diário da leitura.</param>
        /// <returns>O valor lido.</returns>
        public ParsePolynomialItem <CoeffType> Parse(
            ISymbol <string, string>[] symbolListToParse,
            ILogStatus <string, EParseErrorLevel> errorLogs)
        {
            var pol         = default(ParsePolynomialItem <CoeffType>);
            var innerError  = new LogStatus <string, EParseErrorLevel>();
            var parsedCoeff = this.coeffParser.Parse(symbolListToParse, innerError);

            if (innerError.HasLogs(EParseErrorLevel.ERROR))
            {
                if (symbolListToParse.Length == 1)
                {
                    var stringValue = symbolListToParse[0].SymbolValue;
                    if (string.IsNullOrWhiteSpace(stringValue))
                    {
                        errorLogs.AddLog(
                            "Variable name can't be empty.",
                            EParseErrorLevel.ERROR);
                    }
                    else if (char.IsLetter(stringValue[0]))
                    {
                        pol            = new ParsePolynomialItem <CoeffType>();
                        pol.Polynomial = new Polynomial <CoeffType>(this.coeffRing.MultiplicativeUnity, stringValue, this.coeffRing);
                    }
                    else
                    {
                        var degreeError  = new LogStatus <string, EParseErrorLevel>();
                        var integerValue = this.integerParser.Parse(symbolListToParse, degreeError);
                        if (!degreeError.HasLogs(EParseErrorLevel.ERROR))
                        {
                            pol        = new ParsePolynomialItem <CoeffType>();
                            pol.Degree = integerValue;
                        }

                        this.CopyErrors(degreeError, errorLogs);
                    }
                }
                else
                {
                    var degreeError  = new LogStatus <string, EParseErrorLevel>();
                    var integerValue = this.integerParser.Parse(symbolListToParse, degreeError);
                    if (!degreeError.HasLogs(EParseErrorLevel.ERROR))
                    {
                        pol        = new ParsePolynomialItem <CoeffType>();
                        pol.Degree = integerValue;
                    }

                    this.CopyErrors(degreeError, errorLogs);
                }
            }
            else
            {
                pol       = new ParsePolynomialItem <CoeffType>();
                pol.Coeff = parsedCoeff;

                // Poderão existir avisos
                this.CopyErrors(innerError, errorLogs);
            }

            return(pol);
        }
Esempio n. 4
0
        /// <summary>
        /// Determina a potência do polinómio.
        /// </summary>
        /// <param name="left">O polinómio.</param>
        /// <param name="right">O expoente.</param>
        /// <returns>O resultado da potência.</returns>
        /// <exception cref="MathematicsException">Se a operação falhar por vários motivos.</exception>
        protected virtual ParsePolynomialItem <T> Power(ParsePolynomialItem <T> left, ParsePolynomialItem <T> right)
        {
            var result = new ParsePolynomialItem <T>();

            if (left.ValueType == EParsePolynomialValueType.COEFFICIENT)
            {
                if (right.ValueType == EParsePolynomialValueType.COEFFICIENT)
                {
                    var degree = this.conversion.DirectConversion(right.Coeff);
                    result.Coeff = MathFunctions.Power(left.Coeff, degree, this.ring);
                }
                else if (right.ValueType == EParsePolynomialValueType.INTEGER)
                {
                    result.Coeff = MathFunctions.Power(left.Coeff, right.Degree, this.ring);
                }
                else if (right.ValueType == EParsePolynomialValueType.POLYNOMIAL)
                {
                    if (right.Polynomial.IsValue)
                    {
                        var exponent = this.conversion.DirectConversion(right.Polynomial.GetAsValue(this.ring));
                        result.Coeff = MathFunctions.Power(left.Coeff, exponent, this.ring);
                    }
                    else
                    {
                        throw new MathematicsException("Polynomial exponents aren't allowed.");
                    }
                }
            }
            else if (left.ValueType == EParsePolynomialValueType.INTEGER)
            {
                if (right.ValueType == EParsePolynomialValueType.COEFFICIENT)
                {
                    var rightConversion = this.conversion.DirectConversion(right.Coeff);
                    result.Degree = MathFunctions.Power(left.Degree, rightConversion, this.integerRing);
                }
                else if (right.ValueType == EParsePolynomialValueType.INTEGER)
                {
                    result.Degree = MathFunctions.Power(left.Degree, right.Degree, this.integerRing);
                }
                else if (right.ValueType == EParsePolynomialValueType.POLYNOMIAL)
                {
                    if (right.Polynomial.IsValue)
                    {
                        var exponent = this.conversion.DirectConversion(right.Polynomial.GetAsValue(this.ring));
                        result.Degree = MathFunctions.Power(left.Degree, exponent, this.integerRing);
                    }
                    else
                    {
                        throw new MathematicsException("Polynomial exponents aren't allowed.");
                    }
                }
            }
            else if (left.ValueType == EParsePolynomialValueType.POLYNOMIAL)
            {
                if (right.ValueType == EParsePolynomialValueType.COEFFICIENT)
                {
                    var exponent = this.conversion.DirectConversion(right.Coeff);
                    result.Polynomial = left.Polynomial.Power(exponent, this.ring);
                }
                else if (right.ValueType == EParsePolynomialValueType.INTEGER)
                {
                    result.Polynomial = left.Polynomial.Power(right.Degree, this.ring);
                }
                else if (right.ValueType == EParsePolynomialValueType.POLYNOMIAL)
                {
                    if (right.Polynomial.IsValue)
                    {
                        var exponent = this.conversion.DirectConversion(right.Polynomial.GetAsValue(this.ring));
                        result.Polynomial = left.Polynomial.Power(exponent, this.ring);
                    }
                    else
                    {
                        throw new MathematicsException("Polynomial exponents aren't allowed.");
                    }
                }
            }

            return(result);
        }
Esempio n. 5
0
        /// <summary>
        /// Divide dois polinómios.
        /// </summary>
        /// <param name="left">O primeiro polinómio.</param>
        /// <param name="right">O segundo polinómio.</param>
        /// <returns>O polinómio resultante.</returns>
        /// <exception cref="MathematicsException">
        /// Se a operação falhar por vários motivos.
        /// </exception>
        protected virtual ParsePolynomialItem <T> Divide(ParsePolynomialItem <T> left, ParsePolynomialItem <T> right)
        {
            var result = new ParsePolynomialItem <T>();

            if (left.ValueType == EParsePolynomialValueType.COEFFICIENT)
            {
                if (right.ValueType == EParsePolynomialValueType.COEFFICIENT)
                {
                    var field = this.ring as IField <T>;
                    if (field == null)
                    {
                        throw new MathematicsException("The provided ring isn't a field.");
                    }
                    else
                    {
                        result.Coeff = field.Multiply(left.Coeff, field.MultiplicativeInverse(right.Coeff));
                    }
                }
                else if (right.ValueType == EParsePolynomialValueType.INTEGER)
                {
                    var field = this.ring as IField <T>;
                    if (field == null)
                    {
                        throw new MathematicsException("The provided ring isn't a field.");
                    }
                    else
                    {
                        var rightConversion = this.conversion.InverseConversion(right.Degree);
                        result.Coeff = this.ring.Multiply(left.Coeff, field.MultiplicativeInverse(rightConversion));
                    }
                }
                else if (right.ValueType == EParsePolynomialValueType.POLYNOMIAL)
                {
                    if (right.Polynomial.IsValue)
                    {
                        var rightCoeff = right.Polynomial.GetAsValue(this.ring);
                        if (this.ring.IsAdditiveUnity(rightCoeff))
                        {
                            throw new MathematicsException("Division by an additive unity.");
                        }
                        else
                        {
                            var field = this.ring as IField <T>;
                            if (field == null)
                            {
                                throw new MathematicsException("The provided ring isn't a field.");
                            }
                            else
                            {
                                result.Polynomial.Multiply(field.MultiplicativeInverse(left.Coeff), this.ring);
                            }
                        }
                    }
                    else
                    {
                        throw new MathematicsException("Can't divide by a polynomial.");
                    }
                }
            }
            else if (left.ValueType == EParsePolynomialValueType.INTEGER)
            {
                if (right.ValueType == EParsePolynomialValueType.COEFFICIENT)
                {
                    var field = this.ring as IField <T>;
                    if (field == null)
                    {
                        throw new MathematicsException("The provided ring isn't a field.");
                    }
                    else
                    {
                        var leftConverted = this.conversion.InverseConversion(left.Degree);
                        result.Coeff = this.ring.Multiply(leftConverted, field.MultiplicativeInverse(right.Coeff));
                    }
                }
                else if (right.ValueType == EParsePolynomialValueType.INTEGER)
                {
                    if (left.Degree % right.Degree == 0)
                    {
                        result.Degree = left.Degree / right.Degree;
                    }
                    else
                    {
                        throw new MathematicsException("Fractional powers aren't allowed.");
                    }
                }
                else if (right.ValueType == EParsePolynomialValueType.POLYNOMIAL)
                {
                    if (right.Polynomial.IsValue)
                    {
                        var field = this.ring as IField <T>;
                        if (field == null)
                        {
                            throw new MathematicsException("The provided ring isn't a field.");
                        }
                        else
                        {
                            var rightValue    = right.Polynomial.GetAsValue(this.ring);
                            var leftConverted = this.conversion.InverseConversion(left.Degree);
                            result.Coeff = this.ring.Multiply(leftConverted, field.MultiplicativeInverse(rightValue));
                        }
                    }
                    else
                    {
                        throw new MathematicsException("Can't divide by a polynomial.");
                    }
                }
            }
            else if (left.ValueType == EParsePolynomialValueType.POLYNOMIAL)
            {
                if (right.ValueType == EParsePolynomialValueType.COEFFICIENT)
                {
                    var field = this.ring as IField <T>;
                    if (field == null)
                    {
                        throw new MathematicsException("The provided ring isn't a field.");
                    }
                    else
                    {
                        result.Polynomial = left.Polynomial.Multiply(
                            field.MultiplicativeInverse(right.Coeff),
                            this.ring);
                    }
                }
                else if (right.ValueType == EParsePolynomialValueType.INTEGER)
                {
                    var field = this.ring as IField <T>;
                    if (field == null)
                    {
                        throw new MathematicsException("The provided ring isn't a field.");
                    }
                    else
                    {
                        var rightConverted = this.conversion.InverseConversion(right.Degree);
                        result.Polynomial.Multiply(field.MultiplicativeInverse(rightConverted), this.ring);
                    }
                }
                else if (right.ValueType == EParsePolynomialValueType.POLYNOMIAL)
                {
                    if (right.Polynomial.IsValue)
                    {
                        var rightValue = right.Polynomial.GetAsValue(this.ring);
                        var field      = this.ring as IField <T>;
                        if (field == null)
                        {
                            throw new MathematicsException("The provided ring isn't a field.");
                        }
                        else
                        {
                            result.Polynomial = left.Polynomial.Multiply(
                                field.MultiplicativeInverse(rightValue),
                                this.ring);
                        }
                    }
                    else
                    {
                        throw new MathematicsException("Can't divide by a polynomial.");
                    }
                }
            }

            return(result);
        }