Logo by CorneliaYoder - Contribute your own Logo!

END OF AN ERA, FRACTALFORUMS.COM IS CONTINUED ON FRACTALFORUMS.ORG

it was a great time but no longer maintainable by c.Kleinhuis contact him for any data retrieval,
thanks and see you perhaps in 10 years again

this forum will stay online for reference
News: Check out the originating "3d Mandelbulb" thread here
 
*
Welcome, Guest. Please login or register. April 19, 2024, 09:15:27 PM


Login with username, password and session length


The All New FractalForums is now in Public Beta Testing! Visit FractalForums.org and check it out!


Pages: [1] 2 3   Go Down
  Print  
Share this topic on DiggShare this topic on FacebookShare this topic on GoogleShare this topic on RedditShare this topic on StumbleUponShare this topic on Twitter
Author Topic: Perturbation formula for burning ship (hopefully correct :P)  (Read 4634 times)
0 Members and 3 Guests are viewing this topic.
laser blaster
Iterator
*
Posts: 178


« on: May 18, 2014, 05:40:25 AM »

I took a shot at deriving the perturbation formula for the burning ship fractal. I need someone to check it for correctness though, because I'm not really a math guru. cheesy

So with the burning ship formula, the component-wise abs function means you need to split it into real and imaginary components. Let Z be the reference point, and let r and i be the real and imaginary components of Z.

Zn+1:    
    rn+1 = rn2 - in2 + r0
    in+1 = 2 * abs(rn * in) + i0
(I simplified out some of the abs()s, the result will be the same)

Let W be the pixel we are going to iterate, and let x and y be the real and imaginary components of W.
Let D be the difference between the pixel point and reference point, let a and b be the real and imag parts of D

W0 = Z0 + D0  
D0 = W0 - Z0

Dn+1 = Wn+1 - Zn+1

Dn+1:
    an+1 = (xn2 - yn2 + x0) - (rn2 -in2 + r0)
   edit:
    bn+1 = 2*(abs(xnyn) + y0 - abs(rnin)-i0)
   bn+1 = 2*abs(xnyn) + y0 - 2*abs(rnin)-i0

Now, putting Dn+1 in terms of rn,in,an, and bn only (getting rid of all the x's and y's):

an+1 = ( (rn + an)2 -  (in + bn)2 + r0 + a0) ) - (rn2  - in2 + r0)
    edit:
    = (rn2 + 2anrn + an2 - in2 + 2inbn + bn2 +r0 + a0) - (rn2 - in2 + r0)
    = (rn2 + 2anrn + an2 - in2 - 2inbn - bn2 +r0 + a0) - (rn2 - in2 + r0)
    some of the terms cancel...
    = 2anrn + an2 - 2inbn - bn2 + a0
    Now all the terms in the equation for a are "small" when D is small.

b is harder to simplify due to the non-removable abs() function. But here goes: (continued next post)
« Last Edit: May 18, 2014, 05:52:12 PM by laser blaster » Logged
laser blaster
Iterator
*
Posts: 178


« Reply #1 on: May 18, 2014, 05:45:52 AM »

edit:
bn+1 = 2( abs((rn+an)*(in+bn)) + i0 + b0 - abs(rnin) - i0 )
    = 2( abs(rnin+rnbn+anin+anbn) + b0 - abs(rnin) )

bn+1 = 2*abs((rn+an)*(in+bn)) + i0 + b0 - 2*abs(rnin) - i0
    = 2( abs(rnin+rnbn+anin+anbn) - abs(rnin) ) + b0


Now the important thing to note about the above formula is that 3 of the terms inside the first abs() contain an or bn as a factor, and so those three terms will be small when D is small. There is one term, rnin, that doesn't have a or b as a factor (so it's too "large"), but there's a tantalizing  "- abs(rnin)" after that that looks like it could be made to cancel with the earlier term. However, the  first occurence of rnin is wrapped up in an abs() function with other terms, which complicates things.

To understand how to make the large terms vanish, I simplified the problem to it's basics: given the formula abs(c+d) - abs(c), try to find the answer without having the result depend on c. (c stands in for rnin (the "large" term), and d stands in for the sum of the other, smaller terms) (comparisons with c in conditional statements are fine, as you can use a rounded double precision representation of c and experience no precision loss, as long as your other comparison operand is "small" enough to be represented as a double(d meets this criteria)).


