# Formulae

Sysdea uses a small bespoke language called Syscript for entering calculations. This language should read like usual mathematical notation, with the addition of a simple syntax for conditionals.

## Mathematical Operators

Standard arithmetic is supported with `+ - * / ^` and follows normal precedence rules, which can be made explicit with the use of brackets `( )`.

``````+ - *: Addition, subtraction, multiplication.
/: Division, with division by 0 trapped to equal 0.
a^b: Raises a to the power of b.
a%b: a modulo b
a mod b: a modulo b
``````

## Element references

You can refer to other elements (variables, stocks, flows, etc) by name using double quotes around the name of the element. For example, you could multiply the value of a stock called 'Bank Account' using `"Bank Account" * 3`.

## Builtin Functions

For the function listings, optional parameters are listed with their defaults in the form `parameter=default`. For example, `random(x=1)` means the calls `random()` and `random(1)` are equivalent.

``````abs(x): Return the absolute value of x.
ceil(x): Round x upwards (towards positive) to the nearest integer.
div(x, y, z=0): Divide x by y, returning z if y is 0.
exp(x): Returns the exponential of x (e^x).
floor(x): Round x downwards (towards negative) to the nearest integer.
frac(x): The fractional part of x, e.g. frac(1.7) == 0.7.
int(x): The integer part of x.
Equivalent to floor(x) for positive numbers and ceil(x) for negative numbers.
ln(x): Natural logarithm of x.
log(x): Base 10 logarithm of x.
max(x, y, ...): Returns the maximum of any number of arguments.
min(x, y, ...): Returns the minimum of any number of arguments.
power(x, y): Raises x to the power y, equivalent to x^y.
random(x=1): Returns a random number between 0 and x.
root(x, y): The yth root of x.
round(x, places=0): Rounds x to a number of decimal places, 0.5 rounds up.
round2(x, places=0): Bankers rounding, like round(x, places) but 0.5 rounds to nearest even.
sign(x): -1 for negative numbers, +1 for positive numbers, and 0 for 0.
sqrt(x): Square root of x.
``````

### Time dependent functions

``````delay(expression, n):
Evaluates the expression n time steps in the past. Expression could
be a simple variable reference or a more complicated calculation.

pulse(x, start="start_time", interval=0):
Returns a value of x every interval time steps, beginning at start, 0 otherwise.
An interval of 0 is treated as never repeating the pulse.

ramp(x, start="start_time"):
Smoothly increases in value by x every time step, beginning at start.

step(x, step_time=0):
0 until time reaches step_time, after which it will return x.
``````

## User Functions

To use a user function, call it like a normal function, with the quoted name as the name of the function. For example, if you had a user function 'Lookup Conversion Rate', then you could call it with a value using `"Lookup Conversion Rate"(0.7)`.

Defining user functions is covered separately at Functions.

## Conditionals and Comparison

### Operators

For checking of conditions Syscript supports the usual logical operators necessary to compare numbers and combine logical checks together.

``````Comparison operators:
>: Greater than
>=: Greater than or equal to
<: Less than
<=: Less than or equal to
=: Equal to
!=, <>: Not equal to

Combination operators:
and, &&: Logical AND (conjunction)
or, ||: Logical OR (disjunction)
not, !: Logical NOT (negation)
``````

While these operators can be used outside of the condition sections of `if then else` and `select case`, their behaviour in these circumstances may give rise to errors or confusing behaviour, and so should be avoided.

### If then else

For use if you need to choose between two options based on some condition.

``````if <condition>
then <when true>
else <when false>
``````

### Select case

If you have a series of conditions that may give rise to several different answers, then the `select` syntax is useful. The first condition which evaluates to true will give the result of the `select`. Note that you can have any number of cases but must have a default statement.

``````select
case <condition a>: <when a true>
case <condition b>: <when b true>
...
default: <when none true>
``````

### Examples

``````if "time" < 30 then 1 else 2
``````

At times before 30 this will return 1, and at 30 and after it will return 2.

``````select
case "time" < 30: 1
case "time" < 50: 2
default: 3
``````

At times before 30 this will return 1, between 30 and 50 this will return 2, and at times 50 and after it will return 3.

## Local Variables

You can store intermediate results inside a formula using local variables, which are prefixed with an `@` and then an alphanumeric name (with underscores).

``````@my_var: 2 + "other variable"
@my_var * 3
``````

This would return the value of `@my_var * 3`, equivalent to `(2 + "other variable") * 3`.