Search in sources :

Example 86 with IASTMutable

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

the class Solve method of.

/**
 * @param ast the <code>Solve(...)</code> ast
 * @param numeric if true, try to find a numerically solution
 * @param engine
 * @return
 */
public static IExpr of(final IAST ast, boolean numeric, EvalEngine engine) {
    boolean[] isNumeric = new boolean[] { numeric };
    try {
        if (ast.arg1().isEmptyList()) {
            return F.list(F.CEmptyList);
        }
        IAST userDefinedVariables = Validate.checkIsVariableOrVariableList(ast, 2, ast.topHead(), engine);
        if (userDefinedVariables.isPresent()) {
            IAST equationVariables = VariablesSet.getVariables(ast.arg1());
            if (userDefinedVariables.isEmpty()) {
                userDefinedVariables = equationVariables;
            }
            ISymbol domain = S.Complexes;
            if (ast.isAST3()) {
                if (!ast.arg3().isSymbol()) {
                    LOGGER.log(engine.getLogLevel(), "{}: domain definition expected at position 3 instead of {}", ast.topHead(), ast.arg3());
                    return F.NIL;
                }
                domain = (ISymbol) ast.arg3();
                if (domain.equals(S.Booleans)) {
                    return BooleanFunctions.solveInstances(ast.arg1(), userDefinedVariables, Integer.MAX_VALUE);
                }
                if (domain.equals(S.Integers)) {
                    return solveIntegers(ast, equationVariables, userDefinedVariables, Integer.MAX_VALUE, engine);
                }
                if (!domain.equals(S.Reals) && !domain.equals(S.Complexes)) {
                    Level level = engine.getLogLevel();
                    LOGGER.log(level, "{}: domain definition expected at position 3 instead of {}", ast.topHead(), domain);
                    return F.NIL;
                }
            }
            IAssumptions oldAssumptions = engine.getAssumptions();
            try {
                IAssumptions assum = setVariablesReals(userDefinedVariables, domain);
                if (assum != null) {
                    engine.setAssumptions(assum);
                }
                IAST termsList = Validate.checkEquationsAndInequations(ast, 1);
                IASTMutable[] lists = SolveUtils.filterSolveLists(termsList, F.NIL, isNumeric);
                boolean numericFlag = isNumeric[0] || numeric;
                if (lists[2].isPresent()) {
                    IExpr result = solveNumeric(lists[2], numericFlag, engine);
                    if (!result.isPresent()) {
                        return IOFunctions.printMessage(ast.topHead(), "nsmet", F.list(ast.topHead()), engine);
                    }
                    return checkDomain(result, domain);
                }
                IASTMutable termsEqualZeroList = lists[0];
                IExpr result = solveRecursive(termsEqualZeroList, lists[1], numericFlag, userDefinedVariables, engine);
                if (!result.isPresent()) {
                    return IOFunctions.printMessage(ast.topHead(), "nsmet", F.list(ast.topHead()), engine);
                }
                return checkDomain(result, domain);
            } finally {
                engine.setAssumptions(oldAssumptions);
            }
        }
    } catch (ValidateException ve) {
        return IOFunctions.printMessage(S.Solve, ve, engine);
    } catch (LimitException e) {
        LOGGER.log(engine.getLogLevel(), S.Solve, e);
    } catch (RuntimeException rex) {
        LOGGER.debug("Solve.of() failed() failed", rex);
    }
    return F.NIL;
}
Also used : ValidateException(org.matheclipse.core.eval.exception.ValidateException) ISymbol(org.matheclipse.core.interfaces.ISymbol) IAssumptions(org.matheclipse.core.eval.util.IAssumptions) Level(org.apache.logging.log4j.Level) IAST(org.matheclipse.core.interfaces.IAST) IASTMutable(org.matheclipse.core.interfaces.IASTMutable) IExpr(org.matheclipse.core.interfaces.IExpr) LimitException(org.matheclipse.core.eval.exception.LimitException)

Example 87 with IASTMutable

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

the class Solve method solveRecursive.

