Logo by Timeroot - 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: Visit the official fractalforums.com Youtube Channel
 
*
Welcome, Guest. Please login or register. January 09, 2026, 07:20:00 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 [4] 5 6 7   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: Benesi "pinetree" (fold+bulb)  (Read 7184 times)
0 Members and 1 Guest are viewing this topic.
M Benesi
Fractal Schemer
****
Posts: 1075



WWW
« Reply #45 on: October 18, 2015, 02:18:03 AM »

Hi,
I mean the math, but in terms which make it easy for me to translate it into MB3D's environment (in order to avoid errors while translating it).
Not sure, how it is currently done, but I was hoping there is something between the pure math and the compiled/optimized ASM-stuff.

  Hey Andreas,

  The math for formula 1 and 2 is in the first post of this thread.  The math for the "Pine Tree" version of the Mandelbulb is described in post 8.  If you want further explanations, ask away.


  Something I forgot to tell Luca before he started coding:

  Only add in the x pixel component after the Pine Tree Mandelbulb portion for maximum symmetry.

  I'd do all 3 (pine tree, mod 1, and mod 2) formulas stand alone, so they can be alternated with one another.
Logged

thargor6
Fractal Molossus
**
Posts: 789



WWW
« Reply #46 on: October 19, 2015, 12:15:24 AM »

Hi,
I think I succeeded with including Formula 1 in my experimental MB3D-solution (i. e., I entered just the text, but in Pascal-syntax).
I have combined a classic mandelbulb (i. e. IntPower) with this formula and got the following cool result:

The solution is not really usable now (one cant even save params), but I think it is the way to go.

Best regards,
Andreas
Logged
M Benesi
Fractal Schemer
****
Posts: 1075



WWW
« Reply #47 on: October 19, 2015, 01:18:10 AM »

  Looks like the tree I was trimming a few minutes ago.    A Beer Cup
Logged

M Benesi
Fractal Schemer
****
Posts: 1075



WWW
« Reply #48 on: October 22, 2015, 05:29:39 AM »

So, I split the formulas into the transforms, and the pine tree portions.  Made a pine tree with only the x-pixel component as well.

I've yet to figure out how to do something like:

 T1, PTx, T1, PTx, T1, PTxyz, PTx, T2, PTx, T1

  T1: transform 1   
  T2: ...  Ahhnolldd  ...
  PTx:  Pine tree with x-pixel component only
  PTxyz: pine tree with x,y, and z pixel components
 
  Here is a mix of T1 and PTx...



All the code for the split formulas...  with them attached below.  Also code for pine tree 1, with no y and z, and pine tree 2 with no y and z...  maybe next post.  Can't attach any more.... cheesy
Code:
[OPTIONS]
.Version = 2
.DEscale = 1
.SIpower = 2
.Double Scale = 2.0
.Double xOff = 2.0
[CONSTANTS]
Double = 0.816496580927726     
Double = 0.5773502691896258
Double = 0.7071067811865475
[CODE]
558BEC81EC300000005356578B75088B7E308BD8D9D0DD03DC0FDD01DC4F08D9
E0DEC1DC4F10DD5DF8DD03DC4F08DD01DC0FDEC1D9E190DD45F8DD02DC4F10D9
E0DEC1D9E190DD45F8DD02DC4F10DEC1D9E190DD1ADD1BDD1990DD03DC02DC4F
10DD5DF890DD03D9E0DC02DC4F1090DD45F8DC0FDD01DC4F08DEC190DD45F8DC
4F08D9E0DD01DC0FDEC190DD19DD1BDD1A90DD03DC4FF0DC67E8DD1BDD02DC4F
F0DD1ADD01DC4FF0DD1990D9D08BC35F5E5B89EC5DC20800
[END]


Description:

Cool??  :D  absolute value xyz transform;

// STEP1: "Benesi transform 1"
tx=(x*sqrt(2/3)-z*sqrt(1/3))*sqrt(1/2);
z=abs(x*sqrt(1/3) + z*sqrt(2/3));   
x=abs(tx-y*sqrt(1/2));         
y=abs(tx+y*sqrt(1/2));

tx=x*sqrt(1/2)+y*sqrt(1/2);
y=-x*sqrt(1/2)+y*sqrt(1/2);
x=tx*sqrt(2/3)+z*sqrt(1/3);
z=-tx*sqrt(1/3)+z*sqrt(2/3);

x=scale*x-offset;  //scale =2    offset=2       
y=scale*y;
z=scale*z;



................................................................Transform 2...,,,,.,,,,.

