# The MathMap Language Reference Manual

## Filter Syntax

> options `filter` name `(`user values)
> expression
> `end`

> options can be zero or more options for the filter. They are discussed in detail below.

> The name of the filter can be an arbitrary identifier (identifiers can contain letters, digits and the underscore and must not begin with a digit).

> The user values must be separated by commas. Any number of user values can be specified. See below for a detailed discussion of user values.

## User Values

> `float` name`:` min`-`max `(`default`)`
>   A tuple of type `nil:1` with the value of a floating point number chosen in the range from min to max. The default value is default.
> `int` name`:` min`-`max `(`default`)`
>   A tuple of type `nil:1` with the value of an integer chosen in the range from min to max. The default value is default.
> `bool` name
>   A tuple of type `nil:1` with the value `0` or `1`.
> `color` name
>   A tuple of type `rgba:4`, representing a color.
> `curve` name
>   A function taking a single argument between `0` and `1` and returning the value of the corresponding point on the curve, also between `0` and `1`.
> `gradient` name
>   A function taking a single argument between `0` and `1` and returning the color at that point as a tuple of type `rgba:4`.
> options `image` name
>   A function taking a single argument of type `xy:2` or `ra:2` and returning the color of the point with those coordinates in the image as a tuple of type `rgba:4`. options can be left out or it can be the `unit` option, discussed below.

## Options

> ### `unit`

> > Filters and image user values can be given the `unit` option to use a differently scaled coordinate system. Instead of pixel coordinates, which are the default, a filter or image with the `unit` option will be scaled such that the value along its shorter axis goes from `-1` to `1`. The longer axis will be scaled to preserve the aspect ratio.

> > If the `unit` option is given the `stretched` sub-option in addition, the values along both axes will go from `-1` to `1`.

## The Type System

> Every value in MathMap is a tagged tuple. This means it consists of one or more numbers and a symbolic tag. RGBA colors, for example are represented by tuples of length 4 with the tag `rgba` (standing for "red, green, blue, alpha"). The value `rgba:[1,0,0,1]` for example, represents the fully opaque color red.

> Single numbers are represented by tuples of length 1 with the tag `nil` (which is the default tag). For simplicity's sake, single numbers need not be written in tuple syntax, i.e. `3.1415` is equivalent to `nil:[3.1415]`.

> There are several other tuple tags which are used by MathMap:

> Tag | Purpose
> `nil` | Default tag
> `rgba` | RGBA Color
> `hsva` | HSVA Color
> `ri` | Complex number
> `xy` | Cartesian coordinate
> `ra` | Polar coordinate
> `v2` | 2d vector
> `v3` | 3d vector
> `m2x2` | 2x2 matrix
> `m3x3` | 3x3 matrix
> `quat` | non-commutative quaternion
> `cquat` | commutative quaternion
> `hyper` | hypercomplex number

> In order for the tag system to make sense, operators and functions are overloaded based on the types of their arguments. For this to work at compile time, types must be statically determined. That means that any expression must have only one possible type, e.g. the expression `if x then abc:[1,2,3] else xyz:[4,5] end` is not valid. Furthermore, all assignments to the same variable must have the same type. Hence, `v=[1,2];v=[1,2,3]` is not valid.

> Tuple types are expressed in this manual in the form `T:L` where `T` is the tag and `L` is the length, e.g. `rgba:[1,0,0,1]` has the type `rbga:4`.

> Elements of tuples can be extracted by the indexing operator `[]`. The expression `p[0]`, for example, extracts the first element of `p` and is of type `nil:1`.

## Constants and Internal Variables