// /**
// * Check if all rules in the list return a real result. Try to get a real solution from
// * <code>ConditionalExpression</code>s.
// *
// * @param listOfRules a list of rules <code>Rule(variable, value)</code>
// * @return
// */
// private static boolean isReal(IASTAppendable listOfRules) {
// if (listOfRules.isListOfRules(false)) {
// for (int i = 1; i < listOfRules.size(); i++) {
// IAST rule = listOfRules.getAST(i);
// IExpr rhs = rule.second();
// if (!rhs.isRealResult()) {
// try {
// IExpr res = rhs.replaceAll(x -> rewriteConditionalExpressionIfReal(x));
// if (res.isPresent()) {
// listOfRules.set(i, rule.setAtCopy(2, res));
// continue;
// }
// return false;
// } catch (NoEvalException noeex) {
// return false;
// }
// }
// }
// return true;
// }
// return false;
// }
// /**
// * If <code>expr</code> is a <code>ConditionalExpression</code> try to rewrite <code>expr</code>
// * as a real expression.
// *
// * @param expr
// * @return {@link F#NIL} if no <code>ConditionalExpression</code> was matched
// * @throws NoEvalException if <code>ConditionalExpression</code> can not be rewritten as a real
// * result.
// */
// private static IExpr rewriteConditionalExpressionIfReal(IExpr expr) throws NoEvalException {
// if (expr.isConditionalExpression()) {
// IExpr function = expr.first();
// IExpr condition = expr.last();
// IExpr result = EvalEngine.get().evaluate(F.Refine(F.Re(function), condition));
// if (result.isRealResult()) {
// return result;
// }
// throw NoEvalException.CONST;
// }
// return F.NIL;
// }
/**
 * Solve the list of equations recursively. Return a list of rules <code>
 * {var1->expr1, var1->expr2, ...}</code> (typically for NSolve function) or return a &quot;list
 * of list of rules&quot; (typically for Solve function) <code>
 * {{var1->expr11, var1->expr12,...}, {var1->expr21, var1->expr22,...}, ...}</code>. The method
 * solves for the first variable from the <code>variables</code> list and inserts the solution
 * back in the remaining equations and calls the method recursively again with this new system.
 *
 * @param termsEqualZeroList the list of expressions, which should equal <code>0</code>
 * @param inequationsList a list of inequality constraints
 * @param numericFlag if <code>true</code>, try to find a numeric solution
 * @param variables the variables for which the equations should be solved
 * @param engine
 * @return a list of rules (typically NSolve) or a list of list of rules (typically Solve) of the
 *         solutions, <code>F.NIL</code> otherwise.
 */
private static IExpr solveRecursive(IASTMutable termsEqualZeroList, IASTMutable inequationsList, boolean numericFlag, IAST variables, EvalEngine engine) {
    IASTMutable temp = solveTimesEquationsRecursively(termsEqualZeroList, inequationsList, numericFlag, variables, true, engine);
    if (temp.isPresent()) {
        return solveNumeric(QuarticSolver.sortASTArguments(temp), numericFlag, engine);
    }
    if (inequationsList.isEmpty() && termsEqualZeroList.size() == 2 && variables.size() == 2) {
        IExpr firstVariable = variables.arg1();
        IExpr res = eliminateOneVariable(termsEqualZeroList, firstVariable, true, engine);
        if (!res.isPresent()) {
            if (numericFlag) {
                // find numerically with start value 0
                res = engine.evalQuiet(F.FindRoot(termsEqualZeroList.arg1(), F.list(firstVariable, F.C0)));
            }
        }
        if (!res.isList() || !res.isFree(t -> t.isIndeterminate() || t.isDirectedInfinity(), true)) {
            return F.NIL;
        }
        return solveNumeric(res, numericFlag, engine);
    }
    if (termsEqualZeroList.size() > 2 && variables.size() >= 3) {
        // expensive recursion try
        IExpr firstEquation = termsEqualZeroList.arg1();
        IExpr firstVariable = variables.arg1();
        IAST[] reduced = Eliminate.eliminateOneVariable(F.list(F.Equal(firstEquation, F.C0)), firstVariable, true, engine);
        if (reduced != null) {
            variables = variables.splice(1);
            termsEqualZeroList = termsEqualZeroList.removeAtCopy(1);
            // oneVariableRule = ( firstVariable -> reducedExpression )
            IAST oneVariableRule = reduced[1];
            IExpr replaced = termsEqualZeroList.replaceAll(oneVariableRule);
            if (replaced.isList()) {
                IExpr subResult = solveRecursive((IASTMutable) replaced, inequationsList, numericFlag, variables, engine);
                if (subResult.isListOfLists()) {
                    IASTAppendable result = F.ListAlloc(subResult.size());
                    IASTAppendable appendable;
                    for (int i = 1; i < subResult.size(); i++) {
                        IAST listOfRules = (IAST) subResult.getAt(i);
                        replaced = oneVariableRule.second().replaceAll(listOfRules);
                        if (replaced.isPresent()) {
                            replaced = S.Simplify.of(engine, replaced);
                            appendable = listOfRules.copyAppendable();
                            appendable.append(F.Rule(firstVariable, replaced));
                            result.append(appendable);
                        }
                    }
                    return result;
                } else if (subResult.isList()) {
                    // important for NSolve
                    replaced = oneVariableRule.second().replaceAll((IAST) subResult);
                    if (replaced.isPresent()) {
                        IASTAppendable appendable = ((IAST) subResult).copyAppendable();
                        appendable.append(F.Rule(firstVariable, replaced));
                        return appendable;
                    }
                }
            }
        }
    }
    return F.NIL;
}
Also used : IASTAppendable(org.matheclipse.core.interfaces.IASTAppendable) IASTMutable(org.matheclipse.core.interfaces.IASTMutable) IExpr(org.matheclipse.core.interfaces.IExpr) IAST(org.matheclipse.core.interfaces.IAST)

