use of com.sri.ai.grinder.polynomial.api.Monomial 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:
// ∫ 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));
}
}
// ∫ 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;
}
use of com.sri.ai.grinder.polynomial.api.Monomial in project aic-expresso by aic-sri-international.
the class PolynomialIntegration method replaceVariableByValueInTerms.
private static List<Expression> replaceVariableByValueInTerms(Polynomial q, Expression variable, Expression value) {
List<Expression> replacedTerms = new ArrayList<>();
for (Monomial term : q.getMonomials()) {
List<Expression> replacedFactorsInTerm = replaceVariableByValueInTerm(term, variable, value);
replacedTerms.add(DefaultMonomial.make(Times.make(replacedFactorsInTerm)));
}
return replacedTerms;
}
use of com.sri.ai.grinder.polynomial.api.Monomial 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;
}
use of com.sri.ai.grinder.polynomial.api.Monomial in project aic-expresso by aic-sri-international.
the class IsolateUtil method isolate.
public static Expression isolate(Polynomial leftPolynomial, Expression operator, Polynomial rightPolynomial, Expression linearVariableToIsolate) {
assertSupportedOperator(operator);
Pair<List<Monomial>, List<Monomial>> splitIntoSimilarAndDissimilarTerms;
splitIntoSimilarAndDissimilarTerms = splitIntoSimilarAndDissimilarTerms(leftPolynomial, linearVariableToIsolate);
List<Monomial> leftSimilarTerms = splitIntoSimilarAndDissimilarTerms.first;
List<Monomial> leftDissimilarTerms = splitIntoSimilarAndDissimilarTerms.second;
splitIntoSimilarAndDissimilarTerms = splitIntoSimilarAndDissimilarTerms(rightPolynomial, linearVariableToIsolate);
List<Monomial> rightSimilarTerms = splitIntoSimilarAndDissimilarTerms.first;
List<Monomial> rightDissimilarTerms = splitIntoSimilarAndDissimilarTerms.second;
// First move the left dissimilar terms over to the right side
for (Monomial leftDissimilarTerm : leftDissimilarTerms) {
rightDissimilarTerms.add(DefaultMonomial.make(Times.make(Expressions.MINUS_ONE, leftDissimilarTerm)));
}
// Second move the right similar terms over to the left side
for (Monomial rightSimilarTerm : rightSimilarTerms) {
leftSimilarTerms.add(DefaultMonomial.make(Times.make(Expressions.MINUS_ONE, rightSimilarTerm)));
}
Polynomial leftSimilarPolynomial = DefaultPolynomial.make(Plus.make(new ArrayList<>(leftSimilarTerms)));
Polynomial rightDissimilarPolynomial = DefaultPolynomial.make(Plus.make(new ArrayList<Expression>(rightDissimilarTerms)));
Monomial isolated = null;
// Compute Alpha
List<Expression> alphaTerms = new ArrayList<>();
for (Monomial similarTerm : leftSimilarPolynomial.getMonomials()) {
List<Expression> dissimilarFactors = new ArrayList<>();
dissimilarFactors.add(Expressions.makeSymbol(similarTerm.getNumericFactor()));
for (Expression factor : similarTerm.getOrderedNonNumericFactors()) {
if (factor.equals(linearVariableToIsolate)) {
if (isolated == null) {
isolated = DefaultMonomial.make(Exponentiation.make(factor, Expressions.makeSymbol(similarTerm.getPowerOfFactor(factor))));
}
if (!Rational.ONE.equals(similarTerm.getPowerOfFactor(factor))) {
throw new IllegalArgumentException("Only linear (i.e. x^1) can be isolated by this API but found : " + factor);
}
} else {
dissimilarFactors.add(Exponentiation.make(factor, Expressions.makeSymbol(similarTerm.getPowerOfFactor(factor))));
}
}
alphaTerms.add(DefaultMonomial.make(Times.make(dissimilarFactors)));
}
Polynomial alpha = DefaultPolynomial.make(Plus.make(alphaTerms), rightDissimilarPolynomial.getVariables());
Expression rightDissimilarTerm;
if (alpha.equals(Expressions.ZERO)) {
isolated = DefaultMonomial.ZERO;
rightDissimilarTerm = rightDissimilarPolynomial;
} else {
Pair<Polynomial, Polynomial> quotientAndRemainder = rightDissimilarPolynomial.divide(alpha);
if (quotientAndRemainder.second.equals(Expressions.ZERO)) {
rightDissimilarTerm = quotientAndRemainder.first;
} else {
rightDissimilarTerm = Division.simplify(Division.make(rightDissimilarPolynomial, alpha));
}
}
Expression result;
// If alpha is numeric we can divide (or know it was 0 - handled accordingly already).
if (Expressions.isNumber(alpha)) {
result = Expressions.apply(flipIfRequired(operator, alpha), isolated, rightDissimilarTerm);
} else {
Expression thenBranch;
if (isEquality(operator)) {
thenBranch = Expressions.apply(operator, isolated, rightDissimilarTerm);
} else {
thenBranch = IfThenElse.make(Expressions.apply(FunctorConstants.GREATER_THAN, alpha, Expressions.ZERO), Expressions.apply(operator, isolated, rightDissimilarTerm), Expressions.apply(flipInequalityOperator(operator), isolated, rightDissimilarTerm));
}
result = IfThenElse.make(Expressions.apply(FunctorConstants.DISEQUALITY, alpha, Expressions.ZERO), thenBranch, Expressions.apply(FunctorConstants.EQUALITY, Expressions.ZERO, rightDissimilarPolynomial));
}
return result;
}
use of com.sri.ai.grinder.polynomial.api.Monomial in project aic-expresso by aic-sri-international.
the class DefaultMonomialTest method testDivide.
@Test
public void testDivide() {
Monomial m1 = makeMonomial("1");
Monomial m2 = makeMonomial("2");
Assert.assertEquals(new Pair<>(makeMonomial("0.5"), makeMonomial("0")), m1.divide(m2));
m1 = makeMonomial("3");
m2 = makeMonomial("2");
Assert.assertEquals(new Pair<>(makeMonomial("1.5"), makeMonomial("0")), m1.divide(m2));
m1 = makeMonomial("3*x^3");
m2 = makeMonomial("2*x^2");
Assert.assertEquals(new Pair<>(makeMonomial("1.5*x"), makeMonomial("0")), m1.divide(m2));
m1 = makeMonomial("3*x^3");
m2 = makeMonomial("2*x^3");
Assert.assertEquals(new Pair<>(makeMonomial("1.5"), makeMonomial("0")), m1.divide(m2));
m1 = makeMonomial("3*x^3*z^2");
m2 = makeMonomial("3*x^2");
Assert.assertEquals(new Pair<>(makeMonomial("x*z^2"), makeMonomial("0")), m1.divide(m2));
m1 = makeMonomial("3*x^3*z^2");
m2 = makeMonomial("3*x^4");
Assert.assertEquals(new Pair<>(makeMonomial("0"), makeMonomial("3*x^3*z^2")), m1.divide(m2));
m1 = makeMonomial("3*x^2*y");
m2 = makeMonomial("3*x^3*z^2");
Assert.assertEquals(new Pair<>(makeMonomial("0"), makeMonomial("3*x^2*y")), m1.divide(m2));
m1 = makeMonomial("0");
m2 = makeMonomial("3*x^3*z^2");
Assert.assertEquals(new Pair<>(makeMonomial("0"), makeMonomial("0")), m1.divide(m2));
}
Aggregations