Search in sources :

Example 71 with IASTMutable

use of org.matheclipse.core.interfaces.IASTMutable in project symja_android_library by axkr.

the class Product method evaluateProduct.

private IExpr evaluateProduct(final IAST preevaledProduct, IExpr arg1, EvalEngine engine) {
    if (preevaledProduct.size() > 2) {
        IAST list;
        if (preevaledProduct.last().isList()) {
            list = (IAST) preevaledProduct.last();
        } else {
            list = F.list(preevaledProduct.last());
        }
        if (list.isAST1()) {
            // indefinite product case
            IExpr variable = list.arg1();
            if (preevaledProduct.arg1().isFree(variable) && variable.isVariable()) {
                return indefiniteProduct(preevaledProduct, variable);
            }
        }
    }
    IExpr temp = F.NIL;
    if (preevaledProduct.size() == 3) {
        IExpr result = matcher1().apply(preevaledProduct);
        if (result.isPresent()) {
            return result;
        }
    }
    try {
        temp = evaluateTableThrow(preevaledProduct, Times(), Times(), engine);
        if (temp.isPresent()) {
            return temp;
        }
    } catch (final ValidateException ve) {
        return IOFunctions.printMessage(S.Product, ve, engine);
    }
    if (arg1.isPower()) {
        IExpr exponent = arg1.exponent();
        boolean flag = true;
        // Prod( i^a, {i,from,to},... )
        for (int i = 2; i < preevaledProduct.size(); i++) {
            IIterator<IExpr> iterator;
            if (preevaledProduct.get(i).isList()) {
                iterator = Iterator.create((IAST) preevaledProduct.get(i), i, engine);
            } else {
                iterator = Iterator.create(F.list(preevaledProduct.get(i)), i, engine);
            }
            if (iterator.isValidVariable() && exponent.isFree(iterator.getVariable())) {
                continue;
            }
            flag = false;
            break;
        }
        if (flag) {
            IASTMutable prod = preevaledProduct.copy();
            prod.set(1, arg1.base());
            return F.Power(prod, exponent);
        }
    }
    IExpr argN = preevaledProduct.last();
    if (preevaledProduct.size() >= 3 && argN.isList()) {
        try {
            if (arg1.isZero()) {
                // Product(0, {k, n, m})
                return F.C0;
            }
            IIterator<IExpr> iterator = Iterator.create((IAST) argN, preevaledProduct.argSize(), engine);
            if (iterator.isValidVariable() && iterator.getUpperLimit().isInfinity()) {
                if (arg1.isOne()) {
                    // Product(1, {k, a, Infinity})
                    return F.C1;
                }
                if (arg1.isPositiveResult() && arg1.isIntegerResult()) {
                    // Product(n, {k, a, Infinity}) ;n is positive integer
                    return F.CInfinity;
                }
            }
            if (iterator.isValidVariable() && !iterator.isNumericFunction()) {
                if (iterator.getUpperLimit().isSymbol() && iterator.getStep().isOne()) {
                    final ISymbol var = iterator.getVariable();
                    final IExpr from = iterator.getLowerLimit();
                    final ISymbol to = (ISymbol) iterator.getUpperLimit();
                    if (arg1.isPower()) {
                        IExpr base = arg1.base();
                        if (base.isFree(var)) {
                            if (iterator.getLowerLimit().isOne()) {
                                IExpr exponent = arg1.exponent();
                                if (exponent.equals(var)) {
                                    // Prod( a^i, ..., {i,from,to} )
                                    if (preevaledProduct.isAST2()) {
                                        return F.Power(base, Times(C1D2, to, Plus(C1, to)));
                                    }
                                    IASTAppendable result = preevaledProduct.removeAtClone(preevaledProduct.argSize());
                                    // result.remove(ast.argSize());
                                    result.set(1, F.Power(base, Times(C1D2, to, Plus(C1, to))));
                                    return result;
                                }
                            }
                        }
                    }
                    if (arg1.isFree(var)) {
                        if (preevaledProduct.isAST2()) {
                            if (from.isOne()) {
                                return F.Power(preevaledProduct.arg1(), to);
                            }
                            if (from.isZero()) {
                                return F.Power(preevaledProduct.arg1(), Plus(to, C1));
                            }
                            if (from.isSymbol()) {
                                // 2^(1-from+to)
                                return F.Power(arg1, F.Plus(F.C1, from.negate(), to));
                            }
                        } else {
                            IASTAppendable result = preevaledProduct.removeAtClone(preevaledProduct.argSize());
                            // result.remove(ast.argSize());
                            if (from.isOne()) {
                                result.set(1, F.Power(preevaledProduct.arg1(), to));
                                return result;
                            }
                            if (from.isZero()) {
                                result.set(1, F.Power(preevaledProduct.arg1(), Plus(to, C1)));
                                return result;
                            }
                            if (from.isSymbol()) {
                                // 2^(1-from+to)
                                result.set(1, F.Power(arg1, F.Plus(F.C1, from.negate(), to)));
                                return result;
                            }
                        }
                    }
                }
            }
            temp = F.NIL;
            IAST resultList = Times();
            temp = evaluateLast(preevaledProduct.arg1(), iterator, resultList, F.C1);
            if (!temp.isPresent() || temp.equals(resultList)) {
                return F.NIL;
            }
        } catch (final ValidateException ve) {
            return IOFunctions.printMessage(S.Product, ve, engine);
        } catch (RecursionLimitExceeded rle) {
            // Recursion depth of `1` exceeded during evaluation of `2`.
            int recursionLimit = engine.getRecursionLimit();
            IOFunctions.printMessage(S.Product, "reclim2", F.list(recursionLimit < 0 ? F.CInfinity : F.ZZ(recursionLimit), preevaledProduct), engine);
            return F.NIL;
        }
        if (preevaledProduct.isAST2()) {
            return temp;
        } else {
            IASTAppendable result = preevaledProduct.removeAtClone(preevaledProduct.argSize());
            result.set(1, temp);
            return result;
        }
    }
    return F.NIL;
}
Also used : RecursionLimitExceeded(org.matheclipse.core.eval.exception.RecursionLimitExceeded) ValidateException(org.matheclipse.core.eval.exception.ValidateException) ISymbol(org.matheclipse.core.interfaces.ISymbol) IASTAppendable(org.matheclipse.core.interfaces.IASTAppendable) IAST(org.matheclipse.core.interfaces.IAST) IExpr(org.matheclipse.core.interfaces.IExpr) IASTMutable(org.matheclipse.core.interfaces.IASTMutable)

