use of org.matheclipse.core.convert.VariablesSet in project symja_android_library by axkr.
the class Algebra method cancelGCD.
/**
* Calculate the 3 elements result array
*
* <pre>
* [
* commonFactor,
* numeratorPolynomial.divide(gcd(numeratorPolynomial, denominatorPolynomial)),
* denominatorPolynomial.divide(gcd(numeratorPolynomial, denominatorPolynomial))
* ]
* </pre>
*
* for the given expressions <code>numeratorPolynomial</code> and <code>denominatorPolynomial
* </code>.
*
* @param numerator an expression which should be converted to JAS polynomial (using
* substitutions)
* @param denominator a expression which could be converted to JAS polynomial (using
* substitutions)
* @return <code>null</code> if the expressions couldn't be converted to JAS polynomials or gcd
* equals 1
* @throws JASConversionException
*/
public static IExpr[] cancelGCD(final IExpr numerator, final IExpr denominator) throws JASConversionException {
try {
if (denominator.isInteger() && numerator.isPlus()) {
IExpr[] result = Cancel.cancelPlusIntegerGCD((IAST) numerator, (IInteger) denominator);
if (result != null) {
return result;
}
}
VariablesSet eVar = new VariablesSet(numerator);
eVar.addVarList(denominator);
if (eVar.size() == 0) {
return null;
}
IAST vars = eVar.getVarList();
PolynomialHomogenization substitutions = new PolynomialHomogenization(vars, EvalEngine.get());
IExpr[] subst = substitutions.replaceForward(numerator, denominator);
IExpr numeratorPolynomial = subst[0];
IExpr denominatorPolynomial = subst[1];
if (substitutions.size() > 0) {
eVar.clear();
eVar.addAll(substitutions.substitutedVariablesSet());
vars = eVar.getVarList();
}
try {
ExprPolynomialRing ring = new ExprPolynomialRing(vars);
ExprPolynomial pol1 = ring.create(numeratorPolynomial);
ExprPolynomial pol2 = ring.create(denominatorPolynomial);
List<IExpr> varList = eVar.getVarList().copyTo();
JASIExpr jas = new JASIExpr(varList, true);
GenPolynomial<IExpr> p1 = jas.expr2IExprJAS(pol1);
GenPolynomial<IExpr> p2 = jas.expr2IExprJAS(pol2);
GreatestCommonDivisor<IExpr> engine;
engine = GCDFactory.getImplementation(ExprRingFactory.CONST);
GenPolynomial<IExpr> gcd = engine.gcd(p1, p2);
IExpr[] result = new IExpr[3];
if (gcd.isONE()) {
return null;
// result[0] = jas.exprPoly2Expr(gcd);
// result[1] = jas.exprPoly2Expr(p1);
// result[2] = jas.exprPoly2Expr(p2);
} else {
result[0] = F.C1;
result[1] = F.eval(jas.exprPoly2Expr(p1.divide(gcd)));
result[2] = F.eval(jas.exprPoly2Expr(p2.divide(gcd)));
}
result[0] = substitutions.replaceBackward(result[0]);
result[1] = substitutions.replaceBackward(result[1]);
result[2] = substitutions.replaceBackward(result[2]);
return result;
} catch (RuntimeException rex) {
}
List<IExpr> varList = eVar.getVarList().copyTo();
ComplexRing<BigRational> cfac = new ComplexRing<BigRational>(BigRational.ZERO);
JASConvert<Complex<BigRational>> jas = new JASConvert<Complex<BigRational>>(varList, cfac);
GenPolynomial<Complex<BigRational>> p1 = jas.expr2JAS(numeratorPolynomial, false);
GenPolynomial<Complex<BigRational>> p2 = jas.expr2JAS(denominatorPolynomial, false);
GreatestCommonDivisor<Complex<BigRational>> engine;
engine = GCDFactory.getImplementation(cfac);
GenPolynomial<Complex<BigRational>> gcd;
// if (numeratorPolynomial.isSymbol()||denominatorPolynomial.isSymbol() ) {
// gcd = jas.expr2IExprJAS(F.C1);
// }else {
gcd = engine.gcd(p1, p2);
// }
IExpr[] result = new IExpr[3];
if (gcd.isONE()) {
return null;
// result[0] = jas.complexPoly2Expr(gcd);
// result[1] = jas.complexPoly2Expr(p1);
// result[2] = jas.complexPoly2Expr(p2);
} else {
result[0] = F.C1;
result[1] = F.eval(jas.complexPoly2Expr(p1.divide(gcd)));
result[2] = F.eval(jas.complexPoly2Expr(p2.divide(gcd)));
}
result[0] = substitutions.replaceBackward(result[0]);
result[1] = substitutions.replaceBackward(result[1]);
result[2] = substitutions.replaceBackward(result[2]);
return result;
} catch (RuntimeException e) {
LOGGER.debug("Algebra.cancelGCD() failed", e);
}
return null;
}
use of org.matheclipse.core.convert.VariablesSet in project symja_android_library by axkr.
the class Reduce method evaluate.
@Override
public IExpr evaluate(final IAST ast, EvalEngine engine) {
IAST vars;
ISymbol domain = S.Reals;
if (ast.isAST2() || ast.isAST3()) {
if (ast.arg2().isList()) {
vars = (IAST) ast.arg2();
} else {
vars = F.list(ast.arg2());
}
} else {
VariablesSet eVar = new VariablesSet(ast.arg1());
vars = eVar.getVarList();
}
if (!vars.isList1()) {
// only univariate expressions allowed atm
return F.NIL;
}
if (ast.isAST3()) {
if (ast.arg3().isSymbol()) {
domain = (ISymbol) ast.arg3();
} else {
return F.NIL;
}
}
if (domain != S.Reals) {
return F.NIL;
}
try {
IExpr expr = ast.arg1();
if (ast.arg1().isList()) {
expr = ((IAST) expr).setAtCopy(0, S.And);
} else if (!expr.isBooleanFunction()) {
if (!expr.isComparatorFunction()) {
expr = F.And(expr);
}
}
IExpr variable = vars.get(1);
IExpr logicalExpand = S.LogicalExpand.of(engine, expr);
if (logicalExpand.isTrue() || logicalExpand.isFalse()) {
return logicalExpand;
}
if (!logicalExpand.isBooleanFunction()) {
logicalExpand = F.And(logicalExpand);
}
if (logicalExpand.isAST(S.And)) {
IAST andAST = (IAST) logicalExpand;
IASTMutable andResult = andAST.copy();
for (int i = 1; i < andAST.size(); i++) {
IExpr arg = andAST.get(i);
if (arg.isEqual()) {
IExpr roots = S.Roots.ofNIL(engine, arg, variable);
if (roots.isPresent()) {
andResult.set(i, roots);
}
}
}
logicalExpand = S.LogicalExpand.of(engine, andResult);
if (logicalExpand.isTrue() || logicalExpand.isFalse()) {
return logicalExpand;
}
}
ReduceComparison rc = new ReduceComparison(variable);
// may throw ArgumentTypeException
IExpr reduced = rc.evaluate(logicalExpand);
return reduced.orElse(logicalExpand);
} catch (RuntimeException rex) {
rex.printStackTrace();
}
return F.NIL;
}
use of org.matheclipse.core.convert.VariablesSet in project symja_android_library by axkr.
the class ComplexExpand method evaluate.
@Override
public IExpr evaluate(final IAST ast, EvalEngine engine) {
IExpr temp = StructureFunctions.threadLogicEquationOperators(ast.arg1(), ast, 1);
if (temp.isPresent()) {
return temp;
}
IAssumptions oldAssumptions = engine.getAssumptions();
try {
IExpr arg1 = ast.arg1();
IAST arg2 = F.NIL;
if (ast.isAST2()) {
arg2 = ast.arg2().isList() ? (IAST) ast.arg2() : F.list(ast.arg2());
}
VariablesSet eVar = new VariablesSet(arg1);
List<IExpr> varList = eVar.getVarList().copyTo();
IASTAppendable assumptionExpr = F.ListAlloc(varList.size() + 1);
for (int i = 0; i < varList.size(); i++) {
final IExpr variable = varList.get(i);
if (arg2.isPresent()) {
boolean hasMatched = false;
for (int j = 1; j < arg2.size(); j++) {
if (S.MatchQ.ofQ(variable, arg2.get(j))) {
hasMatched = true;
break;
}
}
if (hasMatched) {
continue;
}
}
assumptionExpr.append(F.Element(variable, S.Reals));
}
IAssumptions assumptions;
if (oldAssumptions == null) {
assumptions = org.matheclipse.core.eval.util.Assumptions.getInstance(assumptionExpr);
} else {
assumptions = oldAssumptions.copy();
assumptions = assumptions.addAssumption(assumptionExpr);
}
engine.setAssumptions(assumptions);
ComplexExpandVisitor tteVisitor = new ComplexExpandVisitor(engine);
IExpr result = arg1.accept(tteVisitor);
if (result.isPresent()) {
return result;
}
return arg1;
} finally {
engine.setAssumptions(oldAssumptions);
}
}
use of org.matheclipse.core.convert.VariablesSet in project symja_android_library by axkr.
the class PredicateQ method isPossibleZeroQ.
public static boolean isPossibleZeroQ(IAST function, boolean fastTest, EvalEngine engine) {
try {
VariablesSet varSet = new VariablesSet(function);
IAST variables = varSet.getVarList();
if (function.leafCount() < Config.MAX_POSSIBLE_ZERO_LEAFCOUNT / 5) {
IExpr expr = F.TrigExpand.of(engine, function);
expr = F.expandAll(expr, true, true);
expr = engine.evaluate(expr);
if (!expr.isAST()) {
return expr.isZero();
}
function = (IAST) expr;
}
if (variables.isEmpty()) {
INumber num = function.isNumericFunction(true) ? function.evalNumber() : null;
if (num == null || !(F.isZero(num.reDoubleValue(), Config.SPECIAL_FUNCTIONS_TOLERANCE) && F.isZero(num.imDoubleValue(), Config.SPECIAL_FUNCTIONS_TOLERANCE))) {
return false;
}
return true;
} else {
if (function.isNumericFunction(varSet)) {
if (function.isFreeAST(h -> isSpecialNumericFunction(h))) {
int trueCounter = 0;
// 1. step test some special complex numeric values
COMPARE_TERNARY possibeZero = isPossibeZeroFixedValues(F.C0, function, variables, engine);
if (possibeZero == IExpr.COMPARE_TERNARY.FALSE) {
return false;
}
if (possibeZero == IExpr.COMPARE_TERNARY.TRUE) {
trueCounter++;
}
possibeZero = isPossibeZeroFixedValues(F.C1, function, variables, engine);
if (possibeZero == IExpr.COMPARE_TERNARY.FALSE) {
return false;
}
if (possibeZero == IExpr.COMPARE_TERNARY.TRUE) {
trueCounter++;
}
possibeZero = isPossibeZeroFixedValues(F.CN1, function, variables, engine);
if (possibeZero == IExpr.COMPARE_TERNARY.FALSE) {
return false;
}
if (possibeZero == IExpr.COMPARE_TERNARY.TRUE) {
trueCounter++;
}
possibeZero = isPossibeZeroFixedValues(F.CI, function, variables, engine);
if (possibeZero == IExpr.COMPARE_TERNARY.FALSE) {
return false;
}
if (possibeZero == IExpr.COMPARE_TERNARY.TRUE) {
trueCounter++;
}
possibeZero = isPossibeZeroFixedValues(F.CNI, function, variables, engine);
if (possibeZero == IExpr.COMPARE_TERNARY.FALSE) {
return false;
}
if (possibeZero == IExpr.COMPARE_TERNARY.TRUE) {
trueCounter++;
}
if (trueCounter == 5) {
// 2. step test some random complex numeric values
for (int i = 0; i < 36; i++) {
possibeZero = isPossibeZero(function, variables, engine);
if (possibeZero == IExpr.COMPARE_TERNARY.FALSE) {
return false;
}
if (possibeZero == IExpr.COMPARE_TERNARY.TRUE) {
trueCounter++;
}
}
if (trueCounter > 28) {
return true;
}
}
if (fastTest) {
return false;
}
}
}
}
IExpr temp = function.replaceAll(x -> //
x.isNumericFunction(true) ? IExpr.ofNullable(x.evalNumber()) : F.NIL);
if (temp.isPresent()) {
temp = engine.evaluate(temp);
if (temp.isZero()) {
return true;
}
}
return isZeroTogether(function, engine);
} catch (ValidateException ve) {
LOGGER.debug("PredicateQ.isPossibleZeroQ() failed", ve);
}
return false;
}
use of org.matheclipse.core.convert.VariablesSet in project symja_android_library by axkr.
the class Sum method evaluateSum.
private static IExpr evaluateSum(final IAST preevaledSum, EvalEngine engine) {
if (preevaledSum.size() > 2) {
try {
IAST list;
if (preevaledSum.last().isList()) {
list = (IAST) preevaledSum.last();
} else {
list = F.list(preevaledSum.last());
}
if (list.isAST1()) {
// indefinite sum case
IExpr variable = list.arg1();
if (preevaledSum.arg1().isFree(variable) && variable.isVariable()) {
return indefiniteSum(preevaledSum, variable);
}
}
if (preevaledSum.size() == 3) {
IExpr result = matcher1().apply(preevaledSum);
if (result.isPresent()) {
return result;
}
}
IExpr argN = preevaledSum.last();
// try {
IExpr temp = evaluateTableThrow(preevaledSum, Plus(), Plus(), engine);
if (temp.isPresent()) {
return temp;
}
VariablesSet variablesSet = determineIteratorExprVariables(preevaledSum);
IAST varList = variablesSet.getVarList();
IIterator<IExpr> iterator = null;
if (argN.isList()) {
argN = evalBlockWithoutReap(argN, varList);
if (argN.isList()) {
iterator = Iterator.create((IAST) argN, preevaledSum.argSize(), engine);
} else {
if (argN.isReal()) {
iterator = Iterator.create(F.list(argN), preevaledSum.argSize(), engine);
} else {
// Non-list iterator `1` at position `2` does not evaluate to a real numeric value.
return IOFunctions.printMessage(preevaledSum.topHead(), "nliter", F.list(argN, F.ZZ(preevaledSum.size() - 1)), engine);
}
}
}
IExpr arg1 = preevaledSum.arg1();
if (arg1.isTimes()) {
if (variablesSet.size() > 0) {
temp = collectConstantFactors(preevaledSum, (IAST) arg1, variablesSet);
if (temp.isPresent()) {
return temp;
}
}
}
if (iterator != null) {
if (arg1.isZero()) {
// Sum(0, {k, n, m})
return F.C0;
}
if (iterator.isValidVariable() && iterator.getUpperLimit().isInfinity()) {
if (arg1.isPositiveResult() && arg1.isIntegerResult()) {
// Sum(n, {k, a, Infinity}) ;n is positive integer
return F.CInfinity;
}
if (arg1.isNegativeResult() && arg1.isIntegerResult()) {
// Sum(n, {k, a, Infinity}) ;n is negative integer
return F.CNInfinity;
}
}
if (iterator.isValidVariable() && iterator.isNumericFunction()) {
IAST resultList = Plus();
temp = evaluateLast(preevaledSum.arg1(), iterator, resultList, F.C0);
if (!temp.isPresent() || temp.equals(resultList)) {
return F.NIL;
}
if (preevaledSum.isAST2()) {
return temp;
} else {
IASTAppendable result = preevaledSum.removeAtClone(preevaledSum.argSize());
result.set(1, temp);
return result;
}
}
if (iterator.isValidVariable() && !iterator.isNumericFunction()) {
if (iterator.getStep().isOne()) {
if (iterator.getUpperLimit().isDirectedInfinity()) {
temp = definiteSumInfinity(arg1, iterator, (IAST) argN, engine);
} else {
temp = definiteSum(arg1, iterator, (IAST) argN, engine);
}
if (temp.isPresent()) {
if (preevaledSum.isAST2()) {
return temp;
}
IASTAppendable result = preevaledSum.removeAtClone(preevaledSum.argSize());
result.set(1, temp);
return result;
}
}
}
} else if (argN.isSymbol()) {
temp = indefiniteSum(arg1, (ISymbol) argN);
if (temp.isPresent()) {
if (preevaledSum.isAST2()) {
return temp;
} else {
IASTAppendable result = preevaledSum.removeAtClone(preevaledSum.argSize());
result.set(1, temp);
return result;
}
}
}
} catch (ValidateException ve) {
return IOFunctions.printMessage(preevaledSum.topHead(), ve, engine);
}
}
return F.NIL;
}
Aggregations