Search in sources :

Example 56 with Rational

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

the class DefaultMonomial method computeInnerExpression.

@Override
protected Expression computeInnerExpression() {
    Expression result;
    if (isNumericConstant()) {
        result = numericFactorExpression;
    } else {
        List<Expression> arguments = makeListOfArgumentsWithRequiredSize();
        boolean isNegative = getNumericFactor().isNegative();
        Rational numericFactorToUse = determineNumericFactorToUse(isNegative);
        gatherNumericConstantIfNotOne(numericFactorToUse, arguments);
        gatherFactorsToTheirPowers(arguments);
        Expression productOfFactors = Times.make(arguments);
        result = makeResultWithAppropriateSign(isNegative, productOfFactors);
    }
    return result;
}
Also used : Rational(com.sri.ai.util.math.Rational) Expression(com.sri.ai.expresso.api.Expression)

Example 57 with Rational

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

the class DefaultMonomial method times.

@Override
public Monomial times(Monomial multiplier) {
    Monomial result;
    // Optimization: return 0 if either numeric factor is 0
    if (isZero() || multiplier.isZero()) {
        result = ZERO;
    } else if (isOne()) {
        // Optimization, neutral element
        result = multiplier;
    } else if (multiplier.isOne()) {
        // Optimization, neutral element
        result = this;
    } else {
        List<Expression> combinedNonNumericFactors = Monomial.orderedUnionOfNonNumericFactors(this, multiplier);
        List<Rational> thisSignature = this.getSignature(combinedNonNumericFactors);
        List<Rational> multiplierSignature = multiplier.getSignature(combinedNonNumericFactors);
        Rational resultNumericFactor = getNumericFactor().multiply(multiplier.getNumericFactor());
        List<Rational> resultPowers = zipWith((power1, power2) -> power1.add(power2), thisSignature, multiplierSignature);
        result = make(resultNumericFactor, combinedNonNumericFactors, resultPowers);
    }
    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)

Example 58 with Rational

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

the class DefaultMonomial method make.

static DefaultMonomial make(Rational numericFactor, List<Expression> orderedNonNumericFactors, List<Rational> orderedNonNumericPowers) {
    DefaultMonomial result;
    // if numeric constant is 0, the whole expression is 0, so reduce to that.
    if (numericFactor.equals(Rational.ZERO)) {
        result = new DefaultMonomial(Rational.ZERO, Collections.emptyList(), Collections.emptyList());
    } else {
        List<Expression> factors = new ArrayList<>(orderedNonNumericFactors.size());
        List<Rational> powers = new ArrayList<>(orderedNonNumericPowers.size());
        for (int i = 0; i < orderedNonNumericPowers.size(); i++) {
            Rational power = orderedNonNumericPowers.get(i);
            // Power must not be negative as this is illegal for a monomial
            if (power.signum() == -1) {
                throw new IllegalArgumentException("Negative powers are not allowed.");
            }
            // 0 power means the factor is equivalent to 1 so we can just drop it.
            if (power.signum() > 0) {
                Expression factor = orderedNonNumericFactors.get(i);
                factors.add(factor);
                powers.add(power);
            }
        }
        result = new DefaultMonomial(numericFactor, factors, powers);
    }
    return result;
}
Also used : Rational(com.sri.ai.util.math.Rational) Expression(com.sri.ai.expresso.api.Expression) ArrayList(java.util.ArrayList)

Example 59 with Rational

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

the class DefaultPolynomial method add.

