MbLan is the app's embedded expression language used for defining custom fractal types and paint modes.
For a simple fractal type or paint mode definition, you use only MbLan expressions. If you have any experience with programming, or even with spreadsheet formulas, you should find it easy.
For an advanced definition you use MbLan programs.
The MbLan syntax is based on C/Java.
Do not forget to end each instruction with a semicolon ;
In addition to C/Java syntax, the MbLan introduces some extensions making it easier to enter formulas using an Android keyboard.
The MbLan compiler is powered by JavaCC. Those who are really interested may take a look at MbLan syntax definition file: mblan.jj.
The MbLan uses the following data types:
int  integer number (standard C/Java int) 
double  floatingpoint number (standard C/Java double) 
complex  a complex number using doubles for the real and imaginary part 
You may refer to real and imaginary parts of a complex variable z
or a complex expression as follows:
real part 
z.x 
(z + c).x 
imaginary part 
z.y 
(z + c).y 
You may construct complex values using complex function or complex literals as in the following examples:
complex(z.x  1, z.y + 1)
complex(1, 0)
1.2 + 2.3e2i
5i
You may declare helper variables at the very beginning of the Initialization code section of an advanced custom fractal type or paint mode definition. Follow the example below:
double sum, tmp4me;
int count;
complex a, a_c;
int k;
Helper variables are by default initialized to 0.
Because of the shortcut power syntax extension, variable names must not end with a digit.
You may use the following C/Java based syntax:
Arithmetic operators:
The MbLan supports arithmetic operations on complex or mixedtype arguments (except for % operator). The implicit type conversion from int to double and from double to complex is also supported. For explicit type conversion see the function reference. Integer division by zero will give the result of 0 instead of crashing the app. 
Comparison operators:
The result of comparison is int value 0 (false) or 1 (true). When comparing complex numbers the result is 1 if both parts fulfill the condition.
No support for chaining like 
Logical operators:
Logical operators take int arguments (0 means false, nonzero value means true) and give int result of 0 or 1. 
Unary arithmetic negation:

Unary logical negation:

Conditional expression:

Function call:

Comments:

The MbLan introduces the following syntax extensions to make formulas more readable and easier to type on a mobile device.
You may express multiplication by writing arguments with no *
operator between.
You may even write no space between arguments (of course not if both are variables).
Warning: implicit multiplication binds stronger than explicit one (see the last example below). More details in Operators precedence section.
example use  equivalent to 
a b c 
a * b * c 
3.5zc 
3.5 * zc 
2z + z2 
2 * z + z^2 
2z + 2(z  c) 
2 * z + 2 * (z  c) 
(k + 1)(z  2) 
(k + 1) * (z  2) 
z (2) 
z * 2 
a b / c d 
(a * b) / (c * d) 
Warning: exponentiation binds stronger than implicit multiplication (see the last example below). More details in Operators precedence section.
example use  equivalent to 
z^3 
pow(z, 3) 
c^0.7 
pow(c, 0.7) 
(a + b)^3^(k + 1) 
pow(a + b, pow(3, k + 1)) 
z^2c 
pow(z, 2) * c 
You may express exponentiation by following a base (variable only) with an exponent (positive integer literal only) with no space between. Typing ^ on a mobile device is not so easy.
This is the reason that variable names must not end with a digit.
example use  equivalent to 
z2 
pow(z, 2) 
a4 
pow(a, 4) 
z 4 
z * 4 
z2 
z  2 
(z + 1)5 
(z + 1) * 5 
You may call unary functions without using parenthesis. This can be especially useful for chaining function calls like writing:
abs log rad z
instead of:
abs(log(rad(z)))
Warning: unary function call binds stronger than any other operation but shortcut power (see examples below). More details in Operators precedence section.
example use  equivalent to 
abs z 
abs(z) 
abs sin z^2 
(abs(sin(z)))^2 
sin(z)^2 
(sin(z))^2 
log abs x y 
log(abs(x)) * y 
sin z.x 
(sin(z)).x 
sin 2z cos z2 
sin(2) * z * cos(z^2) 
The MbLan operators precedence in descending order (just like in C or Java plus MbLan extensions).
shortcut power  z2 
unary function call  sin z 
complex postfix  z.x z.y z.re z.im 
exponentiation  ^ 
implicit multiplication  2z 
unary operators   ! 
multiplicative operators  * / % 
additive operators  +  
relational operators  < <= => > 
comparison operators  == != 
logical AND  && 
logical OR   
conditional expression  ? : 
The operators associativity is like in C or Java. Exponentiation operator ^
binds righttoleft.
In case of any doubts, you may use parenthesis.
An MbLan program is a sequence of instructions. Each instruction must be followed by a semicolon ;
You may also use instruction blocks { }
like in C or Java.
The list of available instructions is quite short:
assignment