> A few variables are set for the position of the pixel to be calculated:
> `xy` (`xy:2`)
>   The cartesian coordinates of the pixel.
> `x` (`nil:1`)
>   The first component of the cartesian coordinates of the pixel.
> `y` (`nil:1`)
>   The second component of the cartesian coordinates of the pixel.
> `ra` (`ra:2`)
>   The polar coordinates of the pixel.
> `r` (`nil:1`)
>   The first component of the polar coordinates of the pixel (`0 <= r < 2*pi`).
> `a` (`nil:1`)
>   The second component of the polar coordinates of the pixel (the distance from the center).
> To make it easier to write expressions which depend on the image size, a few additional variables are set:
> `WH` (`xy:2`)
>   The size of the image.
> `W` (`nil:1`)
>   The width of the image.
> `H` (`nil:1`)
>   The height of the image.
> `R` (`nil:1`)
>   The biggest possible value for `r` in the image, which it has at the four corners.
> `XY` (`xy:2`)
>   The biggest possible value (in both components) for `xy`.
> `X` (`nil:1`)
>   The biggest possible value for `x` for the image.
> `Y` (`nil:1`)
>   The biggest possible value for `y` for the image.
> For the purpose of animations two additional variable are set:
> `t` (`nil:1`)
>   The time which is `0 <= t < 1`. If animation is disabled, the value of `t` can be chosen in the Settings tab. If you want to make animations loop, set the 'Periodic' check-box in the Settings tab and make sure that the images at `t == 0` and `t == 1` are the same.
> `frame` (`nil:1`)
>   The number of the current frame, beginning with `0` for the first frame.

## Mathematical Constants

> MathMap defines a few mathematical constants to make your life easier:
> `pi` (`nil:1`)
>   3.1415926535...
> `e` (`nil:1`)
>   Euler's constant 2.7182818284...
> `I` (`ri:2`)
>   The imaginary unit `ri:[0,1]`

## Conditionals and Loops

> Conditions and invariants are always expected to evaluate to tuples of length 1.

> > `if` condition `then`
> > consequence
> > `end`
> >   Returns the value of consequence if the value of condition is not `0`, `0` otherwise.
> > `if` condition `then`
> > consequence
> > `else`
> > alternative
> > `end`
> >   Returns the value of consequence if the value of condition is not `0`, otherwise the value of alternative.
> > `while` invariant `do`
> > body
> > `end`
> >   While invariant is not `0`, executes body, then returns `0`.
> > `do`
> > body
> > `while` invariant `end`
> >   Executes body until invariant is not equal `0`, then returns `0`.
> > `for` counter `=` start `..` end `do`
> > body
> > `end`
> >   Executes body with the variable counter going from start to end, then returns 0. Semantically equivalent to
> >   counter `=` start`;`
> >   `__tmp` `=` end`;`
> >   `while` counter `<=` `__tmp` `do`
> >   body`;`
> >   counter `=` counter `+` `1``;`
> >   `end`

## Operators and Functions

> Operators and functions in MathMap are overloaded based on the number and tuple types of their arguments. The reference enumerates all the ways in which operators and functions are overloaded by giving the argument and return types like this: `(v3:3, m3x3:9) -> v3:3`. This particular example describes a function taking two arguments, the first of length 3 with the tag `v3` and the second of length 9 with the tag `m3x3`, and returning a tuple of length 3 with the tag `v3`.

