Search in sources :

Example 21 with Rational

use of com.sri.ai.util.math.Rational in project aic-expresso by aic-sri-international.

the class DefaultMonomial method make.

private static Monomial make(List<Expression> numericConstantsAndTerms) {
    Rational numericFactor = Rational.ONE;
    Map<Expression, Rational> factorToPower = new LinkedHashMap<>();
    for (Expression numericConstantOrTerm : numericConstantsAndTerms) {
        if (Expressions.isNumber(numericConstantOrTerm)) {
            numericFactor = numericFactor.multiply(numericConstantOrTerm.rationalValue());
        } else {
            // Is a term
            Expression factor = numericConstantOrTerm;
            Rational power = Rational.ONE;
            boolean attemptFlattening = false;
            // Handle case where factor is negated, e.g.: -x
            if (factor.hasFunctor(MINUS) && factor.numberOfArguments() == 1) {
                factor = factor.get(0);
                // i.e. same as having an explicit constant '-1' multiplicand in the expression
                numericFactor = numericFactor.negate();
                attemptFlattening = true;
            }
            // If exponentiation using a constant integer exponent then we need to extract the factor and the power
            if (Expressions.hasFunctor(factor, Exponentiation.EXPONENTIATION_FUNCTOR)) {
                Expression simplifiedPower = simplifyExponentIfPossible(factor.get(1));
                if (isLegalExponent(simplifiedPower)) {
                    power = simplifiedPower.rationalValue();
                    // The factor is actually the base of the exponentiation
                    factor = factor.get(0);
                    attemptFlattening = true;
                } else if (!simplifiedPower.equals(factor.get(1))) {
                    // Use the simplified version of the non legal exponent in the factor
                    // i.e. is a non numeric factor where the exponent has been simplified
                    // as best as possible.
                    factor = apply(EXPONENTIATION_FUNCTOR, factor.get(0), simplifiedPower);
                }
            }
            // Handle nested *'s arguments
            if (factor.hasFunctor(TIMES)) {
                attemptFlattening = true;
            }
            // We attempt flattening if we were/are able to simplify the factor in some way
            if (attemptFlattening) {
                // Treat the factor as a Monomial and merge it in
                // This lets you handle nested monomial expressions
                // in a simplified/recursive manner.
                Monomial factorAsMonomial = make(Times.getMultiplicands(factor));
                // Need to raise to the current power
                factorAsMonomial = factorAsMonomial.exponentiate(power.intValue());
                numericFactor = numericFactor.multiply(factorAsMonomial.getNumericFactor());
                List<Expression> factors = factorAsMonomial.getOrderedNonNumericFactors();
                List<Rational> powers = factorAsMonomial.getPowersOfNonNumericFactors();
                int factorSize = factors.size();
                for (int i = 0; i < factorSize; i++) {
                    updateFactorToPowerMap(factorToPower, factors.get(i), powers.get(i));
                }
            } else {
                updateFactorToPowerMap(factorToPower, factor, power);
            }
        }
    }
    Monomial result = null;
    if (numericFactor.equals(Rational.ZERO)) {
        result = ZERO;
    } else {
        List<Expression> orderedFactors = new ArrayList<>(factorToPower.keySet());
        Collections.sort(orderedFactors, _factorComparator);
        List<Rational> orderedPowers = new ArrayList<>(orderedFactors.size());
        orderedFactors.forEach(factor -> orderedPowers.add(factorToPower.get(factor)));
        result = make(numericFactor, orderedFactors, orderedPowers);
    }
    return result;
}
Also used : Rational(com.sri.ai.util.math.Rational) Expression(com.sri.ai.expresso.api.Expression) Monomial(com.sri.ai.grinder.polynomial.api.Monomial) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap)

Example 22 with Rational

use of com.sri.ai.util.math.Rational in project aic-expresso by aic-sri-international.

the class DefaultPolynomial method makeFromMonomial.

private static Polynomial makeFromMonomial(Expression monomialExpression, List<Expression> variables) {
    Monomial monomial = DefaultMonomial.make(monomialExpression);
    if (!monomial.isNumericConstant()) {
        // TODO: (Sept 2017) This treatment of coefficient factors (basically, combining factors into a single one)
        // seems overly complicated and unnecessary.
        // Need to pull out the factors that need to be treated together as a single factor
        // based on the polynomial's signature of factors.
        Monomial coefficient = monomial.getCoefficient(variables);
        if (!coefficient.isNumericConstant()) {
            // Have factors of the monomial that need to be treated as a single constant
            // based on the polynomials signature of factors.
            List<Expression> orderedFactors = new ArrayList<>();
            Map<Expression, Rational> factorToPower = new HashMap<>();
            orderedFactors.add(coefficient);
            factorToPower.put(coefficient, Rational.ONE);
            Set<Expression> coefficientFactors = coefficient.getFactors();
            for (Expression factor : monomial.getOrderedNonNumericFactors()) {
                if (!coefficientFactors.contains(factor)) {
                    orderedFactors.add(factor);
                    factorToPower.put(factor, monomial.getPowerOfFactor(factor));
                }
            }
            Rational numericConstant = monomial.getNumericFactor();
            // of the variables.
            if (coefficient.getNumericFactor().equals(numericConstant)) {
                // i.e. numeric constant was in variables.
                numericConstant = Rational.ONE;
            }
            List<Rational> orderedPowers = new ArrayList<>();
            Collections.sort(orderedFactors, _factorComparator);
            orderedFactors.forEach(factor -> orderedPowers.add(factorToPower.get(factor)));
            monomial = DefaultMonomial.make(numericConstant, orderedFactors, orderedPowers);
        }
    }
    Polynomial result = new DefaultPolynomial(list(monomial), variables);
    return result;
}
Also used : Polynomial(com.sri.ai.grinder.polynomial.api.Polynomial) Rational(com.sri.ai.util.math.Rational) Expression(com.sri.ai.expresso.api.Expression) Expressions.containsAnyOfGivenCollectionAsSubExpression(com.sri.ai.expresso.helper.Expressions.containsAnyOfGivenCollectionAsSubExpression) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Monomial(com.sri.ai.grinder.polynomial.api.Monomial) ArrayList(java.util.ArrayList)