[OPTIONS]
.Version = 2
.DEscale = 1
.SIpower = 2
.Double Scale = 2.0
.Double xOff = 2.0
[CONSTANTS]
Double = 0.816496580927726
Double = 0.5773502691896258
Double = 0.7071067811865475
[CODE]
558BEC81EC300000005356578B75088B7E308BD8D9D0DD03DC0FDD01DC4F08D9
E0DEC1DC4F10DD5DF8DD02DC4F10DD1A90DD03DC4F08DD01DC0FDEC190DD45F8
DC2290DD45F8DC0290D8C8DD5DF0D8C8DD5DF8D8C8DD19D9D0DD45F0DC01D9FA
DC67E8D9E1DC4FF0DC4F10DD1B90DD45F8DC01D9FADC67E8D9E1DC4FF0DC4F10
DD1A90DD45F8DC45F0D9FADC67E8D9E1DC4FF0DD1990DD02DC03DD02DC23DD1A
DD5DF890DD45F8DC0FDD01DC4F08DEC1DD45F8DC4F08D9E0DD01DC0F90DEC1DD
19DD1B90D9D08BC35F5E5B89EC5DC20800
[END]


Description:

The cool Benesi pinetree formula. Use in conjunction with normal
 BenesiPine1 or it is messy!
Or any other formula :)
(Three iters of pine1 + one of pine2)

// STEP1: "Benesi fold 2"
tx=(x*sqrt(2/3)-z*sqrt(1/3))*sqrt(1/2);
y=y*sqrt(1/2);
z=(x*sqrt(1/3) + z*sqrt(2/3))^2;   
tx=(tx-y)^2;         
ty=(tx+y)^2;

x=abs(sqrt(ty+z)-offset2)*scale2*sqrt(1/2) ;
y=abs(sqrt(tx+z)-offset2)*scale2*sqrt(1/2) ;   
z=abs(sqrt(tx+ty)-offset2)*scale2 ;

tx=y+x; y=y-x;
x=z*sqrt(1/3)+x*sqrt(2/3);
z=z*sqrt(2/3)-x*sqrt(1/3);


..................................Pine Tree X pixel Only!@$...................................
[OPTIONS]
.Version = 2
.DEscale = 1
.SIpower = 2
[CONSTANTS]

[CODE]
558BEC81EC300000005356578B75088B7E308BD8D9D0DD03D8C8DD5DF8DD02D8C8DD5DF0DD01D8C8DD5DE8
DD03D8C0DD45F0DC45E8D9FADEF9DD5DE090DD45F8DC65F0DC65E890DD45E0DD
45F0DC65E8DEC990DD45E0D8C0DC09DC0A90DD1A90DD1990DC46
18DD1BD9D08BC35F5E5B89EC5DC20800
[END]


Description:


//"Benesi pinetree X pixel"
xt = x*x; yt = y*y; zt = z*z;
t = 2*x/sqrt(yt+zt);
x = xt-yt-zt+Cx;
z = t*(yt-zt);
y = 2*t*y*z;


...................................................Pine Tree with xyz pixel......................
[OPTIONS]
.Version = 2
.DEscale = 1
.SIpower = 2
[CONSTANTS]

[CODE]
558BEC81EC300000005356578B75088B7E308BD8D9D0DD03D8C8DD5DF8DD02D8C8DD5DF0DD01D8C8DD5DE8
DD03D8C0DD45F0DC45E8D9FADEF9DD5DE090DD45F8DC65F0DC65E890DD45E0DD
45F0DC65E8DEC990DD45E0D8C0DC09DC0A90DC4620DD1A90DC4628DD1990DC46
18DD1BD9D08BC35F5E5B89EC5DC20800
[END]


Description:


//"Benesi pinetree XYZ pixel"
xt = x*x; yt = y*y; zt = z*z;
t = 2*x/sqrt(yt+zt);
x = xt-yt-zt+Cx;
z = t*(yt-zt);
y = 2*t*y*z;

[/code][/code][/code][/code]

* BenesiPineX.m3f (4.45 KB - downloaded 26 times.)
* BenesiPineXYZ.m3f (9.68 KB - downloaded 21 times.)
* BenesiTransform1.m3f (7.19 KB - downloaded 23 times.)
* BenesiTransform2.m3f (1.17 KB - downloaded 20 times.)
Logged

thargor6
Fractal Molossus
**
Posts: 789



WWW
« Reply #49 on: October 22, 2015, 11:46:18 PM »

Edit, I finally succeeded by translating the first non-trivial formula (your initial formula 1 +2), so that it runs on the experimental embedded formula compiler and leads to the same result.

