# Complex Grapher Documentation

Complex Grapher is an online tool to visualize complex functions using domain coloring. This help guide assumes basic knowledge about how complex numbers and domain coloring work, Wikipedia links will be provided for further explanation.

Complex Grapher requires a browser that supports WebGL 3.0 or greater.

## The user interface

• Equation - Enter the function you want to graph here, in terms of `z`. See below for information about the syntax of expressions.
• Axis scale - Set the bounds of the real and imaginary axes. The first number in each pair is the left/bottom side of the canvas, the second number is the top/right side.
• Shading amount - Control how much black/white shading is applied to numbers close to 0 or ∞. Furthest left is no shading (however, values equal to 0 or ∞ will still be black and white, respectively).
• Swap black and white - Check this to instead use black for ∞ and white for 0.
• Draw contours - Draw rings at integer distances from the origin. The first ring (about the unit circle) is white, the rest are black.
• Smooth coloring - Use a smoother coloring method.
• Iteration This section allows you to iterate the function you put in above a set number of times (that is, call the function on its own output repeatedly). If iteration is enabled, you may also use the variables `c` and `n` in your function. `c` will remain constant throughout the iterations, and `n` represents the current iteration number (starting with 0).
• Iterations - How many times to iterate the function.
• z₀(z) - The initial value for `z`
• c(z) - The initial value for `c`
• Arg offset - use different branches of functions by changing where the branch cut of `arg(z)` is.
• DPI - Control the resolution of the canvas. "single" uses the browser's default, "double" uses twice that on both axes (resulting in 4 times as many pixels), "quadruple" uses four times that (16 times as many pixels). These links will save the graph as a URL parameter and reload the page.
• Graph - Self-explanatory.
• Generate link - Generate a link containing all of the equations and settings currently applied.

## Syntax

```level0 := level1 (("+" | "-") level1)*
level1 := level2 (("*" | "/") level2)*
level2 := (level3 "^")* level3
level3 := "(" level0 ")"
| "{" condition "}"
| name "(" (level0 ",")* level0 ")"
| name
| imag
| real
| "-" level1
condition := level0 ":" level0 "," condition
| level0
name := /[a-zA-Z_√Γπτγ]+/
real := number
imag := number "i"
number := ("+" | "-")? digits "." digits
| ("+" | "-")? digits "."
| ("+" | "-")? "." digits
| ("+" | "-")? digits
digits := /[0-9]+/
whitespace = /[ \t\n\r]*/
```

### Numbers

Real numbers can be written in standard base-10 form (ex. `37`, `-1045`, `33.26258`). Imaginary numbers can be written similarly, but followed by an `i` (ex. `3i`, `-25i`, `.37i`). `i` can also be used alone. Complex numbers can be expressed simply as the sum of a real and an imaginary number (ex. `3-5i`, `.7+52i`).

### Operators

The five basic operators are `+`, `-`, `*`, `/`, and `^` (exponentiation). These follow the normal order of operations, with `^` being right associative (so 2^3^4 = 2^(3^4), not (2^3)^4). Parentheses `( )` can be used for grouping.

### Variables and constants

In `f(z)`, the variables `z`, `c`, and `n` are available. `z` is the argument of the function, and `c` and `n` are used for iteration as described above. In `z₀(z)` and `c(z)`, the only variable available is `z`.

The constants `e`, `tau` or `τ`, `pi` or `π` (= τ/2), and `emg` or `γ` (the Euler–Mascheroni constant) are available

### Functions

Functions are written as the funciton name followed by the argument in parentheses. All functions only take one argument. Examples: `sin(z)`, `gamma(3+2i)`, `conj(1/z)`.

The following functions are available:

• `re` and `im` - the real or imaginary part of a complex number, respectively
• `abs` - absolute value (Euclidean distance from the origin)
• `arg` - the argument (angle about the origin in the range (-π,π])
• `norm` - the norm (equal to `abs(z)^2` and `re(z)^2 + im(z)^2`)
• `conj` - complex conjugate
• `sqrt` or `√` - square root (equal to `z^0.5`)
• `root` - nth root (first argument is radicand, second is index)
• `exp` - the exponential function (equal to `e^z`)
• `ln` - the natural logarithm
• `log` - logarith with base, where the base is the second argument (defaults to e)
• `recip` - reciprocal, equivalent to `1/z`
• `sin cos tan` - sine, cosine and tangent
• `asin acos atan` - inverse sine, cosine and tangent
• `sinh cosh tanh` - hyperbolic sine, cosine and tangent
• `asinh acosh atanh` - inverse hyperbolic sine, cosine and tangent
• `gamma` or `Γ` - the gamma function
• `unitcircle` - set abs(z) to 1, normalizing the complex number to the unit circle
• `signre` - the sign of the real part of z (1 if `re(z)`>0, -1 if `re(z)`<0, 0 if `re(z)`=0
• `signim` - the sign of the imaginary part of z (1 if `im(z)`>0, -1 if `im(z)`<0, 0 if `im(z)`=0
• `lambertw` - the Lambert W function

The following functions are currently experimental and may be changed or removed later:

### Conditionals

Conditionals (using curly braces `{ }`) can be used like if-statements to pick an expression from a list. They take the form `{condition1: expression1, condition2: expression2, expression3}`. The conditions are evaluated from left to right, once the first true one is reached the corresponding expression is evaluated. The final expression (with no condition) acts as a fallback if none of the previous conditions were true. A condition is true if the real part of the result is strictly positive.

Example: `{z-3: 2*z, z-2: z^2, 1/z}` will evaluate to `2*z` whenever `re(z)`>3 (`re(z-3)`>0), otherwise to `z^2` whenever `re(z)`>2, otherwise to `1/z`.

Conditionals are currently experimental and may be changed later.

## A word of caution

WebGL is very prone to crashing, especially when using iteration. Some operations, like addition and multiplication, are very fast and should not cause too many problems. Others, like `exp(z)` and `sinh(z)` are fairly fast since they are implemented directly in the hardware. But some functions, like `lambertw(z)` and `gamma(z)` are a lot slower due to their slow implementations. For the best performance, avoid mixing slow functunctions, high iteration counts, and high DPI settings together.