- JavaDoc

# JEP

- Introduction
- Basic Usage
- Variables
- Data types
- Operators
- Functions
- BigDecimal
- FAQ
- Migration
- Version History

# Advanced Features

- Manipulating Expressions
- Components
- Configurable Parser
- Serialization
- Grammar

# Basic Usage

- Getting started
- Handling errors
- Evaluation methods
- Fast evaluation using RealEvaluator
- Fast repeated evaluation
- Decimal arithmetic
- Implicit multiplication
- Multiple expressions

## Getting started

Using the Jep package of classes in your project is simple! The following steps will get you started quickly.

1. Download the Jep package
2. Unpack the archive
3. Move the `jep-x.x.x.jar` file (located in the main directory) to a directory of your choice
4. IMPORTANT: For the Java compiler to be able to find the Jep classes when compiling your program, it needs to know their location. You will need to set the location of the jar archive in your Java IDE so that the compiler finds the library (refer to your IDE manual for how to do this). If you are not using an IDE, you will need to add the location of the .jar file to your CLASSPATH environment variable (if you don't know how, read this). Your CLASSPATH variable should contain something like C:\java\packages\jep-x.x.x.jar, depending on where you place the jar file.
5. Include the following code in your program

       import com.singularsys.jep.Jep;
       ...
        1: Jep jep = new Jep();
        2: jep.addVariable("x", 10);
        3: try {
        4:    jep.parse("x+1");
        5:    Object result = jep.evaluate();
        6:
        7:    System.out.println("x + 1 = " + result);
        8:
        9: } catch (JepException e) {
       10:    System.out.println("An error occured: " + e.getMessage());
       11: }

   Line 1 creates a new Jep parser object (Javadoc class description). Line 2 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.
6. You should be able to compile your application and see the result printed when you run your program.

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!

## Handling errors

Exceptions are thrown by the parse and evaluate methods if an error occurs. Parsing method 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 occured through the `getMessage()` method.

## Default setup

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

## Evaluation methods

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.

## Fast evaluation using RealEvaluator

If you want to speed up your calculations, and you are not using strings, vectors or complex numbers, you can use the `RealEvaluator` instead of the `StandardEvaluator`. Evaluation is sped up by using only the primitive `double` type rather than creating `Double` objects. Load the `RealEvaluator` by calling `setComponent(Component)` as shown below.

    import com.singularsys.reals.RealEvaluator;
    ...
    jep.setComponent(new RealEvaluator());

The performance gain depends on factors such as the expression, the JVM and operating system. Typically, a peformance increase of over 50% should be expected. Performance tests on a MacBook Pro with a 1.8 GHz Core Duo processor running JVM 1.5 ranged from 2x to 6x performance gain. The same tests on a Windows machine with a 1.6GHz Pentium processor resulted in up to 4x performance. The results are summarized in the following table:

Processor (OS) | JRE Version | Performance Gain
1.6 GHz Pentium (Windows XP) | 1.6 | 2x - 3x
1.6 GHz Pentium (Windows XP) | 1.5 | 2x - 4x
1.8 GHz Core Duo (Mac OS X) | 1.5 | 2x - 6x

## Fast repeated evaluation

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`.

## Decimal arithmetic

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.

## Implicit multiplication

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.

## Handling multiple expressions

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()) {
    		Object res = jep.evaluate(n);
    	}
    }
    catch (JepException e) { }