• April 18, 2021, 01:47:37 AM

### Author Topic: (Question) How to Generate a Derivative Slope for Mandelbar (Tricorn)  (Read 399 times)

0 Members and 1 Guest are viewing this topic.

#### LionHeart

• Posts: 164
##### (Question)How to Generate a Derivative Slope for Mandelbar (Tricorn)
« on: January 05, 2021, 06:14:39 AM »
I have been able to successfully create a Mandelbar (tricorn) fractal and implement slope using forward differencing:

However, when I try to create a slope using derivatives, I don't get the correct image

Here is the code:

Code: [Select]
     case 13: //  z1 = conj(z)); z = z1*z1+c; [Tricorn or Mandelbar] Complex temp; temp = Z; temp.y = -temp.y; // get conjugate dC = dC * (temp + temp) + 1.0; sqr.x = temp.x * temp.x; sqr.y = temp.y * temp.y; real_imag = temp.x * temp.y; Z.x = Q.x + sqr.x - sqr.y; Z.y = Q.y + real_imag + real_imag; break;
Here is the code for standard Mandelbrot and it works:

Code: [Select]
     case 0: //  z = z*z+c; Mandelbrot dC = dC * (Z + Z) + 1.0; sqr.x = Z.x * Z.x; sqr.y = Z.y * Z.y; real_imag = Z.x * Z.y; Z.x = Q.x + sqr.x - sqr.y; Z.y = Q.y + real_imag + real_imag; break;
Can anyone see what I'm doing wrong in calculating the derivative? Is there some special trick needed to get the derivative of a complex conjugate?

Any help greatly appreciated. Thanks.

Paul the LionHeart

#### pauldelbrot

• 3f
• Posts: 2698
##### Re: How to Generate a Derivative Slope for Mandelbar (Tricorn)
« Reply #1 on: January 05, 2021, 07:02:46 AM »
There is no complex-analytic derivative for zed-bar. But at least it doesn't have a "corner" like absolute value does, which gets replicated everywhere when things are iterated until it's nowhere smooth. It should be possible to do something with the Jacobian matrix, treating it as a system of two real variables.

#### LionHeart

• Posts: 164
##### Re: How to Generate a Derivative Slope for Mandelbar (Tricorn)
« Reply #2 on: January 05, 2021, 10:27:29 AM »
Hi pauldelbrot
Thanks for replying. Please elaborate on "Jacobian matrix, treating it as a system of two real variables". This is way beyond my understanding at this time.
Many thanks.

#### pauldelbrot

• 3f
• Posts: 2698
##### Re: How to Generate a Derivative Slope for Mandelbar (Tricorn)
« Reply #3 on: January 05, 2021, 11:54:54 AM »
Hi pauldelbrot
Thanks for replying. Please elaborate on "Jacobian matrix, treating it as a system of two real variables". This is way beyond my understanding at this time.
Many thanks.