Example 72 with IASTMutable

use of org.matheclipse.core.interfaces.IASTMutable 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;
}
Also used : ISymbol(org.matheclipse.core.interfaces.ISymbol) IAST(org.matheclipse.core.interfaces.IAST) VariablesSet(org.matheclipse.core.convert.VariablesSet) IExpr(org.matheclipse.core.interfaces.IExpr) IASTMutable(org.matheclipse.core.interfaces.IASTMutable)

Example 73 with IASTMutable

use of org.matheclipse.core.interfaces.IASTMutable in project symja_android_library by axkr.

the class FindInstance method evaluate.

/**
 * Try to find at least one solution for a set of equations (i.e. <code>Equal[...]</code>
 * expressions).
 */
@Override
public IExpr evaluate(final IAST ast, EvalEngine engine) {
    IAST vars = Validate.checkIsVariableOrVariableList(ast, 2, ast.topHead(), engine);
    if (!vars.isPresent()) {
        return F.NIL;
    }
    try {
        boolean formula = false;
        int maxChoices = 1;
        if (ast.argSize() >= 4) {
            maxChoices = ast.arg4().toIntDefault();
            if (maxChoices < 0) {
                maxChoices = 1;
            }
        } else if (ast.argSize() >= 3) {
            maxChoices = ast.arg3().toIntDefault();
            if (maxChoices < 0) {
                maxChoices = 1;
            }
        }
        try {
            if (ast.arg1().isBooleanFormula()) {
                formula = ast.arg1().isBooleanFormula();
                if (ast.isAST2()) {
                    return BooleanFunctions.solveInstances(ast.arg1(), vars, maxChoices);
                }
            }
        } catch (RuntimeException rex) {
        }
        if (ast.argSize() >= 3) {
            if (ast.arg3().equals(S.Booleans) || formula) {
                return BooleanFunctions.solveInstances(ast.arg1(), vars, maxChoices);
            } else if (ast.arg3().equals(S.Integers)) {
                return Solve.solveIntegers(ast, vars, vars, maxChoices, engine);
            }
            LOGGER.log(engine.getLogLevel(), "{}: Booleans domain expected at position 3 instead of {}", ast.topHead(), ast.arg3());
            return F.NIL;
        }
        IASTMutable termsEqualZeroList = Validate.checkEquations(ast, 1);
        return solveEquations(termsEqualZeroList, F.List(), vars, maxChoices, engine);
    } catch (final ValidateException ve) {
        return IOFunctions.printMessage(ast.topHead(), ve, engine);
    } catch (RuntimeException rex) {
        LOGGER.debug("FindInstance.evaluate() failed", rex);
    }
    return F.NIL;
}
Also used : ValidateException(org.matheclipse.core.eval.exception.ValidateException) IAST(org.matheclipse.core.interfaces.IAST) IASTMutable(org.matheclipse.core.interfaces.IASTMutable)

