Logo by S Nelson - 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: Follow us on Twitter
 
*
Welcome, Guest. Please login or register. August 23, 2019, 12:23:04 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: Experimental MB3D-version with integrated formula-compiler (JIT)  (Read 4534 times)
0 Members and 1 Guest are viewing this topic.
thargor6
Fractal Molossus
**
Posts: 789



WWW
« Reply #30 on: December 15, 2015, 01:13:16 PM »

How to get this editor running ? I can't find it.
Is not released as binary yet, currently working on improving the performance before releasing it
Logged
knighty
Fractal Iambus
***
Posts: 819


« Reply #31 on: December 15, 2015, 01:38:20 PM »

Maybe it's possible to hide parameters and constants access inside the body of the formula and avoid the user to make mistakes:
the user could define the parametrs and constants before the procedure:
Parameter double scale = 2;
Parameter double offset = 2;
Constant double sqrt_2 = 1.41....;
... etc.
then the procedure is modified to add access to those paremeters and constants before it is sent to the JIT compiler.

Just my 2cts.

Great job thargor6!
Repeating Zooming Self-Silimilar Thumb Up, by Craig
Logged
thargor6
Fractal Molossus
**
Posts: 789



WWW
« Reply #32 on: December 15, 2015, 03:09:19 PM »

Maybe it's possible to hide parameters and constants access inside the body of the formula and avoid the user to make mistakes:
Hi, thanks for your ideas! I was also thinking about a way to simplify this, but it is not easy whithout actually putting some "magic" into the code (which I dislike).
The problem is, that the actual parameters at runtime are "fed" by MB3D's interface. So, the values of 2.0 for scale and offset in this example are only the initial values, but can be changed by the user.

Best regards,
Andreas
Logged
knighty
Fractal Iambus
***
Posts: 819


« Reply #33 on: December 15, 2015, 04:08:56 PM »

