 • August 02, 2021, 09:07:21 AM

### Author Topic:  Complex functions implementation by 2 reals  (Read 158 times)

0 Members and 1 Guest are viewing this topic.

#### Alef ##### Complex functions implementation by 2 reals
« on: July 19, 2021, 02:07:08 PM »
This could be usefull for writing formulas. I found this usefull when I needed complex power 3 by 2 real variables. Wikipedia have some formulas but in more powers you 'll need to do algebra by yourself and that is quite cumbersome.

Quote
Formula Compiler tutorial
Introduction to the Fractal Explorer Formula Compiler
version 2.03.02
September 2004
Written by Sirotinsky Arthur, Olga Fedorenko
and Denis McCauley

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);

a catalisator / z=z*sinh(z)-c2

#### claude ##### Re: Complex functions implementation by 2 reals
« Reply #1 on: July 19, 2021, 02:23:06 PM »
for correct results, strongly suggest NOT adding a constant to avoid division by 0.  no constant will be small enough for deep zooms. instead check for 0 explicitly and/or normalize NaNs/infinities afterwards (e.g. with C99 cproj() function).  note: correct behaviour will probably will be slower

#### hobold ##### Re: Complex functions implementation by 2 reals
« Reply #2 on: July 19, 2021, 05:39:33 PM »
I am wondering in which cases (of 1/z) the addition of a tiny epsilon makes an actual difference. I mean when is the tiny constant not effectively rounded to zero, because the left value (sum of squares) is large enough that the right addend is underflowing during alignment?

Hmm, then again, the sum of squares itself could be tiny, and then the supposedly tiny constant may be larger ... destroying any information that was in the input numbers.

In other words, one would need to either add a much smaller constant, which in turn could still cause the division to overflow, or explicitly check the magnitude before deciding on a suitable value for a constant. In the latter case, one can check for zero in the first place and handle the problematic case separately.

Hmm yeah ... there seems to be no simple solution that is behaved better over a larger range of values.

#### Alef ##### Re: Complex functions implementation by 2 reals
« Reply #3 on: July 19, 2021, 07:59:05 PM »
I think it have to do with compiler and alsou initial values. I guess floating variable never can realy get value zero by calculation. But I don't have theoretical knowledge about this;) Alsou I had not done deep zooms, maybe with petrurbation it eventualy could introduce distortion. But it could help to owercome compilers error messages;)

In Chaos Pro programm shows messages like "Fractal (Z*Z+C) may be the result of arithmetic exceptions. The calculation function produced invalid results for at least 7 pixels." Most probably it generated infinities.

#### xenodreambuie

• Fractal Friar
• • Posts: 149 ##### Re: Complex functions implementation by 2 reals
« Reply #4 on: July 20, 2021, 06:23:23 AM »
I think the question of how to handle divide by zero depends on several factors, such as how deep you want to go and by what methods, what precision you are using, what is supported/convenient in your programming environment, and also what the users expect. Most users don't care how many pixels may have been technically NaN somewhere, they just want a nice picture.

In any case, adding a constant is not a good idea. There are other problems with those simple methods of invert and divide: intermediate precision loss due to overflow and underflow. With better methods you need to test anyway, so it costs little more to explicitly test for 0. Here is a method for invert to minimize precision loss, in Pascal.
Code: [Select]
function CInvert(const c1:TComplex):TComplex;var R,Denom: Extended;begin  if Abs(c1.x)>=Abs(c1.y) then begin    if c1.x<>0 then begin      R:= c1.y/c1.x;      Denom:= 1/(c1.x+R*c1.y);      Result.x:= Denom;      Result.y:= - R*Result.x;    end else begin      result.x:= 1e100; // or handle it in some other way      Result.y:= -1e100;    end;  end else begin    R:= c1.x/c1.y;    Denom:= -1/(c1.y+R*c1.x);    Result.y:= Denom;    Result.x:= -R*result.y;  end;end;If you're just using real x and y instead of a complex type, it's easily enough changed.
« Last Edit: July 20, 2021, 09:23:47 AM by xenodreambuie »

### Similar Topics ###### New Theory of Super-Real and Complex-Complex Numbers and Aleph-Null

Started by M8W on Fractal Mathematics And New Theories

2 Replies
723 Views January 06, 2018, 08:40:15 AM
by M8W ###### Baguabox formula implementation in M3D

Started by Alef on Mandelbulb3d

10 Replies
1024 Views November 20, 2018, 05:53:00 PM
by Alef ###### Coloring the Mandelbrot set with a perturbation implementation
5 Replies
752 Views April 02, 2018, 09:49:59 PM
by skychurch ###### BrowserSynth - a StructureSynth implementation that runs in a web browser

Started by kronpano on Fractal Image Gallery

2 Replies
283 Views July 24, 2020, 02:35:24 AM
by gerson ###### Actual Implementation of Perturbation Theory for the Mandelbrot Set

Started by LionHeart on Fractal Mathematics And New Theories

7 Replies
1176 Views November 08, 2020, 04:47:25 AM
by LionHeart