Example 88 with IASTMutable

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

the class Solve method solveTimesEquationsRecursively.

/**
 * Analyze the <code>termsEqualZeroList</code> if it contains a <code>Times[..., ,...]</code>
 * expression. If true, set the factors equal to <code>0</code> and solve the equations
 * recursively.
 *
 * @param termsEqualZeroList the list of expressions, which should equal <code>0</code>
 * @param numericFlag
 * @param variables the variables for which the equations should be solved
 * @param engine the evaluation engine
 * @return
 */
private static IASTMutable solveTimesEquationsRecursively(IASTMutable termsEqualZeroList, IAST inequationsList, boolean numericFlag, IAST variables, boolean multipleValues, EvalEngine engine) {
    try {
        IASTMutable resultList = solveEquations(termsEqualZeroList, inequationsList, variables, 0, engine);
        if (resultList.isPresent() && !resultList.isEmpty()) {
            return resultList;
        }
        Set<IExpr> subSolutionSet = new TreeSet<IExpr>();
        for (int i = 1; i < termsEqualZeroList.size(); i++) {
            IExpr termEQZero = termsEqualZeroList.get(i);
            if (termEQZero.isTimes()) {
                solveTimesAST((IAST) termEQZero, termsEqualZeroList, inequationsList, numericFlag, variables, multipleValues, engine, subSolutionSet, i);
            } else {
                if (termEQZero.isAST()) {
                    // try factoring
                    termEQZero = S.Factor.of(engine, termEQZero);
                    if (termEQZero.isTimes()) {
                        solveTimesAST((IAST) termEQZero, termsEqualZeroList, inequationsList, numericFlag, variables, multipleValues, engine, subSolutionSet, i);
                    }
                }
            }
        }
        if (subSolutionSet.size() > 0) {
            return F.ListAlloc(subSolutionSet);
        }
        return resultList;
    } catch (LimitException le) {
        LOGGER.debug("Solve.solveTimesEquationsRecursively() failed", le);
        throw le;
    } catch (RuntimeException rex) {
        LOGGER.debug("Solve.solveTimesEquationsRecursively() failed", rex);
        if (Config.SHOW_STACKTRACE) {
            rex.printStackTrace();
        }
    }
    return F.NIL;
}
Also used : TreeSet(java.util.TreeSet) IASTMutable(org.matheclipse.core.interfaces.IASTMutable) IExpr(org.matheclipse.core.interfaces.IExpr) LimitException(org.matheclipse.core.eval.exception.LimitException)

Example 89 with IASTMutable

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

the class VisitorReplaceAll method visitAST.

@Override
protected IExpr visitAST(IAST ast) {
    int size = ast.size();
    for (int i = fOffset; i < size; i++) {
        IExpr temp = ast.get(i).accept(this);
        if (temp.isPresent()) {
            // something was evaluated - return a new IAST:
            IASTMutable result = ast.setAtCopy(i, temp);
            ast.forEach(i + 1, size, (x, j) -> {
                IExpr t = x.accept(this);
                if (t.isPresent()) {
                    result.set(j, t);
                }
            });
            return postProcessing(result);
        }
    }
    return F.NIL;
}
Also used : IExpr(org.matheclipse.core.interfaces.IExpr) IASTMutable(org.matheclipse.core.interfaces.IASTMutable)

Example 90 with IASTMutable

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

the class Sum method collectConstantFactors.

private static IExpr collectConstantFactors(final IAST ast, IAST prod, VariablesSet variablesSet) {
    IASTAppendable filterAST = F.TimesAlloc(16);
    IASTAppendable restAST = F.TimesAlloc(16);
    prod.filter(filterAST, restAST, VariablesSet.isFree(variablesSet));
    if (filterAST.size() > 1) {
        IASTMutable reducedSum = ast.setAtCopy(1, restAST.oneIdentity1());
        return F.Times(filterAST.oneIdentity0(), reducedSum);
    }
    return F.NIL;
}
Also used : IASTAppendable(org.matheclipse.core.interfaces.IASTAppendable) IASTMutable(org.matheclipse.core.interfaces.IASTMutable)

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