Example 23 with Rational

use of com.sri.ai.util.math.Rational in project aic-expresso by aic-sri-international.

the class DefaultPolynomial method addMonomialsWithSameSignature.

private Monomial addMonomialsWithSameSignature(Monomial m1, Monomial m2) {
    Monomial result;
    // Both have the same signature
    Monomial m1Coefficient = m1.getCoefficient(getVariables());
    Monomial m2Coefficient = m2.getCoefficient(getVariables());
    Expression summedCoefficient;
    if (m1Coefficient.isNumericConstant() && m2Coefficient.isNumericConstant()) {
        // We can add them
        summedCoefficient = Expressions.makeSymbol(m1Coefficient.getNumericFactor().add(m2Coefficient.getNumericFactor()));
    } else if (m1Coefficient.equals(m2Coefficient)) {
        // Compactly represent non-numeric coefficients that are equal
        summedCoefficient = new DefaultFunctionApplication(TIMES_FUNCTOR, Arrays.asList(Expressions.TWO, m1Coefficient));
    } else {
        List<Expression> plusArgs = new ArrayList<>();
        if (!m1Coefficient.isZero()) {
            plusArgs.add(m1Coefficient);
        }
        if (!m2Coefficient.isZero()) {
            plusArgs.add(m2Coefficient);
        }
        if (plusArgs.size() == 2) {
            summedCoefficient = new DefaultFunctionApplication(PLUS_FUNCTOR, Arrays.asList(m1Coefficient, m2Coefficient));
        } else {
            summedCoefficient = plusArgs.get(0);
        }
    }
    if (!Expressions.ZERO.equals(summedCoefficient)) {
        List<Expression> args = new ArrayList<Expression>();
        Rational numericConstantFactor = Rational.ONE;
        if (Expressions.isNumber(summedCoefficient)) {
            numericConstantFactor = summedCoefficient.rationalValue();
        } else if (summedCoefficient.hasFunctor(TIMES_FUNCTOR)) {
            // i.e. coefficients are equal so write in compact form.
            numericConstantFactor = summedCoefficient.get(0).rationalValue();
            args.add(summedCoefficient.get(1));
        } else {
            args.add(summedCoefficient);
        }
        args.addAll(getVariables());
        Collections.sort(args, _factorComparator);
        List<Rational> orderedPowers = new ArrayList<>();
        for (Expression factor : args) {
            if (factor == summedCoefficient) {
                orderedPowers.add(Rational.ONE);
            } else {
                orderedPowers.add(m1.getPowerOfFactor(factor));
            }
        }
        result = DefaultMonomial.make(numericConstantFactor, args, orderedPowers);
    } else {
        result = DefaultMonomial.ZERO;
    }
    return result;
}
Also used : Rational(com.sri.ai.util.math.Rational) Expression(com.sri.ai.expresso.api.Expression) Expressions.containsAnyOfGivenCollectionAsSubExpression(com.sri.ai.expresso.helper.Expressions.containsAnyOfGivenCollectionAsSubExpression) Monomial(com.sri.ai.grinder.polynomial.api.Monomial) ArrayList(java.util.ArrayList) DefaultFunctionApplication(com.sri.ai.expresso.core.DefaultFunctionApplication) ArrayList(java.util.ArrayList) List(java.util.List)

Example 24 with Rational

use of com.sri.ai.util.math.Rational in project aic-expresso by aic-sri-international.

the class PolynomialIntegration method indefiniteIntegral.

/**
 * Takes a polynomial:<br>
 * <pre>
 * t_1 * variable ^ n + ... + t_n * variable + t_{n+1}
 * </pre>
 * and returns the polynomial equivalent to:<br>
 * <pre>
 * (t_1/(n + 1)) * variable ^ {n + 1} + ... + (t_n / 2) * variable^2 + t_{n+1}*variable
 * </pre>
 *
 * @param polynomial
 *        the polynomial the indefinite integral is to be found for.
 * @param variable
 *        the variable integration is with respect to.
 * @return the indefinite integral of the given polynomial.
 */
