Jep 4 Releases

Jep 4 Releases | Jep 3 Releases | Jep 2 Releases | Jep 1 Releases

Contents:

Version 4.1

Build and testing

Bug Fixes

Breaking changes

Spelling corrections

Typos have been fixed in a number of classes, field and method names. These changes will break existing code.

PublishingVariable

The new com.singularsys.jep.misc.publishingvariable package uses the java.util.concurrent.Flow system of Publishers and Subscribers to provide a system to monitor changes to variables using the Observer pattern, and replaces the removed VariableTableObserver class.

It provides:

Overloaded functions

The new com.singularsys.jep.misc.overloadedfunctions package package allows functions to be overloaded.

Dictionaries

The new com.singularsys.jep.misc.dictionary package provides a grammar matcher supporting a JSON like syntax for dictionaries map = {'x':2, 'y':3} } and functions like put(map,'x', 5), get(map,'x'), and keys(map), for operation on on them.

Parallel Parsing

The new com.singularsys.jep.misc.parallelparsing package has classes to allow equations to be parsed in parallel.

Additionally the ConfigurableParser class has two new constructors ConfigurableParser(ConfigurableParser cp) and ConfigurableParser(Jep jep, ConfigurableParser cp) these both reuse an existing parsers grammar and token matchers, allowing parsers that can be safely used in multiple threads to be efficiently created.

Other changes

Functions:

Main Jep class

Parsers and Operators

Component architecture

Visitors

Most visitors have been reworked to implement the com.singularsys.jep.GenericVisitor interface, which provides better type safety and more specific method signatures.

Variables and VariableTables

Console applications

General

top

Version 4.0

Add support for Java Modules

A modularized version of Jep for use with Java 11 is available in the modules directory. The code is written to be compatible with both long term support versions Java SE 8 and Java SE 11.

Handling of non-thread safe functions

Most functions can work fine in multiple threads, there are some which need special treatment. These functions can be indicated by implementing JepComponent which provides a getLightWeightInstance() to return a thread-safe copy of the function.

When using the FunctionTable and OperatorTable in multiple threads their getLightWeightInstance() methods will just return this which is more memory efficient in the default case. This is the behaviour in Jep 3.4 and earlier.

Starting in version 4.0, both FunctionTable and OperatorTableI have shallowCopy() methods. This will create new instance of the table and copies all functions operators into the new table. If the function implements JepComponent then its getLightWeightInstance() is called to return a thread-safe version.

There is also a MediumWeightComponentSet class which can be used to create a Jep instance which insures thread-safe versions of functions. To use

Jep jep = new Jep();
Jep copy = new Jep(new MediumWeightComponentSet(jep));
and the copy instance can be safely used in new thread.

To implement this functionality FunctionTable, and EmptyOperatorTable have protected threadSafeMapCopy() methods which returns a copy of the internal map respecting JepComponents. They also have protected FunctionTable(Map<,>), EmptyOperatorTable(Map<,>) constructors. This allows subclasses it easily implements this behaviour

class MyFunctionTable extends FunctionTable {
    ...
    protected MyFunctionTable(Map<String, PostfixMathCommandI> tbl) {
		super(tbl);
	}

	public FunctionTable shallowCopy() {
    	Map<String,PostfixMathCommandI> newMap = this.threadSafeMapCopy();
        FunctionTable ft = new MyFunctionTable(newMap);
        return ft;
    }
All subclasses also implement these constructors.

The Jep 3.5 release had a broken implementation of getLightWeightInstance() which would always return an empty table.

Evaluation

A new UncheckedEvaluator evaluator which does no checking of intermediate values during evaluation. Produces a 10-20% speed increase.

Slight change in the logic of the FastEvaluator. Test for functions which implement CallbackEvaluationI happens after tests for UnaryFunction etc.

Support for Lambda expressions

The UnaryFunction, BinaryFunction and NaryBinaryFunction have static factory methods which allow creation using lambda functions. For example

// Function using explicit class
UnaryFunction recip = UnaryFunction.instanceOf(
         x -> 1.0 / ((Number) x).doubleValue());
// Function where arguments are of an explicit type
UnaryFunction neg = UnaryFunction.instanceOf(Integer.class, x -> -x );
// Function using a method reference
UnaryFunction cubrt = UnaryFunction.instanceOf(Double.class,Math::cbrt);
// Binary function
BinaryFunction diff =  BinaryFunction.instanceOf(Number.class, 
        (x,y) -> x.doubleValue() -  y.doubleValue());
// NaryBinaryFunction
NaryBinaryFunction sum =  NaryBinaryFunction.instanceOf(
        (x,y) -> ((Number) x).doubleValue() + ((Number) y).doubleValue());

Complex

Bug Fixes

Other changes

Parsing

Functions and operators

Printing

Variables

Light weight components, hooks and serialization

Other changes

Examples and tests