@Override
public Polynomial add(Polynomial summand) throws IllegalArgumentException {
    assertSameVariables(summand);
    Polynomial result;
    if (isZero()) {
        result = summand;
    } else if (summand.isZero()) {
        result = this;
    } else {
        List<Monomial> summands = new ArrayList<>();
        Set<List<Rational>> combinedSignatures = new LinkedHashSet<>(this.getMonomials().size() + summand.getMonomials().size());
        combinedSignatures.addAll(this.getMapFromSignatureToMonomial().keySet());
        combinedSignatures.addAll(summand.getMapFromSignatureToMonomial().keySet());
        for (List<Rational> signature : combinedSignatures) {
            // NOTE: at least one of these assignments is guaranteed to be non-null.
            Monomial m1 = this.getMapFromSignatureToMonomial().get(signature);
            Monomial m2 = summand.getMapFromSignatureToMonomial().get(signature);
            if (m1 == null) {
                if (!m2.isZero()) {
                    summands.add(m2);
                }
            } else if (m2 == null) {
                if (!m1.isZero()) {
                    summands.add(m1);
                }
            } else {
                Monomial sum = addMonomialsWithSameSignature(m1, m2);
                if (!sum.isZero()) {
                    summands.add(sum);
                }
            }
        }
        // In case all the summands cancel each other out
        if (summands.isEmpty()) {
            result = makeFromMonomial(Expressions.ZERO, variables);
        } else {
            result = new DefaultPolynomial(summands, getVariables());
        }
    }
    return result;
}
Also used : Polynomial(com.sri.ai.grinder.polynomial.api.Polynomial) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) Set(java.util.Set) Rational(com.sri.ai.util.math.Rational) Monomial(com.sri.ai.grinder.polynomial.api.Monomial) ArrayList(java.util.ArrayList) List(java.util.List)

Example 60 with Rational

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

the class PolynomialSummation method sum.

/**
 * Compute the sum for the summation of a polynomial.
 *
 * @param indexOfSummation
 *        the index variable of the summation.
 * @param lowerBoundExclusive
 *        the lower bound of the summation.
 * @param upperBoundInclusive
 *        the upper bound of the summation.
 * @param summand
 *        the polynomial to be summed.
 * @return the sum of the given summation.
 */
