Formula Compiler tutorial  Formula Compiler tutorial  Formula Compiler tutorial Introduction to the Fractal Explorer Formula Compiler version 2.03 August 2001 Written by Sirotinsky Arthur, Olga Fedorenko http://www.eclectasy.com/Fractal-Explorer/index.html art@gor.kv.energy.gov.ua and Denis McCauley http://ata-tenui.ifrance.com/
 Table of content:

```  0     Changes
1     Acknowledgements
2     Limitations
3     Introduction
3.1   What is the formula compiler ?
3.2   Formula Files
4     Formula anatomy
4.1   Formula is a programme
4.2   Formula is a Delphi/Pascal programme
4.3   Requirements
4.4   Simple project
4.5   Temporary variables declaration
4.6   Difficult project
4.7   The complex functions
5     Complex variables functions
5.1   List of the functions and procedures
5.2   Functions selector
5.3   Changes in versions 2.01, 2.02 and 2.03
5.4   Examples of the new formulae

```
```

Changes:

Version 2.03 has no fundamental differences from version 2.02. The basic
achievement of this version is a  significant  speed  improvement. Also,
little bug fixed and added the two new functions: CConj and CConjV.
Besides the constant CPixel was added. This constant contains the source
complex value of the pixel which is currently calculated (i.e. Z0).

The version 2.03 is a further development of the compiler and contains
many new complex-variable functions.  There are now 30 such functions. But
the main innovation is that in the formulae two selectors of functions can
be used, operate with which it is possible from the "Select fractal" window.
So, now the formulae can be changed without compilation. In the following
version we shall try to optimise libraries and to increase speed of
calculations.

Version 2.01 of the formula compiler has few but very important changes.
First of all, now you do not need to write the difficult expressions for
formula realization. We have added support for many operations and functions
of complex values. Also, we added four complex variables for using in your
functions. In part number  we describe these new possibilities. Please,
read it before using the formula compiler.

FRMTUTOR.TXT
AN INTRODUCTION TO
THE FRACTINT FORMULA PARSER

Borland /Inprise/ Corp. for Delphi Command Line compiler

Limitations:

Our formula compiler is not a parser. It's part of the programme, which
calculates one step of the iteration process. It can't read formula directly,
since the complex type is non-standart type for Delphi.

Introduction:

3.1   What is the formula compiler ?

It is a new part of the fractal-generating programme, Fractal Explorer
(version 1.13 and greater).

FE has many different types of the fractal formulae itself, the formula
compiler allows you to add new fractals without having to change the programme.
These formulae are stored in fractal spot files, and may be viewed and
edited by anuther user.

3.2   Formula Files

New formulae will be not saved to another file. Formula will be stored as
fractal spot file (*.frs),  which  contain internal data for generating of the
image. Therefore, FE requires one FRS file for building one image (and the
formula is already implemented into the file).

Formula anatomy:

Why a compiler ?
Compiled programmes always work more quickly than interpreter.

However, don't be surprised that the formulae written by you work too
slowly. Please remember that the formulae that are built into the programme
are specially optimised for calculation speed. Unfortunately, such
optimisation is impossible for the formulae connected from the outside.
We continue to work with this problem and we hope to solve it in the future.
So, you can see, what each new version works quickly then previous.  :o)

4.1   Formula it's a program

Fractal Explorer uses a formula's text for building Dinamic Link Libraries
(DLL), and after that loads the new DLL (for interest - look to the system TEMP
folder: strings "SET TMP=" or "SET  TEMP=" in your c:\autoexec.bat).
When the formula changed (or FE closed) the DLL will be unloaded from memory
and deleted with the project source.

4.2   Formula it's a Delphi/Pascal program

To compile a new formula, FE will create the Delphi project file (*.DPR)
in the temporary folder and execute Borland Delphitm Command Line compiler
to generate the DLL file.

Since we are using Delphi for writing Fractal Explorer, we are using
Delphi for DLL compilation.

4.3   Requirements

To use the Formula Compiler in FE the files listed below are required:

dcc32    exe
math     dcu
sharemem dcu
sysinit  dcu
system   dcu
sysutils dcu
windows  dcu
sysutils inc
make     pif

All  files must exist in the Fractal Explorer folder. FE will be check for
the presence of these files before compiling the new formula. If you have

and unzip it into FE's folder.

4.4   Simple project
Complex numbers are two-part numbers: the first part is thr real part, and
thr second part is the imaginary part. The notation of complex numbers is:
Z = X + jY,
where "j" - imaginary part sign (square root from "-1"). Fractal Explorer uses
this format for complex numbers.

To illustrate a fractal formula take the Mandelbroth Set:
z_new = z * z  +  c

You write in the edit box:
~~~~~~~~~~~~Cut~~~~~~Cut~~~~~~~~~~~~
var k: Extended;
Begin
k:=(x+y) * (x-y) + cr;
y:=2 * x * y + ci;
x:=k;
End;
~~~~~~~~~~~~Cut~~~~~~Cut~~~~~~~~~~~~
"x" is the real part of "z" a complex number, and "y" the imaginary part.
"cr" is the real part of "c" complex number, and "ci" the imaginary part.
"z" is the value received in the "x" and "y" variables. New value of "z"
will be returned in these variables.

The variable "k" is used to store the new "x" values before calculating
new "y" values.

Press the "Compile" button and FE will make a Delphi project for
this formula:
~~~~~~~~~~~~Cut~~~~~~Cut~~~~~~~~~~~~

library proba;
Uses ShareMem, SysUtils, Math;
Procedure Formula(  var x, y, cr, ci: Extended;
const p1r, p1i, p2r, p2i, p3r, p3i, p4r, p4i: Extended;
var cA1, cA2, cA3, cA4: TComplex;
const CPixel: TComplex;
const Fn1, Fn2: Integer); export;
var k: Extended;
Begin
k:=(x+y) * (x-y) + cr;
y:=2 * x * y + ci;
x:=k;
End;
exports
Formula index 1 name 'Formula';
BEGIN
END.

~~~~~~~~~~~~Cut~~~~~~Cut~~~~~~~~~~~~

For Delphi and Pascal programmers these code are simple. Other peoples may be
interested only in Procedure Formula declaration:

Procedure Formula(  var x, y, cr, ci: Extended;
const p1r, p1i, p2r, p2i, p3r, p3i, p4r, p4i: Extended;
var cA1, cA2, cA3, cA4: TComplex;
const CPixel: TComplex;
const Fn1, Fn2: Integer); export;

Variables:
x, y     - mathematical coordinates of current point on every cycle;
cr,ci    - real and imaginary parts of Julia parameter (C);
p1r..p4i - real and imaginary parts of fractal parameters P1, P2, P3 and P4;
cA1..cA4 - zero-initialized variables available for use by you;
CPixel   - constant value, which contains the complex coordinates
of the current pixel;
Fn1, Fn2 - codes of the first and second functions.

You can modify values of cr and ci variales in your formulae.
There are lot of the good formulas used this feature. For example:
~~~~~~~~~~~~Cut~~~~~~Cut~~~~~~~~~~~~

var c1,c2: Extended;
Begin
c1:=x; c2:=y;
k:=(x+y) * (x-y) + cr;
y:=2 * x * y + ci;
x:=k;
cr:=c1; ci:=c2;
End;

~~~~~~~~~~~~Cut~~~~~~Cut~~~~~~~~~~~~

Values, received in p1r, p1i, .. , p4r, p4i parameters are real and
imaginary parts of the P1, P2, P3 and P4 parameters of the fractal (look to
the "Select formula" window). They are constant for your formula. You can't
modify values of these variables. But you can use cA1,..cA4 variables to
send the data from one iteration to another. This variabels available for
modifing and they are initialized to zero before each pixel calculation.

That's all, folks !

NOTE: do not write calculation cycle; Fractal Explorer does it itself!!!

4.5   Temporarly variable declaration

Separate your formula into small parts and use temporary variables
(remember, that it requires the "var" section). Sintax for a temporary
variable declaration:
var name1, name2, name3: [type]
Type may be "Single", "Double" or "Extended".

Difference:
type     | range                       | significant | size in
|                             | digits      | bytes
---------+-----------------------------+-------------+--------
Single   | 1.5x10^_45 .. 3.4x10^38     | 7_8         | 4
Double   | 5.0x10^_324 .. 1.7x10^308   | 15_16       | 8
Extended | 3.6x10^_4951 .. 1.1x10^4932 | 19_20       | 10

"Single" works quickly, but precision is lowest;
"Double" works much slowly, but precision is good;
"Extended" works very slowly, but precision is very good.
The "Double" type is used by default and we recommend it to you.

The special type for the complex numbers is declared in the Formula
Compiler:

TComplex = record
real: Extended;
imag: Extended;
end;

You can declare variables of this type in your formulae to store complex
numbers and use internal functions and procedures. By the way, variables
cA1, cA2, cA3 and cA4 has TComplex type too.

Examles:
var tmp1,tmp2: Double;
Begin
<>formula...<>
End;

var h1x,h1y: Double;
h2x,h2y: Double;
Begin
<>formula...<>
End;

var h1x,h1y: Double;
h2x,h2y: Double;
f: Extended;
c1,c2: TComplex;
Begin
<>formula...<>
c1:=c2;                   // -it is a totally right operation
<>formula...<>
End;

4.6   Difficult project
Mandel/Talis formula:

z_new = z*z + c;
c_new = c*c/(c+P1) + z_new;

Write in the edit area:
~~~~~~~~~~~~Cut~~~~~~Cut~~~~~~~~~~~~

var h1x,h1y, h2x,h2y, f: Extended;  // -temporary variables
Begin
h1x:=(x+y)*(x-y)+cr;                // -calculating z_new
y  := x*y*2     +ci;                //  z_new = z*z + c
x  := h1x;

h1x:= (cr+ci)*(cr-ci);              // -h1 = c*c
h1y:=  cr*ci * 2;

h2x:= cr+p1r;                       // -h2 = c+P1
h2y:= ci+p1i;

f  := h2x*h2x+h2y*h2y+1E-10;        // -c_new=h1/h2 + z_new
cr :=(h2x*h1x+h2y*h1y)/f+x;
ci :=(h2x*h1y-h2y*h1x)/f+y;
End;

~~~~~~~~~~~~Cut~~~~~~Cut~~~~~~~~~~~~
Calculate new values for "x" (real part) and "y" (imaginary part) of
complex variable "z".
Also, change cr and ci values - real and imaginary parts of "c".
Next step will use z_new and c_new.

4.7   The complex functions

You can use any function of the complex variables in your formula, but you
must describe them, like this (remember, that Z = X + jY  and C = CR + jCI):
z*z:
X_new := (X-Y)*(X+Y);
Y_new := 2 * X*Y;

z*c:
X_new := X*CR - Y*CI;
Y_new := X*CI + Y*CR;

z*z*z:
X_new := X*(X*X-3*Y*Y);                       // -this is optimized formula
Y_new := Y*(3*X*X-Y*Y);

z*z*z*z:
tmp_r := (X-Y)*(X+Y);
tmp_i := 2 * X*Y;
X_new := (tmp_r - tmp_i) * (tmp_r + tmp_i);
Y_new := 2 * tmp_r * tmp_i;

1/z:
tmp   := X*X + Y*Y + 1E-25;                   // -without 1E-25 may by
X_new := X / tmp;                             //  divizion by zero
Y_new :=-Y / tmp;

1/(z*z):
tmp   := X*X + Y*Y;
tmp   := tmp * tmp + 1E-25;                   // -see above
X_new := (X*X - Y*Y) / tmp;
Y_new := (2*X * Y  ) / tmp;

Sqrt(z):
tmp   := Sqrt(X*X + Y*Y);
X_new := Sqrt(Abs((X + tmp)/2));
Y_new := Sqrt(Abs((tmp - X)/2));

Exp(z):
tmp   := Exp(X);                              // e^z
X_new := tmp * Cos(Y);
Y_new := tmp * Sin(Y);

Exp(1/z):
tmp   := X*X + Y*Y + 1E-25;                   // -see above
s1    := X/tmp;
s2    :=-Y/tmp;
tmp   := Exp(s1);
X_new := tmp * Cos(s2);
Y_new := tmp * Sin(s2);

Ln(z):
X_new :=Log2(X*X+Y*Y)/2.7182818285;
Y_new :=ArcTan2(Y,X);

z^c:
h1x   :=Log2(X*X+Y*Y)/2.7182818285;           // -Ln(z)
h1y   :=ArcTan2(Y,X);
h2x   :=h1x*CR - h1y*CI;                      // -Ln(z)*c
h2y   :=h1y*CR + h1x*CI;
f     :=Exp(h2x);                             // -Exp(Ln(z)*c)
X_new :=f*Cos(h2y);
Y_new :=f*Sin(h2y);

Sin(z):
tmp   := Exp(Y)/2;                            // -optimized formula (!)
tmp2  := 0.25/tmp;
X_new := Sin(X) * (tmp+tmp2);
Y_new := Cos(X) * (tmp-tmp2);

Cos(z):
X_new := Cos(X)*Cosh(Y);                      // -not optimized formula
Y_new :=-Sin(X)*Sinh(Y);

Tan(z):
X_new := Sin(2*X)/(Cos(2*X)+Cosh(2*Y));
Y_new := Sin(2*Y)/(Cos(2*X)+Cosh(2*Y));

Sinh(z):                      // -hiperbolic sinus
X_new := Sinh(X)*Cos(Y);                      // -it is not optimized formula
Y_new := Cosh(X)*Sin(Y);

Cosh(z):                      // -hiperbolic cosinus
X_new := Cosh(X)*Cos(Y);                      // -it is not optimized formula
Y_new := Sinh(X)*Sin(Y);

You must change X, Y, CR and CI variables to those, which required by you
formula.

Functions of complex variables:

5.1   List of the functions and procedures

The special type for storing of the complex numbers was described above.
You need to remember this declaration:

Type
TComplex = record
real: Extended;
imag: Extended;
end;

All of the functions listed below will use this type for their operations.
It's a very important part of the new version Formula Compiler.

List of the functions and procedures

I. Function  MakeComplex(real, imag: Extended): TComplex;
This function makes a TComplex value from the two values,
which describe the real and imaginary parts of the
complex value. Use this function for translate the input values
(x,y, cr,ci and p1r..p4i) to the complex type. After
translation you can use result in another functions
and procedures.
Also, you can use this function to make a TComplex value
from a constant, for example:

tmp:=MakeComplex(3,0) - convert the real number "3" into
TComplex type.

II. Procedure SetResult(var x,y: Extended; const complex: TComplex);
This procedure makes final results accessible for the
Formula Compiler. As described in the part [4.4], the result
values must be returned in the "X" and "Y" variables.
You can use two operations for it:
x:=Z.real;
y:=Z.imag;
but now you can use the SetResult procedure for this.

Note: remember, what the SetResult procedure works
little bit slowly then direct storing the data.

Below are listed functions and procedures for mathematical operations.
Every operation has two releases: first, as a procedure with no result
returned, and second, as a function, which returns the result of the
operation as a TComplex value.  Any procedure keeps the resulting complex
value in the variable which passed as the first parameter.

III. Sum of the two complex:
Procedure CAddV(var Cmp1: TComplex; const Cmp2: TComplex);
Cmp1 := Cmp1 + Cmp2;
Result value will be returned in the "Cmp1" variable.

Function  CAdd (const Cmp1, Cmp2: TComplex): TComplex;
Cmp3 := Cmp1 + Cmp2;
Result value will be returned as a result of the function.

Function  CAddR (const Cmp1: TComplex; t: Extended): TComplex;
Cmp2 := Cmp1 + t
Added real value "t" to the "Cmp1" complex.

IV. Subtraction of the two complex:
Procedure CSubV(var Cmp1: TComplex; const Cmp2: TComplex);
Cmp1 := Cmp1 - Cmp2;

Function  CSub (const Cmp1, Cmp2: TComplex): TComplex;
Cmp3 := Cmp1 - Cmp2;

Function  CSubR (const Cmp1: TComplex; t: Extended): TComplex;
Cmp2 := Cmp1 - t;

V. Multiplication of the two complex:
Procedure CMulV(var Cmp1: TComplex; const Cmp2: TComplex);
Cmp1 := Cmp1 * Cmp2;

Function  CMul (const Cmp1, Cmp2: TComplex): TComplex;
Cmp3 := Cmp1 * Cmp2;

Function  CMulR (const Cmp1: TComplex; t: Extended): TComplex;
Cmp2 := Cmp1 * t;
(Cmp2.real = Cmp1.real*t
Cmp2.imag = Cmp1.real*t)

VI. Division of the two complex:
Procedure CDivV(var Cmp1: TComplex; const Cmp2: TComplex);
Cmp1 := Cmp1 / Cmp2;

Function  CDiv (const Cmp1, Cmp2: TComplex): TComplex;
Cmp3 := Cmp1 / Cmp2;

Function  CDivR (const Cmp1: TComplex; t: Extended): TComplex;
Cmp2 := Cmp1 / t;
(Cmp2.real = Cmp1.real/t
Cmp2.imag = Cmp1.real/t)

The next set of functions realizes the optimized functions

VII. Square of the complex:
Procedure CSqrV(var Cmp1: TComplex);
Cmp1 := Cmp1^2;

Function  CSqr (Cmp1: TComplex): TComplex;
Cmp2 := Cmp1^2;

VIII. Third power of the complex:
Procedure CTripleV(var Cmp1: TComplex);
Cmp1 := Cmp1^3;

Function  CTriple (Cmp1: TComplex): TComplex;
Cmp2 := Cmp1^3;

IX. Fourth power of the complex:
Procedure CFourV(var Cmp1: TComplex);
Cmp1 := Cmp1^4;

Function  CFour (Cmp1: TComplex): TComplex;
Cmp2 := Cmp1^4;

X. Flip of the complex:
Procedure CFlipV(var Cmp1: TComplex);
Cmp1.real := Cmp1.imag;
Cmp1.imag := Cmp1.real;

Function  CFlip (Cmp1: TComplex): TComplex;
Cmp2.real := Cmp1.imag;
Cmp2.imag := Cmp1.real;

XI. Reversing of the complex value:
Procedure CRevV (var Cmp1: TComplex);
Cmp1 := 1/ Cmp1;

Function  CRev  (const Cmp1: TComplex): TComplex;
Cmp2 := 1/ Cmp1;

XII. Another reversing:
Procedure CRev2V(var Cmp1: TComplex; Cmp2: TComplex);
Cmp1 := 1 / (Cmp1 - Cmp2);

Function  CRev2 (Cmp1,Cmp2: TComplex): TComplex;
Cmp3 := 1 / (Cmp1 - Cmp2);

XIII. Absolute value of complex:
Procedure CAbsV(var Cmp1: TComplex);
Cmp1.real := Abs(Cmp1.real);
Cmp1.imag := Cmp1.imag;
Function  CAbs (Cmp1: TComplex): TComplex;
Cmp2.real := Abs(Cmp1.real);
Cmp2.imag := Cmp1.Imag;

Procedure CAbs2V(var Cmp1: TComplex);
Cmp1.real := Abs(Cmp1.real);
Cmp1.imag := Abs(Cmp1.imag);
Function  CAbs2 (Cmp1: TComplex): TComplex;
Cmp2.real := Abs(Cmp1.real);
Cmp2.imag := Abs(Cmp1.Imag);

XIV. Real or imag part of complex:
Procedure CRealV(var Cmp1: TComplex);
Cmp1.real := Cmp1.real;
Cmp1.imag := 0;
Function  CReal (Cmp1: TComplex): TComplex;
Cmp2.real := Cmp1.real;
Cmp2.imag := 0;

Procedure CImagV(var Cmp1: TComplex);
Cmp1.real := Cmp1.imag;
Cmp1.imag := 0;
Function  CImag (Cmp1: TComplex): TComplex;
Cmp2.real := Cmp1.imag;
Cmp2.imag := 0;

XV. Squre root of the complex:
Procedure CSqrtV(var Cmp1: TComplex);
Cmp1 := Sqrt(Cmp1);

Function  CSqrt (Cmp1: TComplex): TComplex;
Cmp2 := Sqrt(Cmp1);

XVI. Exponent of the complex:
Procedure CExpV (var Cmp1: TComplex);
Cmp1 := Exp(Cmp1);

Function  CExp  (Cmp1: TComplex): TComplex;
Cmp2 := Exp(Cmp1);

XVII. Logorithm of the complex:
Procedure CLnV  (var Cmp1: TComplex);
Cmp1 := Ln(Cmp1);

Function  CLn   (Cmp1: TComplex): TComplex;
Cmp2 := Ln(Cmp1);

XVIII. Raise complex to a real power
Procedure CPowerRV(var Cmp1: TComplex; t: Extended);
Cmp1 := Cmp1^t;

Function  CPowerR (const Cmp1:TComplex;t: Extended): TComplex;
Cmp2 := Cmp1^t;

XIX. Raise complex value to a complex power:
Procedure CPowerV(var Cmp1: TComplex; Cmp2: TComplex);
Cmp1 := Cmp1^Cmp2;

Function  CPower (Cmp1,Cmp2: TComplex): TComplex;
Cmp3 := Cmp1^Cmp2;

Trigonometric functions

XX. Sinus of the complex:
Procedure CSinV (var Cmp1: TComplex);
Cmp1 := Sin(Cmp1);

Function  CSin  (Cmp1: TComplex): TComplex;
Cmp2 := Sin(Cmp1);

XXI. Cosinus of the complex:
Procedure CCosV (var Cmp1: TComplex);
Cmp1 := Cos(Cmp1);

Function  CCos  (Cmp1: TComplex): TComplex;
Cmp2 := Cos(Cmp1);

XXII. Tangent of the complex:
Procedure CTanV (var Cmp1: TComplex);
Cmp1 := Tan(Cmp1);

Function  CTan  (Cmp1: TComplex): TComplex;
Cmp2 := Tan(Cmp1);

XXIII. Cotangent of the complex:
Procedure CCotanV (var Cmp1: TComplex);
Cmp1 := Cotan(Cmp1);

Function  CCotan  (Cmp1: TComplex): TComplex;
Cmp2 := Cotan(Cmp1);

XXIV. Hiperbolic sinus of the complex:
Procedure CSinhV(var Cmp1: TComplex);
Cmp1 := Sinh(Cmp1);

Function  CSinh (Cmp1: TComplex): TComplex;
Cmp2 := Sinh(Cmp1);

XXV. Hiperbolic cosinus of the complex:
Procedure CConhV(var Cmp1: TComplex);
Cmp1 := Cosh(Cmp1);

Function  CCosh (Cmp1: TComplex): TComplex;
Cmp2 := Cosh(Cmp1);

XXVI. ArcSinus of the complex:
Procedure CASinV (var Cmp1: TComplex);
Cmp1 := ArcSin(Cmp1);

Function  CASin  (const Cmp1: TComplex): TComplex;
Cmp2 := ArcSin(Cmp1);

XXVII. ArcCosinus of the complex:
Procedure CACosV (var Cmp1: TComplex);
Cmp1 := ArcCos(Cmp1);

Function  CACos  (const Cmp1: TComplex): TComplex;
Cmp2 := ArcCos(Cmp1);

XXVIII. ArcTangens of the complex:
Procedure CATanV (var Cmp1: TComplex);
Cmp1 := ArcTan(Cmp1);

Function  CATan  (const Cmp1: TComplex): TComplex;
Cmp2 := ArcTan(Cmp1);

XXIX. Gyperbolic arcsinus of the complex:
Procedure CASinhV (var Cmp1: TComplex);
Cmp1 := ArcSinh(Cmp1);

Function  CASinh  (const Cmp1: TComplex): TComplex;
Cmp2 := ArcSinh(Cmp1);

XXX. Hyperbolic arccosinus of the complex:
Procedure CACoshV (var Cmp1: TComplex);
Cmp1 := ArcCosh(Cmp1);

Function  CACosh  (const Cmp1: TComplex): TComplex;
Cmp2 := ArcCosh(Cmp1);

XXXI. Hyperbolic arctangent of the complex:
Procedure CATanhV (var Cmp1: TComplex);
Cmp1 := ArcTanh(Cmp1);

Function  CATanh  (const Cmp1: TComplex): TComplex;
Cmp2 := ArcTanh(Cmp1);

XXXII.  Changes sign of imaginary part of the complex value
Result.real := Cmp1.real;
Result.imag :=-Cmp1.imag;
Procedure CConjV (var Cmp1: TComplex);
Function  CConj  (const Cmp1: TComplex): TComplex;

5.2   Functions selector

From the "Select fractal" window two functions can be changed.
Such changes will not require compilation of the formula. You can use
in your formula one or two functions and change the fractal directly from
the "Select fractal" dialogue.

To support external functions selections the procedure FuncDisp is implemented:
Procedure FuncDisp(const Fn: Integer; var Cmp1: TComplex);

In this procedure - Fn parameter is Fn1 or Fn2 variables,
which is passed to formulae from the outside. For example, write in your
formula:
FuncDisp(Fn1, Z);
and you can change the first function to get changes in the formula.

Examples of the Mandelbrot-set with functions selections:

var Z,Z0: TComplex;
Begin
Z :=MakeComplex(x,y);          // make complex from [x] and [y] variables
Z0:=MakeComplex(cr,ci);        // make complex from [cr] and [ci] variables

FuncDisp(Fn1, Z);              // change source value of the Z variable
Z :=CAdd( CSqr(Z), Z0);        // calculate the Mandel

SetResult(x,y, Z);             // store result to [x] and [y] variables
End;

Changes in versions 2.01 and 2.02
[+] added function selection support (look at [5.2] for details and example);
[+] errors in some functions fixed;
[+] added new procedures and functions:
Procedure CAddR(Cmp1: TComplex; t: Extended): TComplex;
Function  CSubR(Cmp1: TComplex; t: Extended): TComplex;
Procedure CMulR(Cmp1: TComplex; t: Extended): TComplex;
Function  CDivR(Cmp1: TComplex; t: Extended): TComplex;

Procedure CPowerRV(var Cmp1: TComplex; t: Extended);
Function  CPowerR (Cmp1: TComplex; t: Extended): TComplex;

Procedure CCotanV(  var Cmp1: TComplex);
Function  CCotan (const Cmp1: TComplex): TComplex;

Procedure CASinV (  var Cmp1: TComplex);
Function  CASin  (const Cmp1: TComplex): TComplex;
Procedure CACosV (  var Cmp1: TComplex);
Function  CACos  (const Cmp1: TComplex): TComplex;
Procedure CATanV (  var Cmp1: TComplex);
Function  CATan  (const Cmp1: TComplex): TComplex;

Procedure CASinhV(  var Cmp1: TComplex);
Function  CASinh (const Cmp1: TComplex): TComplex;
Procedure CACoshV(  var Cmp1: TComplex);
Function  CACosh (const Cmp1: TComplex): TComplex;
Procedure CATanhV(  var Cmp1: TComplex);
Function  CATanh (const Cmp1: TComplex): TComplex;

new declaration of the main procedure listed below:

Procedure Formula(var x, y, cr, ci: Extended;
const p1r, p1i, p2r, p2i, p3r, p3i: Extended;
var cA1, cA2, cA3, cA4: TComplex;
const Fn1, Fn2: Integer); export;
This variables are initialised to zero values, i.e. cA1.real = 0 and
cA1.imag = 0 and so on. During calculation of the one point these
variables will keep user values.

[!] now N(ewton)-Set Method will work properly;

Changes in version 2.03

[+] speed improvements;
[+] little bug fixes;
[+] added the new CPixel constant and P4 parameter:

Procedure Formula(var x, y, cr, ci: Extended;
const p1r, p1i, p2r, p2i, p3r, p3i, p4r, p4i: Extended;
var cA1, cA2, cA3, cA4: TComplex;
const CPixel: TComplex;
const Fn1, Fn2: Integer); export;

[+] added new procedure and function:

Procedure CConjV(Cmp1: TComplex);
Function  CConj(Cmp1: TComplex): TComplex;

5.4   Examples of the new formulae
I. Mandelbrot furmula:
~~~~~~~~~~~~Cut~~~~~~Cut~~~~~~~~~~~~

var Z,Z0: TComplex;
Begin
Z :=MakeComplex(x,y);          // make complex from [x] and [y] variables
Z0:=MakeComplex(cr,ci);        // make complex from [cr] and [ci] variables

Z :=CAdd( CSqr(Z), Z0);        // calculate the Mandel

SetResult(x,y, Z);             // store result to [x] and [y] variables
End;

~~~~~~~~~~~~Cut~~~~~~Cut~~~~~~~~~~~~

II. Mandel/Talis formula:
z_new = z*z + c;
c_new = c*c/(c+P1) + z_new;

Write:
~~~~~~~~~~~~Cut~~~~~~Cut~~~~~~~~~~~~

var Z,Z0,P1: TComplex;
Begin
Z :=MakeComplex(x,y);          // make complex from [x] and [y] variables
Z0:=MakeComplex(cr,ci);        // make complex from [cr] and [ci] variables
P1:=MakeComplex(p1r,p1i);      // make complex from [p1r] and [p1i] variables

Z :=CAdd( CSqr(Z), Z0);        // calculates Z_NEW

Z0:=CDiv(CSqr(Z0), CAdd(Z0,P1))   // Z' = C*C/(C+P1)
SetResult(cr,ci, Z0);          // store C_NEW to [cr] and [ci] variables
SetResult(x,y, Z);             // store Z_NEW to [x] and [y] variables
End;

~~~~~~~~~~~~Cut~~~~~~Cut~~~~~~~~~~~~

Others, more difficult examples can be found in the FE.ZIP archive.
They're placed into the "Formulas" subfolder.

```