Example 74 with IASTMutable

use of org.matheclipse.core.interfaces.IASTMutable in project symja_android_library by axkr.

the class AbstractFunctionEvaluator method getNormalizedNegativeExpression.

/**
 * Check if the expression is canonical negative.
 *
 * @param expression
 * @param checkTimesPlus check <code>Times(...)</code> and <code>Plus(...)</code> expressions
 * @return the negated negative expression or <code>F.NIL</code> if a negative expression couldn't
 *         be extracted.
 */
public static IExpr getNormalizedNegativeExpression(final IExpr expression, boolean checkTimesPlus) {
    IASTMutable result = F.NIL;
    if (expression.isNumber()) {
        if (((INumber) expression).complexSign() < 0) {
            return ((INumber) expression).negate();
        }
        return F.NIL;
    } else if (expression.isAST()) {
        if (checkTimesPlus && expression.isTimes()) {
            IAST timesAST = ((IAST) expression);
            IExpr arg1 = timesAST.arg1();
            // see github #110: checking for arg1.isNegative() will trigger infinite recursion!
            if (arg1.isNumber()) {
                if (((INumber) arg1).complexSign() < 0) {
                    IExpr negNum = ((INumber) arg1).negate();
                    if (negNum.isOne()) {
                        return timesAST.rest().oneIdentity1();
                    }
                    return timesAST.setAtCopy(1, negNum);
                }
            } else if (arg1.isNegativeInfinity()) {
                return timesAST.setAtCopy(1, F.CInfinity);
            }
        } else if (checkTimesPlus && expression.isPlus()) {
            IAST plusAST = ((IAST) expression);
            IExpr arg1 = plusAST.arg1();
            if (arg1.isNumber()) {
                if (((INumber) arg1).complexSign() < 0) {
                    result = plusAST.copy();
                    result.set(1, arg1.negate());
                    for (int i = 2; i < plusAST.size(); i++) {
                        result.set(i, plusAST.get(i).negate());
                    }
                    return result;
                }
            } else if (arg1.isNegativeInfinity()) {
                result = plusAST.copy();
                result.set(1, F.CInfinity);
                for (int i = 2; i < plusAST.size(); i++) {
                    result.set(i, plusAST.get(i).negate());
                }
                return result;
            } else if (arg1.isTimes()) {
                IExpr arg1Negated = getNormalizedNegativeExpression(arg1, checkTimesPlus);
                if (arg1Negated.isPresent()) {
                    // int positiveElementsCounter = 0;
                    result = plusAST.copy();
                    result.set(1, arg1Negated);
                    for (int i = 2; i < plusAST.size(); i++) {
                        IExpr temp = plusAST.get(i);
                        // if (!temp.isTimes() && !temp.isPower()) {
                        // return F.NIL;
                        // }
                        // arg1Negated = getNormalizedNegativeExpression(temp, checkTimesPlus);
                        // if (arg1Negated.isPresent()) {
                        // result.set(i, arg1Negated);
                        // } else {
                        // positiveElementsCounter++;
                        // if (positiveElementsCounter * 2 > plusAST.argSize()) {
                        // number of positive elements is greater
                        // than number of negative elements
                        // return F.NIL;
                        // }
                        result.set(i, temp.negate());
                    // }
                    }
                    return result;
                }
            }
        // } else if (expression.isNegativeInfinity()) {
        // return F.CInfinity;
        } else if (expression.isDirectedInfinity() && expression.isAST1()) {
            IExpr arg1 = expression.first();
            if (arg1.isMinusOne()) {
                return F.CInfinity;
            }
            if (arg1.isNegativeImaginaryUnit()) {
                return F.DirectedInfinity(F.CI);
            }
        }
    }
    // }
    return F.NIL;
}
Also used : INumber(org.matheclipse.core.interfaces.INumber) IASTMutable(org.matheclipse.core.interfaces.IASTMutable) IAST(org.matheclipse.core.interfaces.IAST) IExpr(org.matheclipse.core.interfaces.IExpr)

