# The MathMap Language Reference Manual

## The Type System

> Every value in MathMap is a tagged tuple. This means it consists of one or more numbers (currently stupidly limited to 9) and a symbolic tag. RGBA colors, for example are represented by tuples of length 4 with the tag `rgba` (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 sake of simplicity, 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
> `m2x2` | 2x2 matrix
> `m3x3` | 3x3 matrix
> `image` | Image ID

> In order for the tag system to make sense, operators and functions are overloaded based on the types of their arguments. In order for this to work at compile time, types must be statically determined. This 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`.

## Variables

> In order for the expression to refer to a pixel in the original image, a few variables are set:
> `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` for the image.
> `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.

## Constants

> MathMap defines a few 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]`

## Operators

> MathMap operators are overloaded based on the types of their arguments. Arithmetic operators work as expected on real and on complex numbers. On tuples with the same length and tag they perform their operation element-wise. If their second argument is a tuple of length 1, they perform element-wise on the left operand always using the same right operand.

> For example, `[1,2,3]+[7,2,4]` gives `nil:[8,4,7]`, while `[1,2,3]+1` gives `nil:[2,3,4]`.

> Relational and logical operators currently only work on tuples with length 1.

> > `+`
> >   Addition
> > `-`
> >   Subtraction
> > `*`
> >   Multiplication. Matrix-matrix, matrix-vector and vector-matrix multiplication for 2x2 or 3x3 matrices is done when the matrix has the type `m2x2:4` or `m3x3:9`, respectively.
> > `/`
> >   Division. Vector-matrix division is done for 2x2 or 3x3 matrices when the matrix has the type `m2x2:4` or `m3x3:9`, respectively.
> > `%`
> >   Modulo. This also works with real numbers.
> > `^`
> >   Exponentation. Does not perform on two tuples of length greater 1.
> > `-` (unary)
> >   Arithmetic negation
> > `==`
> >   Gives `1` if the operands are equal, otherwise `0`.
> > `!=`
> >   Gives `1` if the operands are not equal, otherwise `0`.
> > `<=`
> >   Gives `1` if the first operand is less or equal than the second, `0` otherwise.
> > `>=`
> >   Gives `1` if the first operand is greater or equal than the second, `0` otherwise.
> > `<`
> >   Gives `1` if the first operand is less than the second, `0` otherwise.
> > `>`
> >   Gives `1` if the first operand is greater than the second, `0` otherwise.
> > `||`
> >   Returns `1` if at least one of the operands is not `0`, otherwise `0`.
> > `&&`
> >   Returns `1` if both of the operands is not `0`, otherwise `0`.
> > `!` (unary)
> >   Returns `1` if the operand is `0`, `0` otherwise.
> > `;`
> >   Evaluates both operands (first the left one, then the right one) and gives the value of the second.

## Conditionals and Loops

> Conditions and invariants are always expected to be 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`.

## Built-in Functions

> ### Complex Numbers

> > Complex numbers have type `ri:2`.

> > `arg(x)`
> >   Returns the argument of the complex value `x == ri:[re,im]`, which is `atan(im/re)`.
> > `conj(x)`
> >   Returns the conjugate complex of x == ri:[re,im], which is `ri:[re,-im]`.

> ### Vectors and Matrices

> > Only matrices of dimensions 2x2 and 3x3 are supported. They must have the types `m2x2:4` and `m3x3:9`, respectively.

> > `dotp(x,y)`
> >   Returns the scalar (inner) product of `x` and `y`
> > `crossp(x,y)`
> >   Returns the cross (outer) product of `x` and `y`, which must both have the length 3.
> > `det(m)`
> >   Returns the determinant of matrix `m`.
> > `normalize(v)`
> >   Returns a vector with the same direction as `v` but with length 1. For example, `normalize([2,0,0])` yields `[1,0,0]`.
> > `abs(x)`
> >   Returns the absolute value of `x`. This works with complex numbers and vectors.
> > `sum(t)`
> >   Returns the sum of all elements of the tuple `t`.

> ### Trigonometry

> > Trigonometric functions work with radians on real and complex numbers.

> > `deg2rad(x)`
> >   Returns the value `x` converted from degrees to radians.
> > `rad2deg(x)`
> >   Returns the value `x` converted from radians to degrees.
> > `toRA(xy)`
> >   Converts the cartesian coordinates `xy` (of type `xy:2`) to polar coordinates (of type `ra:2`).
> > `toXY(ra)`
> >   Converts the polar coordinates `ra` (of type `ra:2`) to cartesian coordinates (of type `xy:2`).
> > `sin(x)`
> >   Returns the sine of `x`.
> > `cos(x)`
> >   Returns the cosine of `x`.
> > `tan(x)`
> >   Returns the tangens of `x`.
> > `asin(x)`
> >   Returns the arc-sine of `x`.
> > `acos(x)`
> >   Returns the arc-cosine of `x`.
> > `atan(x)`
> >   Returns the arc-tangent of `x`.
> > `atan(y,x)`
> >   Returns the arc tangent of `x` and `y` which is the same as `atan(y/x)`, except that the signs of `x` and `y` are used to determine the quadrant of the result.

> ### Hyperbolic Functions

> > Hyperbolic functions work on real and complex numbers.

> > `sinh(x)`
> >   Returns the hyperbolic sine of `x`.
> > `cosh(x)`
> >   Returns the hyperbolic cosine of `x`.
> > `tanh(x)`
> >   Returns the hyperbolic tangent of `x`.
> > `asinh(x)`
> >   Returns the hyperbolic arc-sine of `x`.
> > `acosh(x)`
> >   Returns the hyperbolic arc-cosine of `x`.
> > `atanh(x)`
> >   Returns the hyperbolic arc-tangent of `x`.