The result can be expressed without an abs, using conditionals:

abs(c+d) - abs(c):
    if c>0:
        if c+d > 0 (e.g. d > -c):
            result = d
        else if d == -c:
            result = d
        else if d < -c:
            result = -d -2c
    else if c==0:
        result = abs(d)
    else if c < 0:
        if c+d>0 (e.g. d > -c)
            result = d + 2c
        else if d == -c:
            result = -d
        else if d < -c:
            result = -d

That should give the proper result for all c and d, I think (I hope).
Notice that I was able to express the result in terms of d alone (except for the comparisons between d and c, but as I mentioned above, these can be done exactly in the precision of the least precise operand, so we can use fast native doubles), except for two cases, where the result still involves a (-d - 2c, and d + 2c). Upon first glance it seems that we’re screwed, because c is too “large” for the perturbation technique to work. But notice that the result only involves c in when either: c is positive and d is less than -c, or c is negative and d is greater than -c. So in either case, the magnitude of d  (the supposed “small” term) is already LARGER than the magnitude of c, and what’s more, the two have opposite signs. So the addition of the 2c or -2c term will not result in any loss of significant digits of the difference between adjacent pixel points. And, as I learned in Pauldelbrot’s glitch-fixing thread, the magnitude of the D (and here I mean delta, the difference between the reference and pixel points) term isn’t what’s important, the important thing is that there be enough bits of precision to accurately represent the difference between adjacent points, and as long as that’s the case, there won’t be any glitches.
    
Now just replace d with rnbn+anin+anbn and c with rnin, calculate the result using the above algorithm with the conditionals, multiply that by 2, and add to that b0,  and you’ve got bn+1. Now you can find the real and imaginary components of Dn+1.

The one thing I didn't attempt was series approximation. I have a feeling it's possible, but it will obviously be two real-valued functions, each in two varaibles, plus with special considerations for the abs() function, rather than complex-valued polynomial function of a complex variable. Much more complicated than the Mandy approximation

I might have made a typo just typing in my work on paper, so I will check for that tomorrow.
« Last Edit: May 18, 2014, 06:35:40 PM by laser blaster » Logged
laser blaster
Iterator
*
Posts: 178


« Reply #2 on: May 18, 2014, 05:59:04 AM »

Uh oh, I think I see a mistake. shocked  sad cry

I need to learn to check before posting.  Looks like I have to redo the work for b. I think it should still be possible.
Logged
DarkBeam
Global Moderator
Fractal Senior
******
Posts: 2512


Fragments of the fractal -like the tip of it


« Reply #3 on: May 18, 2014, 11:19:11 AM »

Uh-oh, abs() makes bad jokes when you derive... wink cheesy Good luck police
Logged

No sweat, guardian of wisdom!
Kalles Fraktaler
Fractal Senior
******
Posts: 1458



kallesfraktaler
WWW
« Reply #4 on: May 18, 2014, 04:32:59 PM »

Cool, I hope you succeed finding the formula!

I guess Series Approximation is not possible since it is based on derivatives...?
Logged

Want to create DEEP Mandelbrot fractals 100 times faster than the commercial programs, for FREE? One hour or one minute? Three months or one day? Try Kalles Fraktaler http://www.chillheimer.de/kallesfraktaler
http://www.facebook.com/kallesfraktaler
laser blaster
Iterator
*
Posts: 178


« Reply #5 on: May 18, 2014, 05:33:03 PM »

Okay, the abs() was throwing me for a loop... but it is valid to replace abs(x)*abs(y) with abs(x*y), then substitute x any y with an equivalent expression, and expand out the multiplication, right? So that part was fine. But I made another mistake, which I'm gonna fix now.

Okay, I fixed a few things. It might be correct now, but I'll check over it a few more times to make sure it all works out.
« Last Edit: May 18, 2014, 06:38:05 PM by laser blaster » Logged
laser blaster
Iterator
*
Posts: 178


« Reply #6 on: May 20, 2014, 11:13:27 PM »

Wooo! It works! cheesy joy

I wrote a quick test in Fragmentarium. I calculated the reference point in double precision (of course, due to the nature of pixel shaders, I have to recalculate the reference point for every pixel, so it runs slower than just using double precision in the first place, but a CPU-based implementation will have no such limitations), and calculated delta in just single precision, and now I can zoom to double precision levels without pixelization.