Well... this is not exactly what I was suggesting.
Taking for example the BenesiPineTree formula. The user could write:
Code:
Parameter double scale=2; { the =2 is just to say it's the default value}
Parameter double offset=2;
Constant double sqrt_1_2=sqrt(0.5);
Constant double sqrt_1_3=sqrt(1./3.);
Constant double sqrt_2_3=sqrt(2./3.);
procedure BenesiPineTree(var x,y,z,w :double; PIteration3D : TPIteration3D);
var
   start_x, start_y, start_z : double;
   ... etc.
begin
   start_x = x; start_y = y; start_z = z;
   ...etc.
end

A preprocessor could detect the code preceding the procedure and parse it. Then transform the user code to something like:
Code:
procedure BenesiPineTree(var x,y,z,w :double; PIteration3D : TPIteration3D);
var
{added by preprocessor}
   scale, offset : double;
   sqrt_1_2, sqrt_1_3, sqrt_2_3 : double;
{/added by preprocessor}
   start_x, start_y, start_z : double;
   ... etc.
begin
{added by preprocessor}
   sqrt_1_2 = PDouble(Integer(PIteration3D^.PVar) + 0)^;
   sqrt_1_3 = PDouble(Integer(PIteration3D^.PVar) + 8)^;
   sqrt_1_2 = PDouble(Integer(PIteration3D^.PVar) + 16)^;

   offset = PDouble(Integer(PIteration3D^.PVar) - 16)^;
   scale = PDouble(Integer(PIteration3D^.PVar) - 24)^;
{/added by preprocessor}

   start_x = x; start_y = y; start_z = z;
   ...etc.
end

That is after computing the constants, computing the offsets wrt PIteration3D^.PVar and updating other sections of the formula accordingly.

Logged
thargor6
Fractal Molossus
**
Posts: 789



WWW
« Reply #34 on: December 15, 2015, 05:05:24 PM »

Well... this is not exactly what I was suggesting.
Thanks again, but what I meant was that this is somewhat "magic" (=not good code), because you had to violate the DRY-principle. In order to have the params to appear in the UI, you have to put them also in the parameter section of the file (together with the default value). Which would be no problem here, but in the constants-section you can't have names.

So we would have to mix it (i. e., your suggestion, but only for constants).

To be clean, we had to change the file format, which is probably a good option.

I.E.:
- Programmatically put also named constants in the file
- Preprocess the named constants and the named parameters in the way suggested. i. e. generate the code-fragment to define and initialize them

What do you think?

Logged
knighty
Fractal Iambus
***
Posts: 819


« Reply #35 on: December 16, 2015, 11:47:40 AM »

IIUC, yes.
But wait!... the JIT can handle constants, right? in this case there is no need to manage them at all. smiley

IMHO, ".Version" could be used to prevent the use of the formula in older versions of MB3D. A clause like ".JIT PaxCompiler" or ".Language ObjectPascal" could also be added to the file format... maybe in the future MB3D could support other JIT compilers... Why not.

In order to be "clean" the parameters could still be defined in the [OPTIONS] sections while adding the in-procedure name (and other stuff):
Code:
.Double Offset 1 = 0 {InProcName = Offset_1} {Comment = Use it to change the shape! is it clear?}

There is another opportunity: Hidden parameters that are initialized using the visible ones. For example: getting a rotation matrix from euler angles...
Another one: The possiblity to modify some parameters values. For example: barycentric coodinates that should sum to 1...
These could be handled by another procedure in another section [INIT].

These are not feature request, only suggestions. There is a long and hard way between the idea and it's implementation. So R.E.S.P.E.C.T.
Logged
thargor6
Fractal Molossus
**
Posts: 789



WWW
« Reply #36 on: December 17, 2015, 12:29:22 AM »

In order to be "clean" the parameters could still be defined in the [OPTIONS] sections while adding the in-procedure name (and other stuff):
Hi again, I think I have found a very good compromise of all the options discussed, you are most welcome to have an early look at the binary (I will send you a link).


I have extended the file-format to support also named constants. One may use named constants in ASM-formulas as well, even when those names will never be refered from code later.
Those named constants are supported by the JIT-editor, and now, there is a preprocessor which fills in the the nasty code to read those values.
What makes this solution sexy is, that there was nearly no change necessary to the MB3D-core.

Example of the final (preprocessed) code (again, the Benesi-tree cheesy):
Code:
procedure BenesiPineTree(var x, y, z, w: Double; PIteration3D: TPIteration3D);
var
  // begin preprocessor
  sqrt_1_2: Double;
  sqrt_1_3: Double;
  sqrt_2_3: Double;
  Offset: Double;
  Scale: Double;
  // end preprocessor
  temp_x, temp_y, temp_z, temp: Double;  
  new_x, new_y, new_z: Double;
  x_temp, y_temp, z_temp: Double;
begin
  // begin preprocessor
  sqrt_1_2 := PDouble(Integer(PIteration3D^.PVar) + 0)^;
  sqrt_1_3 := PDouble(Integer(PIteration3D^.PVar) + 8)^;
  sqrt_2_3 := PDouble(Integer(PIteration3D^.PVar) + 16)^;
  Offset := PDouble(Integer(PIteration3D^.PVar) - 16)^;
  Scale := PDouble(Integer(PIteration3D^.PVar) - 24)^;
  // end preprocessor
  temp_x := x*sqrt_2_3-z*sqrt_1_3;
  new_z := x*sqrt_1_3 + z*sqrt_2_3;
  new_x := (temp_x-y)*sqrt_1_2;
  new_y := (temp_x+y)*sqrt_1_2;

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

  temp_x := (new_x+new_y)*sqrt_1_2;
  new_y := (-new_x+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;

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

  x_temp:=x*x;
  y_temp:=y*y;
  z_temp:=z*z;
  temp:=(x+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*y*z;

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

The *.m3f-file also looks sexy, there are no redundancies in code/definitions:
Code:
[OPTIONS]
.DEScale = 1
.SIPow = 2
.Version = 9
.Double Offset = 2
.Double Scale = 2
[CONSTANTS]
.Double sqrt_1_2 = 0.707106781186548
.Double sqrt_1_3 = 0.577350269189626
.Double sqrt_2_3 = 0.816496580927726
[SOURCE]
procedure BenesiPineTree(var x, y, z, w: Double; PIteration3D: TPIteration3D);
var
  temp_x, temp_y, temp_z, temp: Double;  
  new_x, new_y, new_z: Double;
  x_temp, y_temp, z_temp: Double;
begin
  temp_x := x*sqrt_2_3-z*sqrt_1_3;
  new_z := x*sqrt_1_3 + z*sqrt_2_3;
  new_x := (temp_x-y)*sqrt_1_2;
  new_y := (temp_x+y)*sqrt_1_2;

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

  temp_x := (new_x+new_y)*sqrt_1_2;
  new_y := (-new_x+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;

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

  x_temp:=x*x;
  y_temp:=y*y;
  z_temp:=z*z;
  temp:=(x+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*y*z;

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

[END]
Description:


Logged
knighty
Fractal Iambus
***
Posts: 819


« Reply #37 on: December 17, 2015, 01:50:24 PM »

 the wave
That's perfect!

Does Pax compiler support inline assembler? it seem that the answer is no.
Logged
chunkygravy
Alien
***
Posts: 22


« Reply #38 on: December 17, 2015, 05:03:43 PM »

excellent work.  i can mostly understand this, much better than the hard coded se.
i would love to see this develop into something similar to fractint which allowed you to write your own formulas in a simple text file that required no compiling or spooky code.

Mandelbrot(XAXIS) {; Mark Peterson
  ; Classical fractal showing LastSqr speedup
  z = Pixel, z = Sqr(z):  ; Start with z**2 to initialize LastSqr
   z = z + Pixel
   z = Sqr(z)
    LastSqr <= 4     ; Use LastSqr instead of recalculating
  }
Logged
chunkygravy
Alien
***
Posts: 22


« Reply #39 on: January 22, 2016, 05:46:06 AM »

ok so i expanded the trig example that came with the update.
I have 32 functions implimentable on X, Y, and Z.  Each axis can have a different function.
Must be used as a pretransform. (repeat from here after this formula)

I also want to make it where you can turn off the functions and have it not affect the render.
I set abc to 0 but it still affects the render.  how do i make a pass through like x:=x  ?

Code:
procedure BenesiPineTree(var x, y, z, w: Double; PIteration3D: TPIteration3D);
begin
if a=1 then x:= int(x*Scale);
if b=1 then y:= int(y*Scale);
if c=1 then z:= int(z*Scale);
if a=2 then x:= frac(x*Scale);
if b=2 then y:= frac(y*Scale);
if c=2 then z:= frac(z*Scale);
if a=3 then x:= exp(x*Scale);
if b=3 then y:= exp(y*Scale);
if c=3 then z:= exp(z*Scale);
if a=4 then x:= cos(x*Scale);
if b=4 then y:= Cos(y*Scale);
if c=4 then z:= Cos(z*Scale);
if a=5 then x:= sin(x*Scale);
if b=5 then y:= sin(y*Scale);
if c=5 then z:= sin(z*Scale);
if a=6 then x:= ln(x*Scale);
if b=6 then y:= ln(y*Scale);
if c=6 then z:= ln(z*Scale);
if a=7 then x:= arctan(x*Scale);
if b=7 then y:= arctan(y*Scale);
if c=7 then z:= arctan(z*Scale);
if a=8 then x:= sqrt(x*Scale);
if b=8 then y:= sqrt(y*Scale);
if c=8 then z:= sqrt(z*Scale);
if a=9 then x:= arccos(x*Scale);
if b=9 then y:= arccos(y*Scale);
if c=9 then z:= arccos(z*Scale);
if a=10 then x:= arcsin(x*Scale);
if b=10 then y:= arcsin(y*Scale);
if c=10 then z:= arcsin(z*Scale);
if a=11 then x:= tan(x*Scale);
if b=11 then y:= tan(y*Scale);
if c=11 then z:= tan(z*Scale);
if a=12 then x:= cotan(x*Scale);
if b=12 then y:= cotan(y*Scale);
if c=12 then z:= cotan(z*Scale);
if a=13 then x:= secant(x*Scale);
if b=13 then y:= secant(y*Scale);
if c=13 then z:= secant(z*Scale);
if a=14 then x:= cosecant(x*Scale);
if b=14 then y:= cosecant(y*Scale);
if c=14 then z:= cosecant(z*Scale);
//if a=15 then x:= hypot(x*Scale);
//if b=15 then y:= hypot(y*Scale);
//if c=15 then z:= hypot(z*Scale);

if a=15 then x:= cot(x*Scale);
if b=15 then y:= cot(y*Scale);
if c=15 then z:= cot(z*Scale);
if a=16 then x:= sec(x*Scale);
if b=16 then y:= sec(y*Scale);
if c=16 then z:= sec(z*Scale);
if a=17 then x:= csc(x*Scale);
if b=17 then y:= csc(y*Scale);
if c=17 then z:= csc(z*Scale);
if a=18 then x:= cosh(x*Scale);
if b=18 then y:= cosh(y*Scale);
if c=18 then z:= cosh(z*Scale);
if a=19 then x:= sinh(x*Scale);
if b=19 then y:= sinh(y*Scale);
if c=19 then z:= sinh(z*Scale);
if a=20 then x:= tanh(x*Scale);
if b=20 then y:= tanh(y*Scale);
if c=20 then z:= tanh(z*Scale);
if a=21 then x:= coth(x*Scale);
if b=21 then y:= coth(y*Scale);
if c=21 then z:= coth(z*Scale);
if a=22 then x:= sech(x*Scale);
if b=22 then y:= sech(y*Scale);
if c=22 then z:= sech(z*Scale);
if a=23 then x:= csch(x*Scale);
if b=23 then y:= csch(y*Scale);
if c=23 then z:= csch(z*Scale);
if a=24 then x:= arccot(x*Scale);
if b=24 then y:= arccot(y*Scale);
if c=24 then z:= arccot(z*Scale);
if a=25 then x:= arcsec(x*Scale);
if b=25 then y:= arcsec(y*Scale);
if c=25 then z:= arcsec(z*Scale);
if a=26 then x:= arccsc(x*Scale);
if b=26 then y:= arccsc(y*Scale);
if c=26 then z:= arccsc(z*Scale);
if a=27 then x:= arccosh(x*Scale);
if b=27 then y:= arccosh(y*Scale);
if c=27 then z:= arccosh(z*Scale);
if a=28 then x:= arcsinh(x*Scale);
if b=28 then y:= arcsinh(y*Scale);
if c=28 then z:= arcsinh(z*Scale);
if a=29 then x:= arctanh(x*Scale);
if b=29 then y:= arctanh(y*Scale);
if c=29 then z:= arctanh(z*Scale);
if a=30 then x:= arccoth(x*Scale);
if b=30 then y:= arccoth(y*Scale);
if c=30 then z:= arccoth(z*Scale);
if a=31 then x:= arcsech(x*Scale);
if b=31 then y:= arcsech(y*Scale);
if c=31 then z:= arcsech(z*Scale);
if a=32 then x:= arccsch(x*Scale);
if b=32 then y:= arccsch(y*Scale);
if c=32 then z:= arccsch(z*Scale);

//if d=1 then let x:=(x*scale)
//if e=1 then let y:=(y*scale)
//if f=1 then let z:=(z*scale)

end;




Logged
thargor6
Fractal Molossus
**
Posts: 789



WWW
« Reply #40 on: January 22, 2016, 12:18:40 PM »

If you do not actually change x (either by not writing it at all or using x := x), it should not affect the render.
If it does, it may be a bug, but sounds strange.
Logged
Pages: 1 2 [3]   Go Down
  Print  
 
Jump to:  

Related Topics
Subject Started by Replies Views Last post
how to sert up most recent mb3d version ??! Mandelbulb 3d cKleinhuis 4 373 Last post July 15, 2012, 09:55:02 PM
by lenord
writing a mb3d formula (*directly* in Assembly) Tutorials « 1 2 » M Benesi 15 1963 Last post October 21, 2015, 11:34:49 PM
by M Benesi
Test: experimental MB3D(JIT) Mandelbulb3D Gallery cyseal 1 532 Last post January 28, 2016, 03:08:58 AM
by Snicker02
Mandelbulb3d experimental version with 8 formula slots Releases thargor6 0 1534 Last post July 02, 2016, 10:58:56 PM
by thargor6
MB3D version with 8 formulas Help & Support erabyterum 2 707 Last post December 08, 2017, 05:23:37 PM
by Spain2points

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.169 seconds with 29 queries. (Pretty URLs adds 0.013s, 2q)