Data Types

Jep supports a number of different data types in the standard mode. These include numbers, strings, vectors, and complex numbers. By default numbers are represented by the double data type. It is however possible to change the internal representation as described in the section on Custom types.

Strings

Strings can be entered in an expression by using double quotes. They can be concatenated with the + operator and compared with the == and != relational operators. A sample expression involving the string type is "foo" + "bar" == "foobar", which would be evaluated by Jep as true.

To add a string as a variable, use the addVariable(String name, Object value) method. If the result of an expression is a string, it can be obtained by calling the evaluate() function.

top

Vectors

A vector is a list of values, separated by commas, and enclosed by square brackets. You can access elements of a vector using square brackets. For example, to access the second element of a vector v, use v[2] to access its value.

Some example expressions involving a vectors are listed below

a = [2, 3, 10]   // create a variable with a vector value
a[1]             // evaluates as 2
a[3]             // evaluates as 10

a + [1, 2, 3]    // addition, evaluates as [3, 5, 13]
a - [1, 2, 3]    // subtraction, evaluates as [1, 1, 7]
[3, 4, 5]*2      // multiplication by a scalar,
                 // evaluates as [6, 8, 10]
[1,2] * [1,2]    // interpreted as a column vector times a row
                 // vector. Evaluates as [[1.0, 2.0], [2.0, 4.0]]
[4, 6, 8]/2      // division by a scalar, evaluates as [2, 3, 4]
[1,2,3].[1,2,3]  // dot product, evaluates as 14
[1,2,3]^^[1,2,3] // cross product, evaluates as [0, 0, 0]
min([6,4,7,8])   // minimum value, 4
max([6,4,7,8])   // minimum value, 8
avg([6,4,7,8])   // average value, 2.5
vsum([6,4,7,8])  // sum of elements, 25

Internally, vector values are represented as lists, specifically Vector<Object>. To add a vector as a variable, use the addVariable(String name, Object value) method. The value parameter should be of type Vector<Object>. If the result of an expression is a vector, it can be obtained by calling the evaluate() method.

A vector valued variable can be used as follows:

    // Add the variable y with value [1.2,3.4]
    jep.addVariable("y", new Vector<Object>(Arrays.asList(new Double[]{1.2,3.4})));
    // Use the y[2] syntax to get a specific element
    Object res = jep.evaluate(jep.parse("y[2]"));
    assertEquals(3.4,res);
    // calculate the vector expression y*2 
    Object res2 = jep.evaluate(jep.parse("y*2"));
    // The returned type will be Vector<Object>
    assertTrue(res2 instanceof Vector<?>);
    Vector<Object> vec = (Vector<Object>) res2;
    // Convert to an array
    Object[] array = vec.toArray();
    assertArrayEquals(new Object[]{2.4,6.8},array);

There is very limited support for matrices. Matrices can be specified as nested vectors [[1.0, 2.0], [2.0, 4.0]]. Vectors multiplied by vectors will give matrices, but multiplying matrices by vectors or multiplying matrices by matrices do not give sensible results. The min, max, avg and vsum functions work just like for vectors, collapsing all elements into a one dimensional array.

top

Complex numbers

Jep supports complex numbers in most operators and functions. The complex imaginary unit i is part of the standard variable table and is added to the parser when using the StandardComponents. A set of complex functions are also included. These include re(c), im(c), cmod(c), arg(c), conj(c), complex(x, y) and polar(r, theta). See the functions page for more information on these functions. You will need to import the com.singularsys.jep.standard.Complex class to be able to manipulate complex values from expressions.

By using the imaginary unit constant i, you can work with complex numbers in your expressions. Some sample complex expressions are listed below:

(1+2*i)^3
e^(-i)
re((1+2*i)^2 - (3+3*i)^2)

To obtain a complex value from an expression, you must use the evaluate() method. It will evaluate the expression and return the result as a Complex object.

You will need to manually cast the Object returned to the Complex type.

Adding a complex variable or constant to the parser before evaluating an expression can be done with addVariable(String name, double re, double im). It takes three parameters: the name of the variable as string, the real component, and the imaginary component.

top

Custom types

In most cases, you will only need to work with the few built in types that Jep supplies (Double, Complex, Vector, String). But suppose you want to evaluate expressions that involve other types. You may want to let variables have custom types, or create numbers with custom types.

You can create variables with custom types by using the addVariable(String name, Object value) method.

You can ensure that numbers are created with a specific type by setting the number factory. For example this is how the bigdecimal components are able to create numbers that are more precise than the double type allows. Simply implement the NumberFactory interface, implement the createNumber(String) method, and call setComponent(JepComponent) to load your number factory class into Jep.

When an expression is evaluated, values are operated on with the classes in the function package. These include the operators (such as Add and Subtract), as well as the functions (such as Sine and Cosine). Without making modifications to the source code, only the default types are handled with these classes. So, in order to be able to handle your own types, you will need to modify theses classes, or make your own function classes as described in the custom functions section. For more information see the custom functions section.

top