> Most overloading specifications are parametric, though, in that the length and/or tag of the tuples is not fixed, like here: `(?t:1, ?t:1) -> ?t:1`. The question mark indicates a parametric variable (in this case `?t`, whose value is arbitrary, but which must have the same value wherever it occurs. Here the function takes two arguments, both of length 1 and both having the same, but arbitrary, tag. It returns a tuple of length 1 with that very same tag. Parametric variables denoted just by a question mark, without any symbolic name, are arbitrary and independent of all other parametric variables, i.e. two sole question marks can have different values.

> ## `a + b`

> > > `(ri:2, ri:2) -> ri:2`
> > > `(ri:2, ?:1) -> ri:2`
> > > `(?:1, ri:2) -> ri:2`
> > > `(?t:1, ?t:1) -> ?t:1`
> > > `(?t:?l, ?:1) -> ?t:?l`
> > > `(?t:?l, ?t:?l) -> ?t:?l`

> > Addition. Works on real numbers, complex numbers and tuples. Tuples can be added element-wise or the same real number can be added to each element of a tuples.

> ## `a && b`

> > > `(?t:1, ?t:1) -> ?t:1`

> > The logical conjunction of the two arguments.

> ## `a / b`

> > > `(ri:2, ri:2) -> ri:2`
> > > `(?t:1, ri:2) -> ri:2`
> > > `(?:2, m2x2:4) -> v2:2`
> > > `(?:3, m3x3:9) -> v3:3`
> > > `(?t:1, ?t:1) -> ?t:1`
> > > `(?t:?l, ?:1) -> ?t:?l`
> > > `(?t:?l, ?t:?l) -> ?t:?l`

> > Division. Works on real numbers, complex numbers, tuples, vectors and matrices. A tuple can be divided by another element-wise or by the same number for each element. Vectors can be divided by matrices.

> ## `a == b`

> > > `(?t:1, ?t:1) -> ?t:1`

> > Returns 1 if the arguments are equal, otherwise 0.

> ## `a > b`

> > > `(?t:1, ?t:1) -> ?t:1`

> > Returns 1 if `a` is greater than `b`, otherwise 0.

> ## `a >= b`

> > > `(?t:1, ?t:1) -> ?t:1`

> > Returns 1 if `a` is greater or equal than `b`, otherwise 0.

> ## `a < b`

> > > `(?t:1, ?t:1) -> ?t:1`

> > Returns 1 if `a` is less than `b`, otherwise 0.

> ## `a <= b`

> > > `(?t:1, ?t:1) -> ?t:1`

> > Returns 1 if `a` is less or equal than `b`, otherwise 0.

> ## `a % b`

> > > `(?t:1, ?t:1) -> ?t:1`
> > > `(?t:?l, ?:1) -> ?t:?l`
> > > `(?t:?l, ?t:?l) -> ?t:?l`

> > Remainder. Calculates the remainder of a division. Works on real numbers and tuples. The remainder can be calculated for two tuples element-wise or for one tuple and the same number for each element of the tuple.

> ## `a * b`

> > > `(ri:2, ri:2) -> ri:2`
> > > `(?:1, ri:2) -> ri:2`
> > > `(m2x2:4, m2x2:4) -> m2x2:4`
> > > `(m3x3:9, m3x3:9) -> m3x3:9`
> > > `(v2:2, m2x2:4) -> v2:2`
> > > `(v3:3, m3x3:9) -> v3:3`
> > > `(m2x2:4, v2:2) -> v2:2`
> > > `(m3x3:9, v3:3) -> v3:3`
> > > `(quat:4, quat:4) -> quat:4`
> > > `(cquat:4, cquat:4) -> cquat:4`
> > > `(hyper:4, hyper:4) -> hyper:4`
> > > `(?t:1, ?t:1) -> ?t:1`
> > > `(?t:?l, ?:1) -> ?t:?l`
> > > `(?t:?l, ?t:?l) -> ?t:?l`

> > Multiplication. Works on real numbers, complex numbers, quaternions, hypercomplex numbers, tuples, vectors and matrices. Two tuples can be multiplied element-wise or a tuple can be multipled by a single number for each element. Vectors and matrices can be multipled in both directions and two matrices can be multipled as well.

> ## `-x`

> > > `(?t:?l) -> ?t:?l`

> > Negation.

> ## `!a`

> > > `(?t:1) -> ?t:1`

> > The logical negation of the argument.

> ## `a != b`

> > > `(?t:1, ?t:1) -> ?t:1`

> > Returns 1 if the arguments are not equal, otherwise 0.

> ## `a || b`

> > > `(?t:1, ?t:1) -> ?t:1`

> > The logical disjunction of the two arguments.

> ## `a ^ b`

> > > `(ri:2, ?t:1) -> ri:2`
> > > `(ri:2, ri:2) -> ri:2`
> > > `(?t:1, ri:2) -> ri:2`
> > > `(?t:1, ?t:1) -> ?t:1`
> > > `(?t:?l, ?:1) -> ?t:?l`

> > Exponentiation of real and complex numbers and tuples. A tuple can be exponentiated for each element by a single number.

> ## `a - b`

> > > `(ri:2, ri:2) -> ri:2`
> > > `(ri:2, ?:1) -> ri:2`
> > > `(?:1, ri:2) -> ri:2`
> > > `(?t:1, ?t:1) -> ?t:1`
> > > `(?t:?l, ?:1) -> ?t:?l`
> > > `(?t:?l, ?t:?l) -> ?t:?l`

> > Subtraction. Works on real numbers, complex numbers and tuples. One tuple can be subtracted from another element-wise or the same real number can be subtracted from each element of a tuple.

> ## `a xor b`

> > > `(?t:1, ?t:1) -> ?t:1`

> > The logical exclusive disjunction of the two arguments.

> ## `abs(a)`

> > > `(ri:2) -> nil:1`
> > > `(quat:4) -> nil:1`
> > > `(cquat:4) -> nil:1`
> > > `(hyper:4) -> nil:1`
> > > `(?t:1) -> ?t:1`
> > > `(?t:?l) -> ?t:?l`

> > Absolute value of real numbers, complex numbers (magnitude), quaternions, hypercomplex numbers and vectors (Euclidian norm).

> ## `acos(a)`

> > > `(ri:2) -> ri:2`
> > > `(?t:1) -> ?t:1`

> > Arccosine of real and complex numbers.

> ## `acosh(a)`

> > > `(ri:2) -> ri:2`
> > > `(?t:1) -> ?t:1`

> > Hyperbolic arccosine of real and complex numbers.

> ## `alpha(c)`

> > > `(rgba:4) -> nil:1`

> > The alpha (opacity) component of the color `c`.

> ## `arg(a)`

> > > `(ri:2) -> nil:1`

> > The argument of a complex number.

> ## `asin(a)`

> > > `(ri:2) -> ri:2`
> > > `(?t:1) -> ?t:1`

> > Arcsine of real and complex numbers.

> ## `asinh(a)`

> > > `(ri:2) -> ri:2`
> > > `(?t:1) -> ?t:1`

> > Hyperbolic arcsine of real and complex numbers.

> ## `atan(y, x)`

> > > `(?t:1, ?t:1) -> ?t:1`

> > Arctangent of `y/x`, with the signs of the arguments taken into account to determine the correct quadrant of the result.

> ## `atan(a)`

> > > `(ri:2) -> ri:2`
> > > `(?t:1) -> ?t:1`

> > Arctangent of real and complex numbers.

> ## `atanh(a)`

> > > `(ri:2) -> ri:2`
> > > `(?t:1) -> ?t:1`

> > Hyperbolic arctangent of real and complex numbers.

> ## `beta(a, b)`

> > > `(?t:1, ?t:1) -> ?t:1`

> > The complete beta function for positive real arguments.

> ## `blue(c)`

> > > `(rgba:4) -> nil:1`

> > The blue component of the color `c`.

> ## `ceil(a)`

> > > `(?t:1) -> ?t:1`

> > The ceiling of a number, defined as the smallest integer not smaller than that number.

> ## `clamp(a, l, u)`

> > > `(?t:?l, ?t:?l, ?t:?l) -> ?t:?l`

> > Clamp each element of tuple `a` to be not less than the corresponding element in `l` and not greater than the corresponding element in `u`.

> ## `conj(a)`

> > > `(ri:2) -> ri:2`

> > The complex conjugate.

> ## `cos(a)`

> > > `(ri:2) -> ri:2`
> > > `(?t:1) -> ?t:1`

> > Cosine of real and complex numbers.

> ## `cosh(a)`

> > > `(ri:2) -> ri:2`
> > > `(?t:1) -> ?t:1`

> > Hyperbolic cosine of real and complex numbers.

> ## `crossp(a, b)`

> > > `(?t:3, ?t:3) -> ?t:3`

> > Cross product of two tuples/vectors with three elements.

> ## `deg2rad(a)`

> > > `(?:1) -> nil:1`

> > Convert degrees to radians.

> ## `det(a)`

> > > `(m2x2:4) -> nil:1`
> > > `(m3x3:9) -> nil:1`

> > Determinant of a matrix.

> ## `dotp(a, b)`

> > > `(?t:?l, ?t:?l) -> nil:1`

> > Dot product of two tuples/vectors.

> ## `ell_int_D(phi, k, n)`

> > > `(?t:1, ?t:1, ?t:1) -> ?t:1`

> > Incomplete elliptic integral D in Legendre form.

> ## `ell_int_E(phi, k)`

> > > `(?t:1, ?t:1) -> ?t:1`

> > Incomplete elliptic integral E in Legendre form.

> ## `ell_int_Ecomp(k)`

> > > `(?t:1) -> ?t:1`

> > Complete elliptic integral E in Legendre form.

> ## `ell_int_F(phi, k)`

> > > `(?t:1, ?t:1) -> ?t:1`

> > Incomplete elliptic integral F in Legendre form.

> ## `ell_int_Kcomp(k)`

> > > `(?t:1) -> ?t:1`

> > Complete elliptic integral K in Legendre form.

> ## `ell_int_P(phi, k, n)`

> > > `(?t:1, ?t:1, ?t:1) -> ?t:1`

> > Incomplete elliptic integral P in Legendre form.

> ## `ell_int_RC(x, y)`

> > > `(?t:1, ?t:1) -> ?t:1`

> > Incomplete elliptic integral RC in Carlson form.

> ## `ell_int_RD(x, y, z)`

> > > `(?t:1, ?t:1, ?t:1) -> ?t:1`

> > Incomplete elliptic integral RD in Carlson form.

> ## `ell_int_RF(x, y, z)`

> > > `(?t:1, ?t:1, ?t:1) -> ?t:1`

> > Incomplete elliptic integral RF in Carlson form.

> ## `ell_int_RJ(x, y, z, p)`

> > > `(?t:1, ?t:1, ?t:1, ?t:1) -> ?t:1`

> > Incomplete elliptic integral RJ in Carlson form.

> ## `ell_jac_cn(u, m)`

> > > `(?t:1, ?t:1) -> ?t:1`
> > > `(ri:2, ?:1) -> ri:2`

> > Jacobian elliptic function cn for real and complex arguments.

> ## `ell_jac_dn(u, m)`

> > > `(?t:1, ?t:1) -> ?t:1`
> > > `(ri:2, ?:1) -> ri:2`

> > Jacobian elliptic function dn for real and complex arguments.

> ## `ell_jac_sn(u, m)`

> > > `(?t:1, ?t:1) -> ?t:1`
> > > `(ri:2, ?:1) -> ri:2`

> > Jacobian elliptic function sn for real and complex arguments.

> ## `exp(a)`

> > > `(ri:2) -> ri:2`
> > > `(?t:1) -> ?t:1`

> > The natural exponential function e^x for real and complex numbers.

> ## `floor(a)`

> > > `(?t:1) -> ?t:1`

> > The floor of a number, defined as the largest integer not greater than that number.

> ## `gamma(a)`

> > > `(ri:2) -> ri:2`
> > > `(?t:1) -> ?t:1`

> > The (logarithm of the) gamma function for real and complex numbers.

> ## `gray(c)`

> > > `(rgba:4) -> nil:1`

> > The luminance value of the color `c`.

> ## `grayColor(g)`

> > > `(?t:1) -> rgba:4`

> > Returns a fully opaque gray RGBA color with luminance `g`, i.e. `rgba:[g,g,g,1]`.

> ## `grayaColor(g, a)`

> > > `(?t:1, ?t:1) -> rgba:4`

> > Returns a gray RGBA color with luminance `g` and alpha component `a`, i.e. `rgba:[g,g,g,a]`.

> ## `green(c)`

> > > `(rgba:4) -> nil:1`

> > The green component of the color `c`.

> ## `inintv(a, l, u)`

> > > `(?t:1, ?t:1, ?t:1) -> ?t:1`

> > Returns 1 if `a` lies in the interval defined by the lower bound `l` and the upper bound `u`, otherwise 0.

> ## `lerp(p, a, b)`

> > > `(?:1, ?t:?l, ?t:?l) -> ?t:?l`
> > > `(?t:?l, ?t:?l, ?t:?l) -> ?t:?l`

> > Linear interpolation between `a` and `b`, done element-wise. The result is `a` if `p` is 0, `b` if `p` is 1, and linearly interpolated in between. More formally, the result is `a*(1-t)+b*t`.

> ## `log(a)`

> > > `(ri:2) -> ri:2`
> > > `(?t:1) -> ?t:1`

> > The natural logarithm for real and complex numbers.

> ## `max(a, b)`

> > > `(?t:?l, ?t:?l) -> ?t:?l`

> > The larger of two numbers. For tuples, the larger number for each pair of elements is determined.

> ## `min(a, b)`

> > > `(?t:?l, ?t:?l) -> ?t:?l`

> > The smaller of two numbers. For tuples, the smaller number for each pair of elements is determined.

> ## `noise(a)`

> > > `(?:3) -> nil:1`

> > A solid noise function defined in three-dimensional space. Its values lie between -1 and 1.

> ## `normalize(a)`

> > > `(?t:?l) -> ?t:?l`

> > Normalize a vector to Euclidian length 1.

> ## `pmod(a, b)`

> > > `(?t:1, ?t:1) -> ?t:1`

> > The remainder of a division, made positive if the dividend is negative by adding the divisor.

> ## `print(val)`

> > > `(?:?) -> nil:1`

> > Print a tuple to standard output. Useful for debugging a script.

> ## `rad2deg(a)`

> > > `(?:1) -> deg:1`

> > Convert radians to degrees.

> ## `rand(a, b)`

> > > `(?t:1, ?t:1) -> ?t:1`

> > A random number between `a` and `b`.

> ## `red(c)`

> > > `(rgba:4) -> nil:1`

> > The red component of the color `c`.

> ## `rgbColor(r, g, b)`

> > > `(?t:1, ?t:1, ?t:1) -> rgba:4`

> > Returns a fully opaque RGBA color with red component `r`, green component `g` and blue component `b`, i.e. `rgba:[r,g,b,1]`.

> ## `rgbaColor(r, g, b, a)`

> > > `(?t:1, ?t:1, ?t:1, ?t:1) -> rgba:4`

> > Returns an RGBA color with red component `r`, green component `g`, blue component `b` and alpha component `a`, i.e. `rgba:[r,g,b,a]`.

> ## `scale(a, fl, fu, tl, tu)`

> > > `(?t:?l, ?t:?l, ?t:?l, ?t:?l, ?t:?l) -> ?t:?l`

> > Scale each element of `a` which is supposed to lie between the corresponding elements of `fl` and `fu` to lie at the same point between `tl` and `tu`, proportionately. More formally, computes `((a-fl)/(fu-fl))*(tu-tl)+tl`.

> ## `sign(a)`

> > > `(?t:?l) -> ?t:?l`

> > The sign of a number or tuple. The sign of a number is -1 if the number is negative, 1 if the number is positive and 0 if the number is 0. For a tuple, calculates the sign element-wise.

> ## `sin(a)`

> > > `(ri:2) -> ri:2`
> > > `(?t:1) -> ?t:1`

> > Sine of real and complex numbers.

> ## `sinh(a)`

> > > `(ri:2) -> ri:2`
> > > `(?t:1) -> ?t:1`

> > Hyperbolic sine of real and complex numbers.

> ## `sqrt(a)`

> > > `(ri:2) -> ri:2`
> > > `(?t:1) -> ?t:1`

> > The square root of a complex or real number. A real argument must be positive, otherwise the result will not be definied.

> ## `sum(a)`

> > > `(?t:?l) -> ?t:1`

> > The sum of all elements of a tuple.

> ## `tan(a)`

> > > `(ri:2) -> ri:2`
> > > `(?t:1) -> ?t:1`

> > Tangent of real and complex numbers.

> ## `tanh(a)`

> > > `(ri:2) -> ri:2`
> > > `(?t:1) -> ?t:1`

> > Hyperbolic tangent of real and complex numbers.

> ## `toHSVA(a)`

> > > `(rgba:4) -> hsva:4`

> > Conversion of an RGBA color value to HSVA.

> ## `toRA(arg)`

> > > `(xy:2) -> ra:2`
> > > `(ra:2) -> ra:2`

> > Conversion of rectangular coordinates to polar coordinates.

> ## `toRGBA(a)`

> > > `(hsva:4) -> rgba:4`

> > Conversion of an HSVA color value to RGBA.

> ## `toXY(a)`

> > > `(ra:2) -> xy:2`
> > > `(xy:2) -> xy:2`

> > Conversion of polar coordinates to rectangular coordinates.