Using this system, this formula can be written like this:
Code:
[OPTIONS]
.Version = 2
.DEscale = 1
.SIpower = 2
[SOURCE]
procedure BenesiPineTree(var x, y, z, w: Double; PIteration3D: TPIteration3D);
var
  scale, offset: Double;
  sqrt_1_2, sqrt_1_3, sqrt_2_3: Double;
  start_x, start_y, start_z: Double;
  temp_x, temp_y, temp_z, temp: Double;  
  new_x, new_y, new_z: Double;
  x_temp, y_temp, z_temp: Double;

begin
  scale := 2.0;
  offset := 2.0;

  sqrt_1_2 := sqrt(1.0/2.0);
  sqrt_1_3 := sqrt(1.0/3.0);
  sqrt_2_3 := sqrt(2.0/3.0);

  start_x := x; start_y := y; start_z := z;
  temp_x := start_x*sqrt_2_3-start_z*sqrt_1_3;
  new_z := start_x*sqrt_1_3 + start_z*sqrt_2_3;
  new_x := temp_x*sqrt_1_2-start_y*sqrt_1_2;
  new_y := temp_x*sqrt_1_2+start_y*sqrt_1_2;

  new_x := abs(new_x);
  new_y := abs(new_y);
  new_z := abs(new_z);

  temp_x := new_x*sqrt_1_2+new_y*sqrt_1_2;
  new_y := -new_x*sqrt_1_2+new_y*sqrt_1_2;
  new_x := temp_x*sqrt_2_3+new_z*sqrt_1_3;
  new_z := -temp_x*sqrt_1_3+new_z*sqrt_2_3;

  start_x:=scale*new_x-offset; //scale =2 offset=2
  start_y:=scale*new_y;
  start_z:=scale*new_z;

  x_temp:=start_x*start_x;
  y_temp:=start_y*start_y;
  z_temp:=start_z*start_z;
  temp:=2.0*start_x/sqrt(y_temp+z_temp);


  new_x:= x_temp - y_temp - z_temp;
  new_z:=temp*(y_temp-z_temp); //y and z variables are switched to add symmetry
  new_y:=temp*2.0*start_y*start_z;

  x := new_x + PIteration3D^.J1;
  y := new_y + PIteration3D^.J2;
  z := new_z + PIteration3D^.J3;

end;
[END]

Description:
...

To compare speed, I rendered the example you provided at 960x720 once with the ASM-formula, once with the on-the-fly compiled formula:

Hand-coded ASM: 14 seconds
On-the-fly compiled : 42 seconds

« Last Edit: October 23, 2015, 12:53:20 AM by thargor6 » Logged
lycium
Fractal Supremo
*****
Posts: 1158



WWW
« Reply #50 on: October 23, 2015, 02:26:48 AM »

Maybe it's failing to optimise those sqrt(1/3) etc. Could try replacing with the result, i.e. 0.57735026918962576450914878050196
Logged

thargor6
Fractal Molossus
**
Posts: 789



WWW
« Reply #51 on: October 23, 2015, 03:09:11 AM »

Maybe it's failing to optimise those sqrt(1/3) etc. Could try replacing with the result, i.e. 0.57735026918962576450914878050196
You are right, of course, thanks for the heads up!
When I use those constants, the render takes 28 seconds (compared to 14 seconds for handcoded ASM), probably there is some more room for improvement.

Cheers!
Logged
M Benesi
Fractal Schemer
****
Posts: 1075



WWW
« Reply #52 on: October 23, 2015, 04:16:58 AM »

Can we compare the binary (or hex) the compiler generates with the ASM hex/binary?


  and.. it's a bit off topic, but is there a way to select each formula you want to use for each iteration in M3D?

Iteration   Formula
1      Transform 1
2      Pine Tree_x only
3      Transform 1
4      Pine Tree
5      Transform 2
n...  ...
« Last Edit: October 23, 2015, 04:24:09 AM by M Benesi » Logged

lycium
Fractal Supremo
*****
Posts: 1158



WWW
« Reply #53 on: October 23, 2015, 04:59:55 AM »

I find it a bit odd that JIT compiled code is (so much!) slower than the normal static code.

As a point of comparison, Chaotica's new render engine (and all transforms) is written in our functional language Winter, and even doing CPU vs CPU comparisons (there is an OpenCL backend for GPUs) the MSVC compiled code gets spanked by LLVM-backed JIT code. This is largely because many things are known at render-time that are not at compile-time, but also because LLVM makes highly optimised code using the latest CPU extensions (such as AVX2, AVX-512) on CPUs which support it.
Logged