> ### Various Mathematical Functions

> > Functions work on and return tuples of length 1 unless noted otherwise.

> > `sqrt(x)`
> >   Returns the square root of `x`. Only works on real numbers.
> > `exp(x)`
> >   Returns `e^x`. Works on real and complex numbers.
> > `log(x)`
> >   Returns the natural logarithm of `x`. Works on real and complex numbers.
> > `gamma(x)`
> >   Returns the value of the gamma function for `x`. Works on real and complex numbers.
> > `pmod(x,y)`
> >   Returns the modulo of `x` and `y` as a positive value, even if `x` is negative.
> > `sign(x)`
> >   Returns `-1` if `x < 0`, 0 if `x = 0` and `1` if `x > 0`. Works on two tuples of the same length.
> > `floor(x)`
> >   Returns the largest integer which is less or equal to `x`.
> > `min(x,y)`
> >   Returns x if `x < y`, `y` otherwise. Works on two tuples of the same arbitrary length.
> > `max(x,y)`
> >   Returns `x` if `x > y`, `y` otherwise. Works on two tuples of the same arbitrary length.
> > `clamp(x,l,u)`
> >   Clamps each element of `x` to be between the corresponding elements of `l` and `u` and returns the result. All three tuples must have the same tag and the same arbitrary length.
> > `lerp(t,a,b)`
> >   Returns `a*(1-t)+b*t`. `t` must have length 1. `a` and `b` must have the same tag and the same arbitrary length.
> > `scale(x,fl,fu,tl,tu)`
> >   Returns `((x-fl)/(fu-fl))*(tu-tl)`.
> > `inintv(a,x,y)`
> >   Returns `1` if `x <= a <= y`, `0` otherwise.

> ### Pseudo-Random Numbers

> > `rand(x,y)`
> >   Returns a random number `a` with `x <= a <= y`. Successive random numbers are evenly distributed within the interval.
> > `noise(coord)`
> >   Returns the value of a solid noise function at coordinate `coord`. `coord` must have length 3. The returned value is in the interval -1 to 1.

> ### Colors

> > Colors must have types `rgba:4` or `hsva:4`, depending on whether they are in the RGB or the HSV color space.

> > `red(p)`
> >   Returns the red component of `p`, which is `0 <= red(p) <= 1`.
> > `green(p)`
> >   Returns the green component of `p`, which is `0 <= green(p) <= 1`.
> > `blue(p)`
> >   Returns the blue component of `p`, which is `0 <= blue(p) <= 1`.
> > `alpha(p)`
> >   Returns the alpha component of `p`, which is `0 <= alpha(p) <= 1`.
> > `gray(p)`
> >   Returns the luminance of `p`, which is `0 <= gray(p) <= 1`.
> > `toRGBA(c)`
> >   Transforms the color `c` to RGBA. Returns an `rgba:4` tuple.
> > `toHSVA(c)`
> >   Transforms the color `c` to HSVA. Returns an `hsva:4` tuple.
> > `rgbColor(r,g,b)`
> >   Returns the `rgba` value of a pixel with red component `r`, green component `g`, blue component `b` and alpha component `1`. This function is provided for compatibility.
> > `rgbaColor(r,g,b,a)`
> >   Returns the `rgba` value of a pixel with red component `r`, green component `g`, blue component `b` and alpha component `a`. This function is provided for compatibility.
> > `grayColor(g)`
> >   Returns the `rgba` value of a pixel with luminance `g` and alpha component `1`.
> > `grayaColor(g,a)`
> >   Returns the `rgba` value of a pixel with luminance `g` and alpha component `a`.

> ### Input Images

> > `origVal(coord)`
> >   Returns the `rgba` value of the pixel at coordinate `coord`. `coord` may be of type `xy:2` or `ra:2`.
> > `origVal(coord,image)`
> >   Returns the `rgba` value of the pixel at coordinate `coord` in the image `image`. `coord` may be of type `xy:2` or `ra:2`. `image` must be of type `image:1` and must be a value returned by `user_image`.
> > `origValXY(x,y)`
> >   Returns the pixel value of the pixel at the cartesian position (`x`,`y`). This function is provided for compatibility.
> > `origValRA(r,a)`
> >   Returns the pixel value of the pixel at the polar position (`r`,`a`). This function is provided for compatibility.

## User Values

> User values are values within the expression which are specified through the graphical interface. Each user value must have a name. User values sometimes take arguments, like `user_float`, in this case to specify the range of allowed values.

> `user_float(name,minimum,maximum)`
> `user_slider(name,minimum,maximum)`
>   Returns a tuple of type `nil:1` corresponding to the chosen number in the range `minimum` to `maximum`.
> `user_int(name,minimum,maximum)`
>   Returns a tuple of type `nil:1` corresponding to the chosen integer in the range `minimum` to `maximum`.
> `user_bool(name)`
>   Returns the tuple `nil:[1]` or `nil:[0]` depending on whether the user has activated a push button.
> `user_color(name)`
>   Returns a tuple of type `rgba:4` corresponding to the color the user has chosen in a color well.
> `user_curve(name,x)`
>   Returns a tuple of type `nil:1` corresponding to the value of a curve at position `x`. The curve is defined in the interval `0` to `1`. Its values are in the same interval. If `x` is outside the interval, it is clamped.
> `user_gradient(name,x)`
>   Returns the value of a user-defined gradient at the value `x`. The gradient is defined in the interval `0` to `1`. Values outside this interval are clamped. The returned tuple is a color of type `rgba:4`. Note: In GIMP it's only possible to use at most one user gradient.
> `user_image(name)`
>   Returns a tuple of type `image:1` containing the ID of a user-selected image. The user may only select images having the same size as the input image.