- JavaDoc

# JEP

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

# Advanced Features

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

# Functions

Note that you can always add new custom functions. Each of the following functions can be applied to objects of the types indicated.

The StandardFunctionTable includes all of these functions by default. They can also be included individually by calling `jep.getFunctionTable().addFunction(String, PostfixMathCommandI)`. All standard function classes are located in the jep.functions package. The BigDecimal functions are kept separate in the jep.bigdecimal.functions package.

## Trigonometric Functions

All functions accept arguments of the `Double` and `Complex` type, except `atan2` which only accepts `Double` arguments.

Description | Function Name | Class Name
Sine | sin(x) | Sine
Cosine | cos(x) | Cosine
Tangent | tan(x) | Tangent
Arc Sine | asin(x) | ArcSine
Arc Cosine | acos(x) | ArcCosine
Arc Tangent | atan(x) | ArcTangent
Arc Tangent (with 2 parameters) | atan2(y, x) | ArcTangent2
Hyperbolic Sine | sinh(x) | SineH
Hyperbolic Cosine | cosh(x) | CosineH
Hyperbolic Tangent | tanh(x) | TanH
Inverse Hyperbolic Sine | asinh(x) | ArcSineH
Inverse Hyperbolic Cosine | acosh(x) | ArcCosineH
Inverse Hyperbolic Tangent | atanh(x) | ArcTanH

## Log and Exponential Functions

All functions accept arguments of the Double and Complex types.

Description | Function Name | Class Name
Natural Logarithm | ln(x) | NaturalLogarithm
Logarithm base 10 | log(x) | Logarithm
Logarithm base 2 | lg(x) | LogBase2
Exponential (e^x) | exp(x) | Exp
Power | pow(x) | Power

## Statistical Functions

All functions accept either a vector (e.g. `min([1,2,3])`) or a set of numbers (e.g. `min(1,2,3)`).

Description | Function Name | Class Name
Average | avg(x1,x2,x3,...) | Average
Minimum | min(x1,x2,x3,...) | MinMax(true)
Maximum | max(x1,x2,x3,...) | MinMax(false)

## Rounding Functions

Description | Function Name | Class Name
Round | round(x), round(x, p) | Round
Floor | floor(x) | Floor
Ceiling | ceil(x) | Ceil

## Miscellaneous Functions

Description |  | Double | Complex | String | Vector
If | if(cond, trueval, falseval) |  |  |  |
Absolute Value / Magnitude | abs(x) |  |  |  |
Random number (between 0 and 1) | rand() |  |  |  |
Modulus | mod(x,y) = x % y |  |  |  |
Square Root | sqrt(x) |  |  |  |
Sum | sum(x,y,...) |  |  |  |
Str (number to string) | str(x) |  |  |  |
Binomial coefficients | binom(n, i) |  |  |  |

## Complex Functions

Description |  | Double | Complex
Real Component | re(c) |  |
Imaginary Component | im(c) |  |
Complex Modulus (Absolute Value) | cmod(c) |  |
Argument (Angle of complex value, in radians) | arg(c) |  |
Complex conjugate | conj(c) |  |
Complex, constructs a complex number from real and imaginary parts | complex(x, y) |  |
Polar, constructs a complex number from modulus and argument | polar(r, theta) |  |

## Custom Functions

JEP allows you to add custom functions by calling `getFunctionTable().addFunction(String name, PostfixMathCommandI function)`. Custom functions are no different from built-in functions, so you can use the source code of the built-in functions as a template. The class methods are accessed both during parsing and evaluation. During parsing, the parser needs to know how many parameters are allowed. During evaluation, the `run(Stack<Object>)` method is called to perform the actual calculation.

The following is an example of how a custom function can be added.

Assume you want to add a function "half" to divide a number by two (for demonstration purposes).

1. Create a class that extends PostfixMathCommand (in the `com.singularsys.jep.functions` package). In this example we will name it "Half"
2. In the constructor set the number of arguments to be taken. In our case this is one. Do this by writing `numberOfParameters = 1;`
   If you want to allow any number of parameters, initialize the `numberOfParameters` value to -1. It is highly recommended to study the `Sum.java` code as an example of a function that accepts any number of parameters.
3. Implement the`run(Stack<Object> inStack)` method. The parameters are passed in a Stack object. This same stack is used as the output for the function. So we first need to pop the parameter off the stack, calculate the result, and finally pop the result back on the stack.

       public void run(Stack<Object> inStack) throws EvaluationException {

          // check the stack
          checkStack(inStack);

          // get the parameter from the stack
          Object param = inStack.pop();

          // check whether the argument is of the right type
          if (param instanceof Double) {
             // calculate the result
             double r = ((Double)param).doubleValue() / 2;
             // push the result on the inStack
             inStack.push(new Double(r));
          } else {
             throw new EvaluationException("Invalid parameter type");
          }
       }

4. In your main program or applet that is using the parser, add the new function. Do this by writing

       jep.getFunctionTable().addFunction("half", new Half());

5. If numberOfParameters == -1 you may wish to overwrite the `boolean checkNumberOfParameters(int n)` to catch an illegal number of arguments at parse time.

Source files

- CustFunc.java (a testing class)
- Half.java (the Half function class)