iteration break

conditional instruction

The following example is iteration code for a hybrid Mandelbrot / Burning ship fractal with a custom escape condition:
if (abs(z.x) >= bailout) break;
if (n % 2) {
/* two steps of Burning ship without adding c */
z = (abs z)^2;
z = (abs z)^2;
}
else
/* one step of Mandelbrot */
z = z2 + c;
The result of the above example using Stings paint mode (no smoothing defined).
You may use the builtin variables listed below. Any change of value affects only the calculation for the current point.
c 
complex the current point readonly 
z 
complex the current orbit element value readonly in a paint mode definition 
limit 
int the iteration limit readonly accessible in a fractal definition the value may vary between points when using the Detail level control as the app may adjust the iteration limit while rendering the image 
i 
int the current orbit element index readonly accessible in iteration code of a paint mode or a paint mode formula 
n 
int the last computed orbit element number in the fractal iteration code section the orbit length in a paint mode definition or in the fractal finalize code section can be written only in fractal finalize code 
smooth 
double the value of the smooth factor can be written only in the finalize code section of an advanced fractal definition always equal 1 when computing a custom paint mode for the fractal interior 
exponent 
double the value of the exponent used for smoothing when using the DIVERGENCE escape accessible only in fractal definition 
bailout 
double the value of bailout used for the DIVERGENCE escape or the CONVERGENCE escape accessible only in fractal definition 
value 
double the paint value to be mapped to the color from the palette accessible only in the iteration and the finalize code sections of an advanced paint mode definition 
start 
int the index of starting element for orbit processing when computing a paint value (see Orbit based coloring section) accessible only in a paint mode definition can be written only in the initialization code section 
pi 
double readonly Pi value 
e 
double readonly natural logarithm base 
You may refer to the orbit elements indexing builtin z
variable like an array.
Follow the examples listed below.
z[0] 
the first element 
z[expr] 
an arbitrary element where expr is an int expression 
z[n] 
the previous element in a fractal formula or iteration code
where this is equivalent to 
z[n  1] 
the element preceding a previous one in fractal formula or iteration code the last element in a paint mode definition or fractal finalize code 
z[i] 
the current element in a paint mode definition where
this is equivalent to 
z[i  1] 
a previous element in a paint mode definition 
You do not need to worry about exceeding the orbit range. You will just get 0 value in such a case (even if you use a negative index).
The following sections describe all the functions available in the MbLan with their supported arguments data types and the result data type.
The MbLan supports implicit data type conversion so you may pass an int instead of a double or a double instead of a complex.
Most of the functions work like their C/Java equivalents so they are not explained in detail.
WARNING: Due to RenderScript limitations, exponentiation, logarithm and trigonometric functions work on singleprecision floatingpoint numbers. This may cause image quality loss at a zoom of about 1e+5 or greater.
int 
int(double) : int type conversion 
double 
double(int) : double type conversion 
complex 
complex(double, double) : complex complex(x, y) = x + i y 
round 
round(double) : double 
floor 
floor(double) : double 
ceil 
ceil(double) : double 
abs 
abs(int) : int abs(double) : double abs(x) = x 
sgn 
sgn(int) : int sgn(double) : double sgn(x) = (x == 0 ? 0 : (x > 0 ? 1 : 1)) 
min 
min(int, int) : int min(double, double) : double 
max 
max(int, int) : int max(double, double) : double 
undef 
undef(double) : int undef(complex) : int returns 1 if an argument is undefined (NaN or infinity) and 0 otherwise for complex argument returns 1 if any of parts is undefined 
abs 
abs(complex) : complex abs(x + i y) = x + i y 
rabs 
rabs(complex) : complex rabs(x + i y) = x + i y 
iabs 
iabs(complex) : complex rabs(x + i y) = x + i y 
rad 
rad(complex) : double rad(z) = z = sqrt(z.x^2 + z.y^2) 
rad2 
rad2(complex) : double rad2(z) = z^2 = z.x^2 + z.y^2 
arg 
arg(complex) : double complex number argument (value in the range of (pi, pi]) 
conj 
conj(complex) : complex conj(x + i y) = x  i y 
flip 
flip(complex) : complex flip(x + i y) = x + i y 
swap 
swap(complex) : complex swap(x + i y) = y + i x 
dot 
dot(complex, complex) : double dot(a, b) = a.x b.x + a.y b.y 
min 
min(complex, complex) : complex min(a, b) = min(a.x, b.x) + i min(a.y, b.y) 
max 
max(complex, complex) : complex max(a, b) = max(a.x, b.x) + i max(a.y, b.y) 
sqr 
sqr(int) : int sqr(double) : double sqr(complex) : complex sqr(x) = x^2 
sqrt 
sqrt(double) : double sqrt(complex) : complex square root, sqr(x) = x^0.5 
pow 
pow(double, int) : double pow(double, double) : double pow(complex, int) : complex pow(complex, double) : complex pow(complex, complex) : complex 
log 
log(double) : double log(complex) : complex natural logarithm 
exp 
exp(double) : double exp(complex) : complex exp(x) = e^x 
sin 
sin(double) : double sin(complex) : complex 
cos 
cos(double) : double cos(complex) : complex 
tan 
tan(double) : double tan(complex) : complex 
sinh 
sinh(double) : double sinh(complex) : complex 
cosh 
cosh(double) : double cosh(complex) : complex 
tanh 
tanh(double) : double tanh(complex) : complex 
asin 
asin(double) : double 
acos 
acos(double) : double 
asin 
asin(double) : double 
atan 
atan(double) : double 
asinh 
asinh(double) : double 
acosh 
acosh(double) : double 
atanh 
atanh(double) : double 
lyapstep 
lyapstep(AB_sequence, complex, complex) : complex 
The special lyapstep function is a shortcut for computing Lyapunov fractals.
Its first argument should be a sequence of A and B characters, eg.:
lyapstep(AAABB, z, c)
The following pseudocode describes how the function works.
lyapstep(seq, z, c) {
double r;
if (seq[n % len(seq)] == 'B')
r = c.y;
else
r = c.x;
double a = abs(r * (1  2 * z.x));
z.y = (a > 0 ? log(a) : 0);
z.x = r * z.x * (1  z.x);
return z;
}
An example of use can be found in builtin Lyapunov fractals definitions.
You may get undefined (NaN or infinity) variable values (eg. as a result of double division by zero or computing a square root for a negative argument). In such a case the computing will not crash but you may get further undefined values.
When an orbit element value is undefined the escape condition will never be met and iteration will continue until iteration count limit is reached.
If a paint value is undefined it is skipped by a builtin aggregation. When using CUSTOM aggregation, a final paint value is changed to zero if it is undefined.
Warning: for simplicity, handling undefined values is not shown in a visible fixed program part of an advanced paint mode definition.
You may handle undefined values by yourself using the builtin undef
function.
The MbLan compiler does not perform any code optimization. You may do it yourself by using helper variables for common intermediate results. Do not expect too much unless you have really big common expressions in your fractal definition.
Let's consider the following iteration code of root finding fractal:
z = z  (z4 + z3  1) / (4z3 + 3z2);
It will compute a little bit faster if you rewrite it like this:
zb = z2;
zc = zb z;
z = z  (zb2 + zc  1) / (3zc + 3zb);
You may also use initialization code to compute intermediate values that do not depend on previous orbit value. This may give noticeable effects if there are many such calculations. An example may be found in the builtin Magnet 2 fractal definition.