# Wiki

Clone wiki# mikulas / mexpr / index

# Mexpr

Mexpr is a library supporting writing mathematical expressions and their evaluation.

Scientific applications sometimes need to enter some formulas and evaluate them or show them in a graph. The formula is not a part of the application but user usually wishes to enter own formula and evaluate it.

## ExpressionParser

### Simplest expression

Main class to use is `ExpressionParser`

Example of use:

ExpressionParser expressionParser = new ExpressionParser("100 * 10 + 25"); double result = expressionParser.evaluateDouble();

### Variables

More complex use may contain variables (which can be considered to be some constants):

#### Easy Variables

Passing a value into variable, like 'x':

ExpressionParser expressionParser = new ExpressionParser("100 * x + 25", Map.of("x", 20)); double result = expressionParser.evaluateDouble();

*Note: the number 20 in this case can't be changed so it's in fact a constant unless using settable instance like DoubleHolder*

#### Settable Variables

Variables can be set without need to recompile expression which would be slow for scientific calculations, like using in equations or drawing a graph.

DoubleHolder xHolder = new DoubleHolder(); // DoubleHolder is a Supplier<Double> with possibility to dynamically change the value ExpressionParser expressionParser = new ExpressionParser("x + 1", Map.of("x", xHolder)); xHolder.accept(10); expressionParser.evaluateDouble(); // 11 xHolder.accept(20); expressionParser.evaluateDouble(); // 21

#### Typical Use Case

An exception should be expected for the parsing. Depending on exception the input should be changed:

ExpressionParser expressionParser = null; try { expressionParser = new ExpressionParser("100 * x + 25"); } catch (ParseExpressionException e) { if (e instanceof UndefinedVariableException) { expressionParser = new ExpressionParser("100 * x + 25", Map.of(e.getVariableName(), 10)); // setting value for missing x variable } } ... double result = expressionParser.evaluateDouble();

### Constants

Also constants like `pi`

are supported:

ExpressionParser expressionParser = new ExpressionParser("pi * r ^ 2", Map.of("r", 20)); double result = expressionParser.evaluateDouble();

### Functions

#### Expressed Functions

They can be made easily directly by user using a declaring and defining string present in the map.

```
new ExpressionParser("sin(0.5) + quadr(11)", Map.of("quadr(x)", "11 * x ^ 2 + 21 * x + 31"));
```

Invalid example:

```
new ExpressionParser("f(11)", Map.of("f(x)", "x + a"));
```

```
new ExpressionParser("f(11)", Map.of("f(x)", "x + a", "a", 20));
```

new ExpressionParser("f(10, 20)", Map.of("f(x, a)", "x + a", "a", 40)); // 30

#### Java Functions

Functions can be made by a java class annotated with `@FunctionalSupplier`

. All such classes with such annotation are ready to use in expression. There are some prepared basic math functions, like `sin`

, `log`

, ...
Prepared functions are all functions found on classpath and their package starts with `cz.jmare.mexpr.func`

but another custom functions with own package may be also added. Prepared functions can be disabled by `new Config().withPredefinedClasses(false);`

, config is passed as an argument int ExpressionParser constructor.

List of available java functions:

SupplierInfos supplierInfos = SuppliersClassesProvider.getSupplierInfosEmbedded(true); System.out.println(supplierInfos.funcInfos);

Example of use:

ExpressionParser expressionParser = new ExpressionParser("sin(2 * pi)"); double result = expressionParser.evaluateDouble();

They can be used, for example, in graphs.

DoubleHolder xHolder = new DoubleHolder(); ExpressionParser expressionParser = new ExpressionParser("sin(x * 2 * pi)", Map.of("x", xHolder)); for (double x = 0; x < 10; x += 0.01) { xHolder.accept(x); double y = expressionParser.evaluateDouble(); plot(x, y); }

Note: We are creating a DoubleHolder instance which is a Supplier providing a value and it's also a Consumer to set the value. The expression needn't be compiled for each evaluation but rather we only set the value and get a new result.

##### Useful functions

I often use functions, like `sin`

, `rand`

. For example to generate a sine wave with standard deviation of 0.05 such formula may be used:

```
sin(x * 2 * pi) + rand(-0.1, 0.1)
```

Or to generate one curve with two frequencies where `x = 1`

is a border:

```
sin(x * 2 * pi) * less(x, 1) + sin(x * 2 * pi * 2) * greater(x, 1)
```

`between`

function to define a range.
Also functions like `log`

are often used. Note they can contain various number of parameters and some functions like `log`

may contain one or two parameters. The second parameter is the base. For `base=10`

the `log10`

function can be also used as shortcut.

## Application configuration

Use following Maven configuration before start:

<dependency> <groupId>io.bitbucket.janmaren</groupId> <artifactId>mexpr</artifactId> <version>1.1</version> </dependency>

See also expression syntax

Updated