Example 75 with IASTMutable

use of org.matheclipse.core.interfaces.IASTMutable in project symja_android_library by axkr.

the class SolveUtils method filterSolveLists.

/**
 * <code>result[0]</code> is the list of expressions <code>== 0</code> . <code>result[1]</code>are
 * the <code>Unequal, Less, LessEqual, Greater, GreaterEqual</code> expressions. If <code>
 * result[2].isPresent()</code> return the entry as solution.
 *
 * @param list
 * @param solution
 * @param isNumeric set isNumeric[0] = true, if an expression must be rationalized
 * @return
 */
public static IASTMutable[] filterSolveLists(IAST list, IASTMutable solution, boolean[] isNumeric) {
    // if numeric is true we use NSolve instead of SOlve
    boolean numeric = isNumeric[0];
    IASTMutable[] result = new IASTMutable[3];
    IASTAppendable termsEqualZero = F.ListAlloc(list.size());
    IASTAppendable inequalityTerms = F.ListAlloc(list.size());
    result[0] = termsEqualZero;
    result[1] = inequalityTerms;
    result[2] = F.NIL;
    int i = 1;
    while (i < list.size()) {
        IExpr arg = list.get(i);
        if (arg.isTrue()) {
        } else if (arg.isFalse()) {
            // no solution possible
            result[2] = F.ListAlloc();
            return result;
        } else if (arg.isEqual()) {
            // arg must be Equal(_, 0)
            IExpr arg1 = arg.first();
            if (numeric) {
                // NSolve
                termsEqualZero.append(arg1);
            } else {
                // Solve
                IExpr temp = NumberTheory.rationalize(arg1, false);
                if (temp.isPresent()) {
                    isNumeric[0] = true;
                    termsEqualZero.append(temp);
                } else {
                    termsEqualZero.append(arg1);
                }
            }
        } else {
            inequalityTerms.append(arg);
        }
        i++;
    }
    EvalAttributes.sort(result[0]);
    EvalAttributes.sort(result[1]);
    if (result[0].isEmpty() && result[1].isEmpty()) {
        if (solution.isPresent()) {
            result[2] = solution;
        } else {
            result[2] = F.unary(S.List, F.List());
        }
        return result;
    }
    return result;
}
Also used : IASTAppendable(org.matheclipse.core.interfaces.IASTAppendable) IASTMutable(org.matheclipse.core.interfaces.IASTMutable) IExpr(org.matheclipse.core.interfaces.IExpr)

Aggregations

IASTMutable (org.matheclipse.core.interfaces.IASTMutable)92 IExpr (org.matheclipse.core.interfaces.IExpr)60 IAST (org.matheclipse.core.interfaces.IAST)34 IASTAppendable (org.matheclipse.core.interfaces.IASTAppendable)26 ISymbol (org.matheclipse.core.interfaces.ISymbol)12 IInteger (org.matheclipse.core.interfaces.IInteger)5 Map (java.util.Map)4 IComplex (org.matheclipse.core.interfaces.IComplex)4 IRational (org.matheclipse.core.interfaces.IRational)4 ArrayList (java.util.ArrayList)3 TreeMap (java.util.TreeMap)3 EvalEngine (org.matheclipse.core.eval.EvalEngine)3 JASConversionException (org.matheclipse.core.eval.exception.JASConversionException)3 ValidateException (org.matheclipse.core.eval.exception.ValidateException)3 INumber (org.matheclipse.core.interfaces.INumber)3 IPatternObject (org.matheclipse.core.interfaces.IPatternObject)3 ISparseArray (org.matheclipse.core.interfaces.ISparseArray)3 ASTNode (org.matheclipse.parser.client.ast.ASTNode)3 ThreadLocalRandom (java.util.concurrent.ThreadLocalRandom)2 AST2Expr (org.matheclipse.core.convert.AST2Expr)2