I attached a comparison picture showing the difference without perturbation (It'll be up in a sec)

I also attached the .frag file along with a slightly changed version of the Progressive2D.frag include file ( I just added 1 line of code to enable native doubles). Note that I actually calculate the reference point in the main loop along with the delta. Trust me, it would work just as well if the reference point were precomputed and stored in a array.

* Progressive2D.frag (2.99 KB - downloaded 91 times.)
* BS_Perturb.frag (3.78 KB - downloaded 86 times.)
Logged
laser blaster
Iterator
*
Posts: 178


« Reply #7 on: May 20, 2014, 11:18:36 PM »

Here's the comparison pic.


* BS Perturb.jpg (81.06 KB, 900x319 - viewed 173 times.)
Logged
Kalles Fraktaler
Fractal Senior
******
Posts: 1458



kallesfraktaler
WWW
« Reply #8 on: May 22, 2014, 04:52:13 PM »

Wooohooo! It works! cheesy joy

But your formula
bn+1 = 2( abs(rnin+rnbn+anin+anbn) - abs(rnin) ) + b0
don't work since rnbn+anin+anbn can be much smaller/bigger than rnin when zooming deeper than e18.
So I had to use your conditions... smiley


* bs.png (114.31 KB, 300x232 - viewed 734 times.)
Logged

Want to create DEEP Mandelbrot fractals 100 times faster than the commercial programs, for FREE? One hour or one minute? Three months or one day? Try Kalles Fraktaler http://www.chillheimer.de/kallesfraktaler
http://www.facebook.com/kallesfraktaler
laser blaster
Iterator
*
Posts: 178


« Reply #9 on: May 22, 2014, 07:28:16 PM »

Awesome! I can't wait to try it! afro
Logged
Kalles Fraktaler
Fractal Senior
******
Posts: 1458



kallesfraktaler
WWW
« Reply #10 on: May 26, 2014, 02:43:26 PM »

I wish I could use the "Power" field to set an arbitrary power also for the Burning Ship fractal in Kalles Fraktaler.
That would be so cool!

However, the absolute values complicates things a lot.
I made a simple complex class for the higher powers of Mandelbrot, that only implemented addition, subtraction and multiplication. I use it from power 4, because it get too complicated to expand all the terms and too easy to make mistakes.

When making full precision calculations of a pixel in the Burning Ship fractal, I have found out that the standard Mandelbrot formula can be used with the only addition to set the real and imaginary parts to absolute values for each iteration (and the square (2) can be replaced by any value):
while(!bailout){
  X = X2 + X0
  X.r = abs(X.r)
  X.i = abs(X.i)
}


Unfortunately this does not work on the perturbation formula that calculates from a reference:
while(!bailout){
  D = 2*X*D + D2 + D0
  D.r = abs(D.r)
  D.i = abs(D.i)
}

Firstly, it seems the absolutes needs to be applied considering how the real and imaginary parts are grouped in the expanded expressions.
Secondly, there are these "abs(c+d) - abs(c)" situations, which in higher depths (>e18) don't give accurate result and must be solved by the conditions that laser blaster created.

Maybe there is a way to generalize arbitrary powers of Burning Ship, but it seems very complicated. I did an attempt to the 3rd power (using the same variable names as laser blaster), but I haven't tried to program it yet:

r = abs(r3) - abs(3*r*i2) + r0
i = abs(3*r2*i) - abs(i3) + i0

a = abs(x3) - abs(3*x*y2) + x0 - (abs(r3) - abs(3*r*i2) + r0)
b = abs(3*x2*y) - abs(y3) + y0 - (abs(3*r2*i) - abs(i3) + i0)

a = abs((r+a)3) - abs(3*(r+a)*(i+b)2) + r0 + a0 - abs(r3) + abs(3*r*i2) - r0
a = abs((r3 + 3*r2*a + 3*r*a2+a3)) - abs(3*(r+a)*(i2+2*i*b+b2)) + a0 - abs(r3) + abs(3*r*i2)
a = abs((r3 + 3*r2*a + 3*r*a2+a3)) - abs(r3) + abs(3*r*i2) - abs(3*r*i2 + 6*r*i*b + 3*r*b2 + 3*a*i2 + 6*a*i*b + 3*a*b2) + a0
...we have two abs(c+d) - abs(c) situations here (one is reversed)

b = abs(3*(r+a)2*(i+b)) - abs((i+b)3) + (i0+b0) - abs(3*r2*i) + abs(i3) - i0
b = abs(3*r2*i+6*r*a*i+3*a2*i + 3*r2*b+6*r*a*b+3*a2*b) - abs(i3+3*i2*b+3*i*b2+b3) + b0 - abs(3*r2*i) + abs(i3)
b = abs(3*r2*i+6*r*a*i+3*a2*i + 3*r2*b+6*r*a*b+3*a2*b) - abs(3*r2*i) + abs(i3) - abs(i3+3*i2*b+3*i*b2+b3) + b0
...and we also have two abs(c+d) - abs(c) situations here, again one reversed

So I guess it is necessary to expand everything for each power and identify all abs(c+d) - abs(c) situations and grouping, and the 4th power would be enormously complicated...
Unless the complex class could be modified to be able to handle the absolutes automatically.
But I don't know how...
« Last Edit: May 26, 2014, 06:10:43 PM by Kalles Fraktaler » Logged

Want to create DEEP Mandelbrot fractals 100 times faster than the commercial programs, for FREE? One hour or one minute? Three months or one day? Try Kalles Fraktaler http://www.chillheimer.de/kallesfraktaler
http://www.facebook.com/kallesfraktaler
Kalles Fraktaler
Fractal Senior
******
Posts: 1458



kallesfraktaler
WWW
« Reply #11 on: May 26, 2014, 10:13:26 PM »

Unfortunately my attempt was not successful...  hurt
Logged

Want to create DEEP Mandelbrot fractals 100 times faster than the commercial programs, for FREE? One hour or one minute? Three months or one day? Try Kalles Fraktaler http://www.chillheimer.de/kallesfraktaler
http://www.facebook.com/kallesfraktaler
stardust4ever
Fractal Bachius
*
Posts: 513



« Reply #12 on: September 16, 2014, 01:59:26 PM »

I'm bumping this thread because I would like to see it done. The third order Burning Ship is one of the most beautifully symmetrical fractals I have seen, with three needles. It was originally popularized by a video posted by HPDZ.

The code I developed in 2012 for the floating point portion of the FX plugin works like this:

Code:
Cubic Burning Ship:

zi = ((zrsqr * 3.0) - zisqr) * abs(zi) + JuliaI;
zr = (zrsqr - (zisqr * 3.0)) * abs(zr) + JuliaR;
zisqr = zi * zi;
zrsqr = zr * zr;

Cubic Buffalo:

zi = abs(((zrsqr * 3.0) - zisqr) * zi) + JuliaI;
zr = abs((zrsqr - (zisqr * 3.0)) * zr) + JuliaR;
zisqr = zi * zi;
zrsqr = zr * zr;

Although we had several missed attempts at getting the 3rd order formula right, compare to these 2nd order formula that Panzerboy initially created:

Code:
Burning ship:

zi = abs(zr * zi) * -2.0 + JuliaI;
zr = zrsqr - zisqr + JuliaR;
zisqr = zi * zi;
zrsqr = zr * zr;

Celtic:

zi = zr * zi * 2.0 + JuliaI;
zr = abs(zrsqr - zisqr) + JuliaR;
zisqr = zi * zi;
zrsqr = zr * zr;

Buffalo:

zi = abs(zr * zi) * -2.0 + JuliaI;
zr = abs(zrsqr - zisqr) + JuliaR;
zisqr = zi * zi;
zrsqr = zr * zr;
As seen above, the 2nd order abs fractals can be generated by applying the abs() command to the entire real or imaginary part of the equation.

In fact, these are all subsets of a larger group of twelve 2nd order Mandelbrot variant fractals I have categorized, including the Mandelbar and Perpendicular sets. Ten of those formulas including the standard M-set are made available in Fractal Extreme as a set of plugins by Panzerboy, some of which I helped create. The two fractal formulas that got omitted are nothing to write home about. I'll save further discussion regarding the twelve Mandelbrot abs() variants, as well as some of my recent musings into the 3rd order, for another topic.

Applying the abs() command only to the entire Zr or Zi after exponent does not get the same results for higher orders. In second order, if both the Zi and Zr components are absoluted prior to squaring, we get essentially the same result as applying the abs() part on the imaginary side post squaring. The reason for this is that the real component contains only square parts, making an abs() operation prior to squaring moot. The Imaginary component contains the product of Zr and Zi, so the result will be positive whether the abs() command is applied before or after. The "-2" multiplicand is only to flip the imaginary channel, making the ship appear mast up as it is most commonly rendered. For the third order version of the Burning Ship, there is only one operand per coordinate that needs the abs() function, due to distributive property of mathematics.

I really don't have a grasp of the actual mathematics behind perturbation theory, but if it works with the burning ship fractal, it should work with the 3rd order as well? It seems that the pixels mostly stick together as their values orbit the set, and the change (delta) values between adjacent pixels changes little during the course of the journey, enabling lower precision than the main orbit. Do the abs() commands really screw it up that bad? It seems the base fractal would not be possible if it did.

Honestly I would be happy with just the 2nd and 3rd order version. I have viewed the 4th and higher higher order versions of the Burning Ship fractals and on first glance (using slow as molassis UF5), they simply don't have the ornate symmetry of the 2nd and 3rd order versions.
« Last Edit: September 16, 2014, 02:39:36 PM by stardust4ever » Logged
youhn
Fractal Molossus
**
Posts: 696


Shapes only exists in our heads.


« Reply #13 on: September 16, 2014, 04:37:40 PM »

That abs operation makes a very big difference between the mandelbrot set and the burning ship. This addition makes the burning ship non-analytical. If I got it right, this should mean that the perturbation thing should NOT work on the bs fractal. But somehow it does. Perhaps the reason is what you just wrote:

Quote from: stardust4ever
The reason for this is that the real component contains only square parts, making an abs() operation prior to squaring moot. The Imaginary component contains the product of Zr and Zi, so the result will be positive whether the abs() command is applied before or after.

If this is the case, the perturbation thing should work on anything with even powers.
Logged
stardust4ever
Fractal Bachius
*
Posts: 513



« Reply #14 on: September 16, 2014, 06:06:53 PM »

That abs operation makes a very big difference between the mandelbrot set and the burning ship. This addition makes the burning ship non-analytical. If I got it right, this should mean that the perturbation thing should NOT work on the bs fractal. But somehow it does. Perhaps the reason is what you just wrote:

If this is the case, the perturbation thing should work on anything with even powers.
So abs() operands are allowed within the imaginary part but not the real part? Or is it a requirement the abs operation needs to be performed after the exponent (the entire Zi or Zr, not just a portion of it)? One way to look at it is like a fast driving car. Mandelbrot is fully connected like a highway with gradual, wide turns. Many shapes in the abs sets are extremely angular and disconnected. No matter how well you think your car handles, in real life a Dukes of Hazzard style jump or a hairpin turn going 155mph will cause you to crash... If a pixel encounters an abs operation prior to the bailout (for instance the delta orbit of the pixel gets a sign change at some point compared to the reference orbit resulting in a detour of the orbit path, which is probably likely at some point given the frequencies of angular and reflected symmetries within the fractal), does this automatically cause the float point estimator to fail?

If so, then why does the quadratic BS work? nerd
« Last Edit: September 16, 2014, 06:13:10 PM by stardust4ever » Logged
Pages: [1] 2 3   Go Down
  Print  
 
Jump to:  

Related Topics
Subject Started by Replies Views Last post
Burning Ship Mutatorkammer Gallery cKleinhuis 2 5487 Last post March 21, 2008, 05:22:42 PM
by GFWorld
3D burning ship Mandelbulb3D Gallery bib 0 4739 Last post November 02, 2010, 09:34:27 PM
by bib
Distance Estimation formula for the Burning Ship? Programming laser blaster 4 5856 Last post April 20, 2014, 05:45:28 PM
by top-quark
Burning Ship with Perturbation Movies Showcase (Rate My Movie) Kalles Fraktaler 1 1015 Last post May 23, 2014, 06:07:35 PM
by ellarien
3D Burning Ship formula and .frag file Fragmentarium laser blaster 7 4474 Last post March 01, 2015, 07:15:02 PM
by Crist-JRoger

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines

Valid XHTML 1.0! Valid CSS! Dilber MC Theme by HarzeM
Page created in 0.223 seconds with 24 queries. (Pretty URLs adds 0.01s, 2q)