M Benesi
Fractal Schemer
****
Posts: 1075



WWW
« Reply #54 on: October 23, 2015, 07:13:55 AM »

Edit, I finally succeeded by translating the first non-trivial formula (your initial formula 1 +2), so that it runs on the experimental embedded formula compiler and leads to the same result.

cheesy

Ok, after doing Lycium's suggestion with the square roots, some questions.

Do you have to assign the variables every iteration?

Doesn't using fewer variables for the calculation mean fewer stack (memory) movements?  Does the compiler automatically eliminate extra variables?   Maybe test the code I make with fewer variables...

  Commenting/changing your code below.   Doing another revision below the following code because I'm not sure about your compiler- whether it's cool to use the x,y, and z variables as part of the iteration.  Second code eliminates more variables by using x,y, and z in the iteration.  SECOND CODE LOOKS BETTER>>>>... but the compiler might already streamline variables, ehh?  So... I don't know.  I can't test it.  I'd recommend second code if it works.
Code:
[OPTIONS]
.Version = 2
.DEscale = 1
.SIpower = 2
[SOURCE]
procedure BenesiPineTree(var x, y, z, w: Double; PIteration3D: TPIteration3D);
var
  scale, offset: Double;
  sqrt_1_2, sqrt_1_3, sqrt_2_3: Double;
 //     start_x, start_y, start_z: Double;   // eliminate these variables.....
//  temp_x, temp_y, temp_z, temp: Double;   // how about these too???  
  new_x, new_y, new_z: Double;
  x_temp, y_temp, z_temp, temp: Double;   //gotta add a new temp variable because we took out the others...

begin
  scale := 2.0;     // can you take all these variable assignments, and do them outside of the iteration???
  offset := 2.0;

  sqrt_1_2 := 0.7071067811865475;
  sqrt_1_3 :=  0.5773502691896258;
  sqrt_2_3 := 0.816496580927726;   // to here...

   //   start_x := x; start_y := y; start_z := z;

    //  can you eliminate the start_x, start_y, and start_z variables???

  x_temp := x*sqrt_2_3 - z*sqrt_1_3;
  new_z :=  x*sqrt_1_3 + z*sqrt_2_3;
  new_x := x_temp*sqrt_1_2-y*sqrt_1_2;
  new_y := x_temp*sqrt_1_2+y*sqrt_1_2;

  new_x := abs(new_x);
  new_y := abs(new_y);
  new_z := abs(new_z);

  x_temp := new_x*sqrt_1_2+new_y*sqrt_1_2;
  new_y := -new_x*sqrt_1_2+new_y*sqrt_1_2;
  new_x := x_temp*sqrt_2_3+new_z*sqrt_1_3;
  new_z := -x_temp*sqrt_1_3+new_z*sqrt_2_3;

  new_x:=scale*new_x-offset; //scale =2 offset=2
  new_y:=scale*new_y;
  new_z:=scale*new_z;

  x_temp:=new_x*new_x;
  y_temp:=new_y*new_y;
  z_temp:=new_z*new_z;
  temp:=2.0*new_x/sqrt(y_temp+z_temp);


  new_x:= x_temp - y_temp - z_temp;
  new_y:=temp*2.0*new_y*new_z;  //  put this above the next one, so I could eliminate variables....
  new_z:=temp*(y_temp-z_temp);   //math for y and z variables is switched from regular bulb formula to add symmetry
 
 x := new_x + PIteration3D^.J1;    // come on... don't add the next pixel components in.  come on... :D  :p   do what ya want.
y := new_y;                             // y := new_y + PIteration3D^.J2;
z := new_z;                           // z := new_z + PIteration3D^.J3;

end;
[END]

Description:
...

With x,y, and z used for variables...

Code:
[OPTIONS]
.Version = 2
.DEscale = 1
.SIpower = 2
[SOURCE]
procedure BenesiPineTree(var x, y, z, w: Double; PIteration3D: TPIteration3D);
var
  scale, offset: Double;
  sqrt_1_2, sqrt_1_3, sqrt_2_3: Double;
 //     start_x, start_y, start_z: Double;   // eliminate these variables.....
//  temp_x, temp_y, temp_z, temp: Double;   // how about these too???  
 // new_x, new_y, new_z: Double;    // for this one, these get eliminated too....
  x_temp, y_temp, z_temp, temp: Double;   //gotta add a new temp variable because we took out the others...

