Using the Jep package of classes in your project is simple! The following steps will get you started quickly.
jep-java-x.x.x.jar
file (located in the main directory)
to a directory of your choiceimport com.singularsys.jep.Jep; ... 1: Jep jep = new Jep(); 2: try { 3: jep.addVariable("x", 10); 4: jep.parse("x+1"); 5: Object result = jep.evaluate(); 6: 7: System.out.println("x + 1 = " + result); 8: } catch (JepException e) { 9: System.out.println("An error occurred: " + e.getMessage()); 10: }Line 1 creates a new Jep parser object (Javadoc class description). Line 3 adds the variable "x" to the parser and initializes it's value to 10. In lines 4 and 5, the expression "x+1" is parsed and evaluated. The result is stored in
result
.
Finally, the result is printed, resulting in "x + 1 = 11" being
printed.What's next? Browse through the documentation to see what Jep is all capable of. Also have a look at the code of the sample applets. And don't forget to use the Javadocs as handy reference!
Exceptions are thrown by the parse and evaluate methods if an error occurs.
Parsing methods throw ParseException
instances while evaluation
methods throw EvaluationException
instances. Both of these classes
extend the JepException
class. So if you do not need to distinguish
between parsing and evaluation errors, simply catch JepException
instead.
The exception classes provide information about the error that occurred through
the getMessage()
method.
If you create a Jep instance with default settings you can parse expressions with the all functions listed in the Functions section. You can also use the following constants:
pi | 3.1415... The ratio of the circumference of a circle to its diameter (Math.PI ) |
e | 2.718... Euler's constant in double precision (Math.E) |
true | The boolean constant (Boolean.TRUE) |
false | The boolean constant (Boolean.FALSE) |
i | The complex imaginary unit |
Three methods for evaluating an expression are available:
Object evaluate()
: Evaluates the last parsed expression and
returns the result as an object.Object evaluate(Node root)
: Evaluates an expression passed
in by it's root node and returns the result as an Object.double evaluateD()
: Evaluates the last parsed expression
and returns the result as a double value. If the result can not be converted
into a double, an EvaluationException is thrown.You may not always know what type the result of the expression is. For example
it could be Double, Vector, Boolean, or String depending on the expression
parsed. You can use the instanceof
operator to identify the type
of the result, then cast the result into the appropriate class.
It is possible to perform repeated evaluation of expressions while changing variable values without repeatedly parsing the expression. This, of course, is much faster than re-parsing the expression each time it needs to be evaluated.
The following code shows how the addVariable(String, Object)
and evaluate()
functions can be called repeatedly to change variable
values and re-evaluate an expression.
// add variable to allow parsing jep.addVariable("x", 0); jep.parse("2*x-3"); // evaluate expression for x = 0 to x = 99 for (int i=0; i<100; i++) { // update the value of x jep.addVariable("x", i); // print the result System.out.println("Value at x = " + i + ": " + jep.evaluate()); }
You can use fast repeated evaluation with any evaluator including the RealEvaluator
.
With Jep 3, it is now possible to evaluate expression using decimal arithmetic.
The datatype used to represent numbers in this mode is BigDecimal
rather than double
. Simply use the following code for constructing
a new Jep instance:
import com.singularsys.jep.bigDecimals.BigDecComponents; ... jep = new Jep(new BigDecComponents());
The difference in the accuracy is best shown through an example. When performing
multiplication of two numbers of the double
type, 10*0.09 evaluates
as 0.8999999999999999. But when performing the same calculation using
decimal arithmetic with the BigDecimal
type, 10*0.09 evaluates
as 0.9.
If you are interested in performing high precision arithmetic, refer to the BigDecimal section of this documentation.
You can enable the implicit multiplication option with setImplicitMul(true)
.
The default setting is true
(implicit multiplication allowed).
Implicit multiplication allows expressions such as "2 x" to be interpreted as "2*x". Note that a space is required between two variables for them to be interpreted as being multiplied. The same holds for a variable followed by a number. For example "y 3" is interpreted as "y*3", but "y3" is interpreted as a single variable with the name y3. If a variable is preceded by a number, no space is required between them for implicit multiplication to come in effect.
Jep can work with multiple expressions at the same time. A simple approach
is to call the Jep.parse()
method multiple times on multiple
strings. The method returns an object of type Node
which represents the expression tree. These Nodes can be stored
for later use and evaluated using the Jep.evaluate(Node n)
method.
Jep jep = new Jep(); try { Node n1 = jep.parse("y=x^2"); Node n2 = jep.parse("z=x+y"); for (double x=0.0; x<=1.0; x+=0.1) { jep.addVariable("x", x); Object value1 = jep.evaluate(n1); Object value2 = jep.evaluate(n2); } } catch(JepException e) { }
Another approach allows all expressions to be contained in a single string. A sequence of equations can be read from a single string or Reader using the
Jep.initMultiParse(String s)
,
Jep.initMultiParse(Reader r)
and the
continueParsing()
methods. Equations are separated by semi-colons. The parser is initialized by initMultiParse
and the expressions are read in turn using continueParsing()
. For example:
Jep jep = new Jep(); String s = "x=1; y=2; x+y"; jep.initMultiParse(s); try { while ((Node n = jep.continueParsing()) != null) { Object res = jep.evaluate(n); } } catch (JepException e) { }
A significant evaluation speed improvement was made from Jep 3.2 to Jep 3.3 by replacing the default StandardEvaluator component with FastEvaluator. However, if your expressions operate solely on floating point numbers, you can achieve an additional performance boost by using RealEvaluator instead of FastEvaluator.
RealEvaluator can be loaded through the Jep constructor with
Jep jep = new Jep(new RealEvaluator());
or by setting the evaluator after construction:
jep.setComponent(new RealEvaluator());
The performance gain depends on factors such as the expression, the JVM and operating system. In tests, the speedup compared to FastEvaluator was approximately 30%.