Reputation: 1773
I'm having trouble adding this functionality to my calculator app. Here's what I had in mind:
I want to solve: 2x = 5 + 4x
.
To solve this is no problem if I would use an external token library to parse the equation, but since my entire program is built around a shunting yard parser (EXP4J), it complicates things. You might say that I could just use the token parser for specific cases, but when you consider that I have FUNCTIONS using EXP4J, it becomes really tangled.
So, while I could make it work for 2x = 5 + 4x
by simply alternating to a token parser for this specific case, calculations that use EXP4J, like:
2x = 5*exp4jfunc(x + 5,x) + cos(x)
are completely beyond me.
Does anyone have any idea on how to get around this? I don't even know how my CASIO tackles this, as it freezes on solve-for-x equations like x = 9^x
...
Upvotes: 2
Views: 2317
Reputation: 958
With the symja library you can solve your problem like this:
package org.matheclipse.core.examples;
import org.matheclipse.core.eval.ExprEvaluator;
import org.matheclipse.core.interfaces.IExpr;
import org.matheclipse.parser.client.SyntaxError;
import org.matheclipse.parser.client.math.MathException;
public class Solve2Example {
public static void main(String[] args) {
try {
ExprEvaluator util = new ExprEvaluator();
IExpr result = util.evaluate("Solve(2*x==5 + 4*x,x)");
// print: {{x->-5/2}}
System.out.println(result.toString());
result = util.evaluate("Roots(2*x==5+4*x, x)");
// print: x==-5/2
System.out.println(result.toString());
} catch (SyntaxError e) {
// catch Symja parser errors here
System.out.println(e.getMessage());
} catch (MathException me) {
// catch Symja math errors here
System.out.println(me.getMessage());
} catch (Exception e) {
e.printStackTrace();
}
}
}
You can look into the implementation of the Roots() function how the parsed AST is transformed to solve the equation.
Upvotes: 2
Reputation: 18813
I am not really familiar with exp4j... Given that the Expression
class doesn't seem to provide much access to the parsed structure, a symbolic approach seems not really feasible with exp4j.
One thing you could try with exp4j instead:
Split the equation at =
into left
and right
Build a new equation that is the difference of both sides:
String diff = "(" + left + ") - (" + right + ")"
Parse diff
with exp4j
Use a numerical method (e.g. the Secant method) with setVariable()
and evaluate()
to find the solution(s).
Shameless plug: If you are considering to use a different parser, take a look at this one
Upvotes: 1
Reputation: 3567
First, define the domain of your equations. Are you talking about linear equations, polynomials, general non-linear equations, differential equations? Then define your dimension: Do you have one variable or many? Finally, select the appropriate solver (numerical, symbolical, Gauss, Newton etc.).
Once you have defined this, you need to transform the syntax tree of exp4j into the format required by the solver. However it seems that you won't be able to do this with exp4j, since it does not expose the structure of an expression as an API.
I would advice to use a proper AST. If you cannot do that, you can see in the implementation, that the internal structure is basically just a token list.
Upvotes: -1