public static Polynomial sum(Expression indexOfSummation, Expression lowerBoundExclusive, Expression upperBoundInclusive, Polynomial summand) {
    Polynomial result;
    List<Expression> indexVariable = Arrays.asList(indexOfSummation);
    Polynomial summandAsPolynomialOfIndex = DefaultPolynomial.make(summand, indexVariable);
    int n = summandAsPolynomialOfIndex.degree();
    // 
    // collect the t coefficients
    List<Expression> tCoefficients = new ArrayList<>(n);
    for (int i = 0; i <= n; i++) {
        tCoefficients.add(Expressions.ZERO);
    }
    for (int i = 0; i < summandAsPolynomialOfIndex.numberOfTerms(); i++) {
        Monomial term = summandAsPolynomialOfIndex.getMonomials().get(i);
        tCoefficients.set(term.getPowerOfFactor(indexOfSummation).intValue(), term.getCoefficient(indexVariable));
    }
    // 
    // compute polynomials R_i(x) = (x + l)^i for each i
    Expression indexOfSummationPlusLowerBound = new DefaultFunctionApplication(PLUS_FUNCTOR, Arrays.asList(indexOfSummation, lowerBoundExclusive));
    Polynomial indexOfSummationPlusLowerBoundPolynomial = DefaultPolynomial.make(indexOfSummationPlusLowerBound, indexVariable);
    List<Polynomial> rPolynomials = new ArrayList<>(n);
    rPolynomials.add(DefaultPolynomial.make(Expressions.ONE, indexVariable));
    rPolynomials.add(indexOfSummationPlusLowerBoundPolynomial);
    for (int i = 2; i <= n; i++) {
        rPolynomials.add(rPolynomials.get(i - 1).times(indexOfSummationPlusLowerBoundPolynomial));
    }
    Map<Pair<Integer, Integer>, Expression> indexedRCoefficient = new LinkedHashMap<>();
    for (int i = 0; i <= n; i++) {
        Polynomial rPolynomial = rPolynomials.get(i);
        for (int q = 0; q <= i; q++) {
            Pair<Integer, Integer> indexKey = new Pair<>(i, q);
            Monomial rqxq = rPolynomial.getMapFromSignatureToMonomial().get(Arrays.asList(new Rational(q)));
            if (rqxq == null) {
                indexedRCoefficient.put(indexKey, Expressions.ZERO);
            } else {
                indexedRCoefficient.put(indexKey, rqxq.getCoefficient(indexVariable));
            }
        }
    }
    // 
    // compute "constants" (may contain variables other than x)
    // s_i,q,j =   t_i*R_{i,q}/(q+1) (-1)^j choose(q+1,j) B_j
    // where R_{i,q}(x) is the coefficient in R_i(x) multiplying x^q.
    Map<Triple<Integer, Integer, Integer>, Polynomial> sConstants = new LinkedHashMap<>();
    for (int i = 0; i <= n; i++) {
        Expression ti = tCoefficients.get(i);
        for (int q = 0; q <= i; q++) {
            Expression riq = indexedRCoefficient.get(new Pair<>(i, q));
            Expression tiByriq = new DefaultFunctionApplication(TIMES_FUNCTOR, Arrays.asList(ti, riq));
            for (int j = 0; j <= q; j++) {
                Triple<Integer, Integer, Integer> indexKey = new Triple<>(i, q, j);
                Expression qPlus1 = Expressions.makeSymbol(q + 1);
                Expression minus1PowerJ = Expressions.makeSymbol(j % 2 == 0 ? 1 : -1);
                Expression chooseQplus1J = Expressions.makeSymbol(Util.binomialCoefficient(q + 1, j));
                Expression bernoulliJ = Expressions.makeSymbol(BernoulliNumber.computeFirst(j));
                Expression sConstant = new DefaultFunctionApplication(TIMES_FUNCTOR, Arrays.asList(new DefaultFunctionApplication(DIVISION_FUNCTOR, Arrays.asList(tiByriq, qPlus1)), minus1PowerJ, chooseQplus1J, bernoulliJ));
                sConstants.put(indexKey, DefaultPolynomial.make(sConstant, indexVariable));
            }
        }
    }
    // 
    // compute polynomials, for each q, j,   V_{q + 1 -j}  = (u - l)^{q + 1 - j}
    Expression upperBoundMinusLowerBound = new DefaultFunctionApplication(MINUS_FUNCTOR, Arrays.asList(upperBoundInclusive, lowerBoundExclusive));
    Polynomial upperBoundMinusLowerBoundPolynomial = DefaultPolynomial.make(upperBoundMinusLowerBound, indexVariable);
    Map<Integer, Polynomial> vValues = new LinkedHashMap<>();
    for (int q = 0; q <= n; q++) {
        for (int j = 0; j <= q; j++) {
            Integer exponent = q + 1 - j;
            if (!vValues.containsKey(exponent)) {
                vValues.put(exponent, upperBoundMinusLowerBoundPolynomial.exponentiate(exponent));
            }
        }
    }
    // 
    // Compute the w values and construct the final result.
    Polynomial ws = DefaultPolynomial.make(Expressions.ZERO, indexVariable);
    for (int i = 0; i <= n; i++) {
        for (int q = 0; q <= i; q++) {
            for (int j = 0; j <= q; j++) {
                Triple<Integer, Integer, Integer> sConstantKey = new Triple<>(i, q, j);
                Integer valueKey = q + 1 - j;
                Polynomial sConstant = sConstants.get(sConstantKey);
                Polynomial vValue = vValues.get(valueKey);
                Polynomial w = sConstant.times(vValue);
                ws = ws.add(w);
            }
        }
    }
    List<Expression> generalizedVariables = DefaultPolynomial.extractGeneralizedVariables(ws);
    if (generalizedVariables.size() > 0) {
        // Simplify in the context of the contained generalized variables
        // and then return as a single constant factor (i.e. the index variable should not be present).
        ws = DefaultPolynomial.make(ws, generalizedVariables);
    }
    result = DefaultPolynomial.make(ws, indexVariable);
    return result;
}
Also used : Polynomial(com.sri.ai.grinder.polynomial.api.Polynomial) Rational(com.sri.ai.util.math.Rational) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) Triple(com.sri.ai.util.base.Triple) Expression(com.sri.ai.expresso.api.Expression) Monomial(com.sri.ai.grinder.polynomial.api.Monomial) DefaultFunctionApplication(com.sri.ai.expresso.core.DefaultFunctionApplication) Pair(com.sri.ai.util.base.Pair)

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