public static Polynomial indefiniteIntegral(Polynomial polynomial, Expression variable) {
    List<Expression> variables = new ArrayList<>(polynomial.getVariables());
    if (!variables.contains(variable)) {
        variables.add(variable);
        // recognized by the polynomial as being one (this is implied).
        try {
            polynomial = DefaultPolynomial.make(polynomial, variables);
        } catch (IllegalArgumentException exception) {
            throw new IllegalArgumentException("Integrating " + polynomial + " requires it to be an integral in the integral variable " + variable + " but it is not because " + exception);
        }
    }
    // Get the integrals of its terms
    List<Expression> integralsOfTerms = new ArrayList<>();
    for (Monomial term : polynomial.getMonomials()) {
        // indefinite integral of the term is:
        // &#x222b; a*x^n dx = a*(x^(n+1)/(n+1) + C
        // NOTE: we do not need to worry about the case where n = -1 (i.e. division by zero case)
        // as our support for Polynomials only allows for positive integer exponents.
        List<Expression> factorsOfIntegral = new ArrayList<>();
        boolean variableFactorAdded = false;
        for (Expression factor : term.getFactors()) {
            Rational powerOfFactor = term.getPowerOfFactor(factor);
            if (factor.equals(variable)) {
                Expression nPlusOne = Expressions.makeSymbol(powerOfFactor.add(1));
                factorsOfIntegral.add(Division.make(Exponentiation.make(variable, nPlusOne), nPlusOne));
                variableFactorAdded = true;
            } else {
                factorsOfIntegral.add(Exponentiation.make(factor, powerOfFactor));
            }
        }
        // &#x222b; a dx = a*x + C
        if (!variableFactorAdded) {
            factorsOfIntegral.add(variable);
        }
        integralsOfTerms.add(DefaultMonomial.make(Times.make(factorsOfIntegral)));
    }
    // The integral of any polynomial is the sum of the integrals of its terms.
    Polynomial result = DefaultPolynomial.make(Plus.make(integralsOfTerms), variables);
    return result;
}
Also used : Polynomial(com.sri.ai.grinder.polynomial.api.Polynomial) Rational(com.sri.ai.util.math.Rational) Expression(com.sri.ai.expresso.api.Expression) ArrayList(java.util.ArrayList) Monomial(com.sri.ai.grinder.polynomial.api.Monomial)

Example 25 with Rational

use of com.sri.ai.util.math.Rational in project aic-expresso by aic-sri-international.

the class DifferenceArithmeticTheory method thereIsAtMostOnePositiveAndOneNegativeVariableMonomial.

private static boolean thereIsAtMostOnePositiveAndOneNegativeVariableMonomial(Polynomial polynomial) {
    boolean result = true;
    int numberOfPositiveVariableTerms = 0;
    int numberOfNegativeVariableTerms = 0;
    for (Monomial monomial : polynomial.getMonomials()) {
        if (monomial.degree() == 1) {
            Rational coefficient = monomial.getNumericFactor();
            if (coefficient.isPositive()) {
                numberOfPositiveVariableTerms++;
            } else if (coefficient.isNegative()) {
                numberOfNegativeVariableTerms++;
            } else {
                throw new Error("Monomial with zero coefficient should not be present: " + monomial);
            }
        }
        if (numberOfPositiveVariableTerms > 1 || numberOfNegativeVariableTerms > 1) {
            result = false;
            break;
        }
    }
    return result;
}
Also used : Rational(com.sri.ai.util.math.Rational) Monomial(com.sri.ai.grinder.polynomial.api.Monomial) SingleVariableConstraint(com.sri.ai.grinder.api.SingleVariableConstraint)

Aggregations

Rational (com.sri.ai.util.math.Rational)72 Expression (com.sri.ai.expresso.api.Expression)33 Test (org.junit.Test)26 Monomial (com.sri.ai.grinder.polynomial.api.Monomial)11 ArrayList (java.util.ArrayList)10 Type (com.sri.ai.expresso.api.Type)9 IntensionalSet (com.sri.ai.expresso.api.IntensionalSet)8 IndexExpressionsSet (com.sri.ai.expresso.api.IndexExpressionsSet)7 RealExpressoType (com.sri.ai.expresso.type.RealExpressoType)6 RealInterval (com.sri.ai.expresso.type.RealInterval)6 List (java.util.List)6 ExtensionalIndexExpressionsSet (com.sri.ai.expresso.core.ExtensionalIndexExpressionsSet)5 Symbol (com.sri.ai.expresso.api.Symbol)4 Expressions.makeSymbol (com.sri.ai.expresso.helper.Expressions.makeSymbol)4 Categorical (com.sri.ai.expresso.type.Categorical)4 FunctionType (com.sri.ai.expresso.type.FunctionType)4 TupleType (com.sri.ai.expresso.type.TupleType)4 Polynomial (com.sri.ai.grinder.polynomial.api.Polynomial)4 LambdaExpression (com.sri.ai.expresso.api.LambdaExpression)3 HashMap (java.util.HashMap)3