begin
  scale := 2.0;     // can you take all these variable assignments, and do them outside of the iteration???
  offset := 2.0;

  sqrt_1_2 := 0.7071067811865475;
  sqrt_1_3 :=  0.5773502691896258;
  sqrt_2_3 := 0.816496580927726;   //   up to here, if you can eliminate these variable assignments.. if it's necessary?

  
  x_temp := x*sqrt_2_3 - z*sqrt_1_3;
  z :=  x*sqrt_1_3 + z*sqrt_2_3;
  x := x_temp*sqrt_1_2-y*sqrt_1_2;
  y := x_temp*sqrt_1_2+y*sqrt_1_2;

  x := abs(x);   // can you do this above?  I don't know how tight the compiler is
  y := abs(y);   // so if it's moving the stack and registers around before it does these commands
  z := abs(z);   // it might be faster to do the abs()  command up above, instead of here

  x_temp := x*sqrt_1_2 + y*sqrt_1_2;
  y := -x*sqrt_1_2 + y*sqrt_1_2;
  x := x_temp*sqrt_2_3 + z*sqrt_1_3;
  z := -x_temp*sqrt_1_3 + z*sqrt_2_3;

  x:=scale*x-offset; //scale =2 offset=2
  y:=scale*y;
  z:=scale*z;

  x_temp:=x*x;
  y_temp:=y*y;
  z_temp:=z*z;
  temp:=2.0*x/sqrt(y_temp+z_temp);


  x:= x_temp - y_temp - z_temp + PIteration3D^.J1;   // moved the pixel component up here....
  y:=temp*2.0*y*z;  //    I didn't add in the y or z pixel components because... it is more awesome that way... @!@$!@$
  z:=temp*(y_temp-z_temp);   //math for y and z variables is switched from regular bulb formula to add symmetry
 
// x := new_x + PIteration3D^.J1;    // come on... don't add the next pixel components in.  come on... :D  :p   do what ya want.
// y := new_y;                             // y := new_y + PIteration3D^.J2;
// z := new_z;                           // z := new_z + PIteration3D^.J3;

end;
[END]

Description:
...
Logged

DarkBeam
Global Moderator
Fractal Senior
******
Posts: 2512


Fragments of the fractal -like the tip of it


« Reply #55 on: October 23, 2015, 10:08:01 AM »

My handcoded uses just one temp for the fold and three for the transform. I did other reductions and stuff. By the way. Can you try to enable SSE2? Jesse did many formulas with it and it could help smiley
I can surely predict that ppl will not use slow formulas, as all slow ones I did stay unused.
Logged

No sweat, guardian of wisdom!
lycium
Fractal Supremo
*****
Posts: 1158



WWW
« Reply #56 on: October 23, 2015, 10:44:13 AM »

Re-using variables is very bad for code readability/clarity, and doesn't result in fewer registers being used or anything like that.

Having to declare variables ahead of time is awful to read and to write, and gets in the way of making variables as locally scoped as possible and declared constant. Compilers make short work of functions which don't modify any global state and just do a bunch of arithmetic on const variables. Const const const const smiley
Logged

DarkBeam
Global Moderator
Fractal Senior
******
Posts: 2512


Fragments of the fractal -like the tip of it


« Reply #57 on: October 23, 2015, 12:17:58 PM »

An assembly formula is never readable nor reusable wink
Logged

No sweat, guardian of wisdom!
thargor6
Fractal Molossus
**
Posts: 789



WWW
« Reply #58 on: October 23, 2015, 12:30:02 PM »

Commenting/changing your code below.   Doing another revision below the following code because I'm not sure about your compiler...
Hi, thanks for the comment, but please note, that for me performance at this step of development was not important (except for those obvious things like precalculating constants), the main achievement was to make this formula to work at all... and getting the same result cheesy There was a lot of guessing involved, because there are so many versions of those formulas around and some of them use variables in a cryptic way, making it not clear, if it is a typo or intended (e.g. using tx and xt as temporary variables, and using them both ;-)). So, it was hard to guess, if the formula is wrong or the compiler did not work right (because there where also problems with compiler, e.g. when using code with a const-section it seems to overwrite internal stuff causing crashes or weird results).

A test-version will be available soon to people who are interested (no public release at the current state)


Best regards

Logged
DarkBeam
Global Moderator
Fractal Senior
******
Posts: 2512


Fragments of the fractal -like the tip of it


« Reply #59 on: October 23, 2015, 12:47:42 PM »

... (e.g. using tx and xt as temporary variables, and using them both ;-))...
Yes !! rolling on floor laughing crazy eyes
Logged

No sweat, guardian of wisdom!
Pages: 1 2 3 [4] 5 6 7   Go Down
  Print  
 
Jump to:  


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.229 seconds with 23 queries. (Pretty URLs adds 0.016s, 2q)