A real analysis textbook (perhaps there's one at Wikibooks) could probably explain it better than I can.

#### LionHeart

• Posts: 164
##### Re: How to Generate a Derivative Slope for Mandelbar (Tricorn)
« Reply #4 on: January 05, 2021, 12:05:47 PM »
Thanks pauldelbrot,
I have been researching it and have a steep learning curve ahead of me. But at least I have a way forward. Let's see what I can come up with

#### FractalAlex

• Fractal Frankfurter
• Posts: 539
• Experienced root-finding method expert
##### Re: How to Generate a Derivative Slope for Mandelbar (Tricorn)
« Reply #5 on: January 05, 2021, 02:00:31 PM »
I have been able to successfully create a Mandelbar (tricorn) fractal and implement slope using forward differencing:

However, when I try to create a slope using derivatives, I don't get the correct image

Here is the code:

Code: [Select]
     case 13: //  z1 = conj(z)); z = z1*z1+c; [Tricorn or Mandelbar] Complex temp; temp = Z; temp.y = -temp.y; // get conjugate dC = dC * (temp + temp) + 1.0; sqr.x = temp.x * temp.x; sqr.y = temp.y * temp.y; real_imag = temp.x * temp.y; Z.x = Q.x + sqr.x - sqr.y; Z.y = Q.y + real_imag + real_imag; break;
Here is the code for standard Mandelbrot and it works:

Code: [Select]
     case 0: //  z = z*z+c; Mandelbrot dC = dC * (Z + Z) + 1.0; sqr.x = Z.x * Z.x; sqr.y = Z.y * Z.y; real_imag = Z.x * Z.y; Z.x = Q.x + sqr.x - sqr.y; Z.y = Q.y + real_imag + real_imag; break;
Can anyone see what I'm doing wrong in calculating the derivative? Is there some special trick needed to get the derivative of a complex conjugate?

Any help greatly appreciated. Thanks.

At least the second image generates some very nice coloring patterns!
"quotquotI am lightning, the rain transformed."quotquot
- Raiden, Metal Gear Solid 4: Guns of the Patriots

#### claude

• 3f
• Posts: 1830
##### Re: How to Generate a Derivative Slope for Mandelbar (Tricorn)
« Reply #6 on: January 05, 2021, 02:43:34 PM »
https://mathr.co.uk/helm/ covers distance estimate for Burning Ship, among other things, which shouldn't be hard to adapt to Mandelbar.

Making it a directional DE, which can be used for slope colouring, is covered in this thread https://fractalforums.org/fractal-image-gallery/18/burning-ship-distance-estimation/647/msg16648#msg16648 (see earlier in the thread for derivation)

#### LionHeart

• Posts: 164
##### Re: How to Generate a Derivative Slope for Mandelbar (Tricorn)
« Reply #7 on: January 06, 2021, 04:28:43 AM »
Thanks FractalAlex,

My mistakes always generate "interesting" images, especially when I play with palettes

Thanks Claude,

There's a lot to take in here. My immediate task is to learn how to use the Jacobian Matrix. Then I need to apply it to derivatives and finally to incorporate it into complex conjugates. I will spend some time looking at it.

I find it interesting that you can apply it to Burning Ship as it contains abs() and these are discontinuities in the curves and therefore there is no continuous derivative. I'm not sure how distance estimation relates to slope calculations, but then I haven't studied your links all that carefully as yet. I'll see what I can come up with.
Many thanks.

• Fractal Frogurt
• Posts: 458
##### Re: How to Generate a Derivative Slope for Mandelbar (Tricorn)
« Reply #8 on: January 06, 2021, 04:24:56 PM »
At least the second image generates some very nice coloring patterns!

Can you post the full code for Mandelbrot ?

#### LionHeart

• Posts: 164
##### Re: How to Generate a Derivative Slope for Mandelbar (Tricorn)
« Reply #9 on: January 06, 2021, 08:44:02 PM »
Please clarify what you need. Is it the Mandelbrot code for Forward differencing?

Maybe this code is what you're looking for...

Code: [Select]
/*    FWDDIFF.CPP a module for determining the slope using forward differencing calculations of fractals.         Written in Microsoft Visual 'C++' by Paul de Leeuw.     https://github.com/hrkalona/Fractal-Zoomer/blob/master/src/fractalzoomer/core/ThreadDraw.java#L3640     https://github.com/hrkalona/Fractal-Zoomer/blob/master/src/fractalzoomer/main/app_settings/BumpMapSettings.java*/#include "slope.h"/**************************************************************************    Calculate functions**************************************************************************/void CSlope::DoSlopeFwdDiffFn(Complex *z, Complex *q)    {    Complex sqr, temp;    Complex t = { 1.0, 0.0 };    double real_imag;    int k;    int degree = (int)param[5];    int degree1, degree2;//    PaletteStart = (int)param[4];    switch (subtype) { case 0: // Mandelbrot     sqr.x = z->x * z->x;     sqr.y = z->y * z->y;     real_imag = z->x * z->y;     z->x = q->x + sqr.x - sqr.y;     z->y = q->y + real_imag + real_imag;     break;// other cases removed }    }/**************************************************************************    Get the gradients in the x and y directions**************************************************************************/double CSlope::getGradientX(double *wpixels, int index, int width)    {    int x = index % width;    double it = *(wpixels + index);    if (x == 0) { return (*(wpixels + index + 1) - it) * 2; }    else if (x == width - 1) { return (it - *(wpixels + index - 1)) * 2; }    else { double diffL = it - *(wpixels + index - 1); double diffR = it - *(wpixels + index + 1); return diffL * diffR >= 0 ? 0 : diffL - diffR; }    }double CSlope::getGradientY(double *wpixels, int index, int width, int height)    {    int y = index / width;    double it = *(wpixels + index);    if (y == 0) { return (it - *(wpixels + index + width)) * 2; }    else if (y == height - 1) { return (*(wpixels + index - width) - it) * 2; }    else { double diffU = it - *(wpixels + index - width); double diffD = it - *(wpixels + index + width); return diffD * diffU >= 0 ? 0 : diffD - diffU; }    }/**************************************************************************   Brightness Scaling**************************************************************************/int CSlope::changeBrightnessOfColorScaling(int rgb, double delta)    {    int     new_color = 0;    double bump_transfer_factor = param[0]; // future add to dialogue box//    double mul = getBumpCoef(delta);    double  mul = (1.5 / (fabs(delta * bump_transfer_factor) + 1.5));    if (delta > 0) { rgb ^= 0xFFFFFF; int r = rgb & 0xFF0000; int g = rgb & 0x00FF00; int b = rgb & 0x0000FF; int ret = (int)(r * mul + 0.5) & 0xFF0000 | (int)(g * mul + 0.5) & 0x00FF00 | (int)(b * mul + 0.5); new_color = 0xff000000 | (ret ^ 0xFFFFFF); }    else { int r = rgb & 0xFF0000; int g = rgb & 0x00FF00; int b = rgb & 0x0000FF; new_color = 0xff000000 | (int)(r * mul + 0.5) & 0xFF0000 | (int)(g * mul + 0.5) & 0x00FF00 | (int)(b * mul + 0.5); }    return new_color;    }/************************************************************************** Slope Fractal**************************************************************************/int CSlope::RunSlopeFwdDiff(HWND hwndIn, void(*plot)(WORD, WORD, DWORD), int user_data(HWND hwnd), char* StatusBarInfo, bool *ThreadComplete, int subtypeIn, int NumThreadsIn, int threadIn, Complex j, double mandel_width, double hor, double vert, double xgap, double ygap,    double rqlim, long threshold, double paramIn[], CTrueCol *TrueCol, CDib *Dib, double *SlopeDataPtr, BYTE juliaflag)    {    Complex z = 0.0; // initial value for iteration Z0    Complex c, q;    BigComplex cBig, zBig, qBig;    BigDouble BigTemp, BigTemp1;    double log_zn, nu;    int lastChecked = -1;    int x, y, i;    DWORD index;    double iterations;    thread = threadIn;    NumThreads = NumThreadsIn;    subtype = subtypeIn;    hwnd = hwndIn;    for (i = 0; i < NUMSLOPEDERIVPARAM; i++) param[i] = paramIn[i];    if (NumThreads == 0) StripWidth = xdots;    else StripWidth = xdots / NumThreads;    StripStart = StripWidth * thread;    *ThreadComplete = false;    for (y = 0; y < ydots; y++) { if (BigNumFlag)     cBig.y = BigVert + BigWidth - Big_ygap * y; else     c.y = vert + mandel_width - y * ygap; double progress = (double)y / ydots; if (int(progress * 100) != lastChecked)     {     lastChecked = int(progress * 10);     sprintf(StatusBarInfo, "Progess (%d%%), %d Threads", int(progress * 100), NumThreads);     } for (x = StripStart; x < StripStart + StripWidth; x++)     {     if (user_data(hwnd) < 0) // trap user input return -1;     c.x = hor + x * xgap;        {         if (juliaflag)             {             q = j;             z = c;             }         else             {             q = c;             z = 0.0;             }         }     iterations = 0.0;     for (;;) { iterations++; if (iterations >= threshold)     break; DoSlopeFwdDiffFn(&z, &q); if ((z.x * z.x + z.y * z.y) >= rqlim)     break; }     if (iterations < threshold) { if (BigNumFlag)     {     // sqrt of inner term removed using log simplification rules.     BigTemp = zBig.x * zBig.x + zBig.y * zBig.y;     BigTemp1 = BigTemp.BigLog();     log_zn = mpfr_get_d(BigTemp1.x, MPFR_RNDN) / 2;     nu = log(log_zn / log(2.0)) / log(2.0);     } else     {     // sqrt of inner term removed using log simplification rules.     log_zn = log(z.x * z.x + z.y * z.y) / 2;     nu = log(log_zn / log(2.0)) / log(2.0);     } iterations = iterations + 1 - nu; }     index = ((DWORD)y * (DWORD)width) + (DWORD)x;     if (x >= 0 && x < xdots - 1 && y >= 0 && y < ydots - 1) *(SlopeDataPtr + index) = iterations;     plot(x, y, (long)iterations);     } }    *ThreadComplete = true;    return 0;    }/************************************************************************** Slope Fractal**************************************************************************/int CSlope::RenderSlope(long threshold, double paramIn[], CTrueCol *TrueCol, CDib *Dib, double *SlopeDataPtr)    {    double dotp, gradAbs, gradCorr, cosAngle, sizeCorr, smoothGrad, lightAngleRadians, lightx, lighty;        for (int i = 0; i < NUMPARAM; i++) param[i] = paramIn[i];    double bumpMappingDepth = param[3]; // future add to dialogue box    double bumpMappingStrength = param[4]; // future add to dialogue box    double lightDirectionDegrees = param[2]; // future add to dialogue box    int PaletteStart = (int)param[1];    double iterations;    int lastChecked = -1;    DWORD index;    int x, y;    double gradx, grady;    unsigned char r, g, b;    RGBTRIPLE colour;    int modified;    lastChecked = -1;    sizeCorr = 0.0;    lightx = 0.0;    lighty = 0.0;    gradCorr = pow(2, (bumpMappingStrength - DEFAULT_BUMP_MAPPING_STRENGTH) * 0.05);    sizeCorr = ydots / pow(2, (MAX_BUMP_MAPPING_DEPTH - bumpMappingDepth) * 0.16);    lightAngleRadians = lightDirectionDegrees * PI / 180.0;    lightx = cos(lightAngleRadians) * gradCorr;    lighty = sin(lightAngleRadians) * gradCorr;    for (y = 0; y < ydots; y++) { for (x = 0; x < xdots; x++)     {     index = ((DWORD)y * (DWORD)width) + (DWORD)x;     if (SlopeDataPtr) iterations = *(SlopeDataPtr + index);     else return 0; // oops, we don't actually have forward differencing     if (iterations >= threshold) { //  interior of Mandelbrot set = inside_color colour.rgbtRed = (BYTE)TrueCol->InsideRed; // M_waves colour.rgbtGreen = (BYTE)TrueCol->InsideGreen; colour.rgbtBlue = (BYTE)TrueCol->InsideBlue; }     else { // modified = rgbs[index]; if (iterations < PaletteStart)     modified = 0x00FFFFFF; else     modified = 0xFF000000 | ((DWORD)*(TrueCol->PalettePtr + (BYTE)(((long)iterations) % 256) * 3 + 0) << 16) | ((DWORD)*(TrueCol->PalettePtr + (BYTE)(((long)iterations) % 256) * 3 + 1) << 8) | *(TrueCol->PalettePtr + (BYTE)(((long)iterations) % 256) * 3 + 2); gradx = getGradientX(SlopeDataPtr, index, xdots); grady = getGradientY(SlopeDataPtr, index, xdots, ydots); dotp = gradx * lightx + grady * lighty;// int original_color = modified; // not sure what this is for if (dotp != 0)     {     gradAbs = sqrt(gradx * gradx + grady * grady);     cosAngle = dotp / gradAbs;     smoothGrad = -2.3562 / (gradAbs * sizeCorr + 1.5) + 1.57;     //smoothGrad = Math.atan(gradAbs * sizeCorr);     modified = changeBrightnessOfColorScaling(modified, cosAngle * smoothGrad);     } r = (modified >> 16) & 0xFF; g = (modified >> 8) & 0xFF; b = modified & 0xFF; colour.rgbtRed = r; colour.rgbtGreen = g; colour.rgbtBlue = b; }     outRGBpoint(Dib, x, y, colour);     } }    return 0;    }

#### LionHeart

• Posts: 164
##### Re: How to Generate a Derivative Slope for Mandelbar (Tricorn)
« Reply #10 on: January 07, 2021, 08:55:03 PM »
Hi Claude

I'm struggling to make sense of the Jacobian Matrix for taking the derivative of a function. Are you able to give me some hints in the practical application, preferably with some code samples?

Many thanks.

#### claude

• 3f
• Posts: 1830
##### Re: How to Generate a Derivative Slope for Mandelbar (Tricorn)
« Reply #11 on: January 08, 2021, 05:57:01 PM »
slope relates to directional DE because both are based on spatial derivative of escape time
https://code.mathr.co.uk/kalles-fraktaler-2/blob/ec44abb522811ea93e03c8a27933b19472d54bc1:/fraktal_sft/fraktal_sft.cpp#l1053 is the implementation in KF with analytic DE (simple) vs forward differences (ugly, inaccurate, noisy when jitter is enabled)

re jacobians,
https://code.mathr.co.uk/kalles-fraktaler-2/blob/ec44abb522811ea93e03c8a27933b19472d54bc1:/formula/formula.xml#l175 is the implementation in KF including derivatives for Burning Ship
https://code.mathr.co.uk/kalles-fraktaler-2/blob/ec44abb522811ea93e03c8a27933b19472d54bc1:/formula/formula.xml#l402 is Mandelbar
Hopefully those examples are clear enough.  (daa, dab; dba, dba) is the identity matrix for normal views, zooming/rotating/skewing changes these.

#### LionHeart

• Posts: 164
##### Re: How to Generate a Derivative Slope for Mandelbar (Tricorn)
« Reply #12 on: January 08, 2021, 08:25:36 PM »
Wow thanks Claude.

I'll study these and hopefully have some working code soon.

You're a gem

### Similar Topics

###### Simplex Mandelbar (^2 Tricorn+ ^-2 Tricorn/(tan(re(z)-i*im(z)))^2+c)

Started by MichaelAutism on Share a fractal

1 Replies
212 Views
April 08, 2021, 12:05:24 AM
by gerson
###### "Time Span"

Started by cricke49 on Fractal Image Gallery

0 Replies
900 Views
August 02, 2018, 07:05:21 AM
by cricke49
###### A new style of fractal imagery using fractal neural style transfer

Started by iRyanBell on Fractal Image Gallery

3 Replies
841 Views
October 03, 2020, 10:50:39 PM
by Jimw338
###### Crazy fractal hybrid mandelbar burning ship and mandelbrot.

Started by realflow100 on Fractal Image Gallery

0 Replies
337 Views
December 24, 2017, 02:33:35 PM
by realflow100
###### Computing bounds on the potential function and it's derivative
15 Replies
642 Views
April 04, 2020, 07:46:42 AM
by gerrit