Home » Other » Community Hangout » Benoit Mandelbrot
Benoit Mandelbrot [message #479445] 
Sun, 17 October 2010 05:32 
John Watson
Messages: 8301 Registered: January 2010 Location: Global Village

Senior Member 


I hear on the news that Professor Mandelbrot died last week. If any of you are interested in mathematics or science history, this is important news.
I've just had a quick look at generating fractals in PL/SQL but I got nowhere, I can't see how to do it without using recursion. I found that you can write a recursive function (I didn't know that) but the level of recursion is very limited, I hit ora4030, ora6512, ora6500, and more.
There are some wonderful examples of fractal images on the net, just google "fractal", and enjoy.
[Updated on: Sun, 17 October 2010 05:33] Report message to a moderator



Re: Benoit Mandelbrot [message #479460 is a reply to message #479445] 
Sun, 17 October 2010 11:08 

Barbara Boehmer
Messages: 8922 Registered: November 2002 Location: California, USA

Senior Member 


I am sorry to hear that Professor Mandelbrot died. Fractals are fascinating and pretty stuff. I am intrigued by your attempts to create a recursive function to produce fractals. Please post what you tried. You can create recursive procedures, recursive functions, and recursive sql. In 11g, you can use the new recursive sql as shown below. I just learned about this new recursive sql from Michel Cadot in another post recently and am enjoying experimenting with it and it seems like it would be ideal for fractal generation.
SCOTT@orcl_11gR2> WITH julia (x, y, i, r) AS
2 (SELECT 2, 1,  starting coordinates
3 1, 1
4 FROM DUAL
5 UNION ALL
6 SELECT POWER (x, 2)  POWER (y, 2) + 1,
7 (2 * x * y) + i,
8 i,
9 r + 1
10 FROM julia
11 WHERE r < 3)  maximum iterations
12 SELECT x, y
13 FROM julia
14 ORDER BY r
15 /
X Y
 
2 1
4 5
8 41
3 rows selected.
SCOTT@orcl_11gR2>



Re: Benoit Mandelbrot [message #479461 is a reply to message #479460] 
Sun, 17 October 2010 11:27 

Barbara Boehmer
Messages: 8922 Registered: November 2002 Location: California, USA

Senior Member 


Apparently it doesn't take very many iterations to produce a numeric overflow as shown below. The documentation says to reduce the operands, so it must be nesting the operands in each of the recursions. Does anybody know of a workaround for that.
SCOTT@orcl_11gR2> WITH julia (x, y, i, r) AS
2 (SELECT 2, 1,  starting coordinates
3 1, 1
4 FROM DUAL
5 UNION ALL
6 SELECT POWER (x, 2)  POWER (y, 2) + 1,
7 (2 * x * y) + i,
8 i,
9 r + 1
10 FROM julia
11 WHERE r < 9)  maximum iterations
12 SELECT x, y
13 FROM julia
14 ORDER BY r
15 /
X Y
 
2 1
4 5
8 41
1616 655
2182432 2116961
2.8149E+11 9.2402E+12
8.530E+25 5.2020E+24
7.2495E+51 8.875E+50
5.177E+103 1.29E+103
9 rows selected.
SCOTT@orcl_11gR2> WITH julia (x, y, i, r) AS
2 (SELECT 2, 1,  starting coordinates
3 1, 1
4 FROM DUAL
5 UNION ALL
6 SELECT POWER (x, 2)  POWER (y, 2) + 1,
7 (2 * x * y) + i,
8 i,
9 r + 1
10 FROM julia
11 WHERE r < 10)  maximum iterations
12 SELECT x, y
13 FROM julia
14 ORDER BY r
15 /
SELECT POWER (x, 2)  POWER (y, 2) + 1,
*
ERROR at line 6:
ORA01426: numeric overflow
SCOTT@orcl_11gR2>



Re: Benoit Mandelbrot [message #479465 is a reply to message #479461] 
Sun, 17 October 2010 12:34 

Barbara Boehmer
Messages: 8922 Registered: November 2002 Location: California, USA

Senior Member 


I get the same problem, different error code with a recursive function:
SCOTT@orcl_11gR2> CREATE OR REPLACE TYPE fractal_typ AS OBJECT
2 (x NUMBER,
3 y NUMBER);
4 /
Type created.
SCOTT@orcl_11gR2> CREATE OR REPLACE FUNCTION julia
2 (p_fractal IN fractal_typ,
3 p_iterations IN NUMBER)
4 RETURN fractal_typ
5 AS
6 v_fractal fractal_typ := fractal_typ (NULL, NULL);
7 BEGIN
8 IF p_iterations > 1 THEN
9 v_fractal.x := POWER (p_fractal.x, 2)  POWER (p_fractal.y, 2) + 1;
10 v_fractal.y := (2 * p_fractal.x * p_fractal.y) + 1;
11 v_fractal := julia (v_fractal, p_iterations  1);
12 ELSE
13 v_fractal := p_fractal;
14 END IF;
15 RETURN v_fractal;
16 END julia;
17 /
Function created.
SCOTT@orcl_11gR2> SHOW ERRORS
No errors.
SCOTT@orcl_11gR2> SELECT t.fractal.x, t.fractal.y
2 FROM (SELECT julia (fractal_typ (2, 1), ROWNUM) fractal
3 FROM DUAL
4 CONNECT BY LEVEL <= 9) t
5 /
FRACTAL.X FRACTAL.Y
 
2 1
4 5
8 41
1616 655
2182432 2116961
2.8149E+11 9.2402E+12
8.530E+25 5.2020E+24
7.2495E+51 8.875E+50
5.177E+103 1.29E+103
9 rows selected.
SCOTT@orcl_11gR2> SELECT t.fractal.x, t.fractal.y
2 FROM (SELECT julia (fractal_typ (2, 1), ROWNUM) fractal
3 FROM DUAL
4 CONNECT BY LEVEL <= 10) t
5 /
ERROR:
ORA06502: PL/SQL: numeric or value error
ORA06512: at "SCOTT.JULIA", line 9
ORA06512: at "SCOTT.JULIA", line 11
ORA06512: at "SCOTT.JULIA", line 11
ORA06512: at "SCOTT.JULIA", line 11
ORA06512: at "SCOTT.JULIA", line 11
ORA06512: at "SCOTT.JULIA", line 11
ORA06512: at "SCOTT.JULIA", line 11
ORA06512: at "SCOTT.JULIA", line 11
ORA06512: at "SCOTT.JULIA", line 11
no rows selected
SCOTT@orcl_11gR2>



Re: Benoit Mandelbrot [message #479470 is a reply to message #479465] 
Sun, 17 October 2010 13:00 

Barbara Boehmer
Messages: 8922 Registered: November 2002 Location: California, USA

Senior Member 


I get the same problem with a procedure with a loop.
SCOTT@orcl_11gR2> CREATE TABLE fractals
2 (x NUMBER,
3 y NUMBER)
4 /
Table created.
SCOTT@orcl_11gR2> CREATE OR REPLACE PROCEDURE julia
2 (p_x IN NUMBER,
3 p_y IN NUMBER,
4 p_r IN NUMBER)
5 AS
6 v_x_old NUMBER := p_x;
7 v_y_old NUMBER := p_y;
8 v_x_new NUMBER;
9 v_y_new NUMBER;
10 BEGIN
11 DELETE FROM fractals;
12 FOR i IN 1 .. p_r LOOP
13 INSERT INTO fractals VALUES (v_x_old, v_y_old);
14 v_x_new := POWER (v_x_old, 2)  POWER (v_y_old, 2) + 1;
15 v_y_new := (2 * v_x_old * v_y_old) + 1;
16 v_x_old := v_x_new;
17 v_y_old := v_y_new;
18 END LOOP;
19 END julia;
20 /
Procedure created.
SCOTT@orcl_11gR2> SHOW ERRORS
No errors.
SCOTT@orcl_11gR2> EXEC julia (2, 1, 8)
PL/SQL procedure successfully completed.
SCOTT@orcl_11gR2> SELECT * FROM fractals
2 /
X Y
 
2 1
4 5
8 41
1616 655
2182432 2116961
2.8149E+11 9.2402E+12
8.530E+25 5.2020E+24
7.2495E+51 8.875E+50
8 rows selected.
SCOTT@orcl_11gR2> EXEC julia (2, 1, 9)
BEGIN julia (2, 1, 9); END;
*
ERROR at line 1:
ORA06502: PL/SQL: numeric or value error
ORA06512: at "SCOTT.JULIA", line 14
ORA06512: at line 1
SCOTT@orcl_11gR2>



Re: Benoit Mandelbrot [message #479471 is a reply to message #479470] 
Sun, 17 October 2010 13:11 

Barbara Boehmer
Messages: 8922 Registered: November 2002 Location: California, USA

Senior Member 


I still get an error with a procedure without any recursion. Apparently it has to do with trying to store too big of a number in the datatype.
SCOTT@orcl_11gR2> CREATE TABLE fractals
2 (x NUMBER,
3 y NUMBER,
4 r NUMBER)
5 /
Table created.
SCOTT@orcl_11gR2> CREATE OR REPLACE PROCEDURE julia
2 (p_x IN NUMBER,
3 p_y IN NUMBER,
4 p_r IN NUMBER)
5 AS
6 v_x_old NUMBER := p_x;
7 v_y_old NUMBER := p_y;
8 v_x_new NUMBER;
9 v_y_new NUMBER;
10 BEGIN
11 DELETE FROM fractals;
12 INSERT INTO fractals VALUES (p_x, p_y, 1);
13 FOR i IN 1 .. p_r LOOP
14 SELECT x, y
15 INTO v_x_old, v_x_new
16 FROM fractals
17 WHERE r = i;
18 v_x_new := POWER (v_x_old, 2)  POWER (v_y_old, 2) + 1;
19 v_y_new := (2 * v_x_old * v_y_old) + 1;
20 INSERT INTO fractals VALUES (v_x_new, v_y_new, i + 1);
21 END LOOP;
22 END julia;
23 /
Procedure created.
SCOTT@orcl_11gR2> SHOW ERRORS
No errors.
SCOTT@orcl_11gR2> EXEC julia (2, 1, 8)
PL/SQL procedure successfully completed.
SCOTT@orcl_11gR2> SELECT * FROM fractals
2 /
X Y R
  
2 1 1
4 5 2
16 9 3
256 33 4
65536 513 5
4294967296 131073 6
1.8447E+19 8589934593 7
3.4028E+38 3.6893E+19 8
1.1579E+77 6.8056E+38 9
9 rows selected.
SCOTT@orcl_11gR2> EXEC julia (2, 1, 9)
BEGIN julia (2, 1, 9); END;
*
ERROR at line 1:
ORA06502: PL/SQL: numeric or value error
ORA06512: at "SCOTT.JULIA", line 18
ORA06512: at line 1
SCOTT@orcl_11gR2>



Re: Benoit Mandelbrot [message #479472 is a reply to message #479471] 
Sun, 17 October 2010 13:23 

Barbara Boehmer
Messages: 8922 Registered: November 2002 Location: California, USA

Senior Member 


The binary_double datatype seems to allow a larger number.
SCOTT@orcl_11gR2> CREATE TABLE fractals
2 (x BINARY_DOUBLE,
3 y BINARY_DOUBLE,
4 r BINARY_DOUBLE)
5 /
Table created.
SCOTT@orcl_11gR2> CREATE OR REPLACE PROCEDURE julia
2 (p_x IN BINARY_DOUBLE,
3 p_y IN BINARY_DOUBLE,
4 p_r IN BINARY_DOUBLE)
5 AS
6 v_x_old BINARY_DOUBLE := p_x;
7 v_y_old BINARY_DOUBLE := p_y;
8 v_x_new BINARY_DOUBLE;
9 v_y_new BINARY_DOUBLE;
10 BEGIN
11 DELETE FROM fractals;
12 INSERT INTO fractals VALUES (p_x, p_y, 1);
13 FOR i IN 1 .. p_r LOOP
14 SELECT x, y
15 INTO v_x_old, v_x_new
16 FROM fractals
17 WHERE r = i;
18 v_x_new := POWER (v_x_old, 2)  POWER (v_y_old, 2) + 1;
19 v_y_new := (2 * v_x_old * v_y_old) + 1;
20 INSERT INTO fractals VALUES (v_x_new, v_y_new, i + 1);
21 END LOOP;
22 END julia;
23 /
Procedure created.
SCOTT@orcl_11gR2> SHOW ERRORS
No errors.
SCOTT@orcl_11gR2> EXEC julia (2, 1, 20)
PL/SQL procedure successfully completed.
SCOTT@orcl_11gR2> SELECT * FROM fractals
2 /
X Y R
  
2.0E+000 1.0E+000 1.0E+000
4.0E+000 5.0E+000 2.0E+000
1.6E+001 9.0E+000 3.0E+000
2.56E+002 3.3E+001 4.0E+000
6.554E+004 5.13E+002 5.0E+000
4.295E+009 1.311E+005 6.0E+000
1.845E+019 8.59E+009 7.0E+000
3.403E+038 3.689E+019 8.0E+000
1.158E+077 6.806E+038 9.0E+000
1.341E+154 2.316E+077 1.0E+001
Inf 2.682E+154 1.1E+001
Inf Inf 1.2E+001
Inf Inf 1.3E+001
Inf Inf 1.4E+001
Inf Inf 1.5E+001
Inf Inf 1.6E+001
Inf Inf 1.7E+001
Inf Inf 1.8E+001
Inf Inf 1.9E+001
Inf Inf 2.0E+001
Inf Inf 2.1E+001
21 rows selected.
SCOTT@orcl_11gR2>



Re: Benoit Mandelbrot [message #479473 is a reply to message #479472] 
Sun, 17 October 2010 13:29 

Barbara Boehmer
Messages: 8922 Registered: November 2002 Location: California, USA

Senior Member 


Here is the original recursive query and recursive function with binary_double. I am starting to feel like I am talking to myself. I am hoping that somebody will jump in with something.
SCOTT@orcl_11gR2> WITH julia (x, y, i, r) AS
2 (SELECT 2, 1,  starting coordinates
3 1, 1
4 FROM DUAL
5 UNION ALL
6 SELECT CAST (POWER (x, 2)  POWER (y, 2) + 1 AS BINARY_DOUBLE),
7 CAST ((2 * x * y) + i AS BINARY_DOUBLE),
8 i,
9 r + 1
10 FROM julia
11 WHERE r < 20)  maximum iterations
12 SELECT x, y
13 FROM julia
14 ORDER BY r
15 /
X Y
 
2.0E+000 1.0E+000
4.0E+000 5.0E+000
8.0E+000 4.1E+001
1.62E+003 6.55E+002
2.182E+006 2.117E+006
2.815E+011 9.24E+012
8.53E+025 5.202E+024
7.25E+051 8.87E+050
5.177E+103 1.29E+103
2.514E+207 1.33E+207
Nan Inf
Nan Nan
Nan Nan
Nan Nan
Nan Nan
Nan Nan
Nan Nan
Nan Nan
Nan Nan
Nan Nan
20 rows selected.
SCOTT@orcl_11gR2>
SCOTT@orcl_11gR2> CREATE OR REPLACE TYPE fractal_typ AS OBJECT
2 (x BINARY_DOUBLE,
3 y BINARY_DOUBLE);
4 /
Type created.
SCOTT@orcl_11gR2> CREATE OR REPLACE FUNCTION julia
2 (p_fractal IN fractal_typ,
3 p_iterations IN BINARY_DOUBLE)
4 RETURN fractal_typ
5 AS
6 v_fractal fractal_typ := fractal_typ (NULL, NULL);
7 BEGIN
8 IF p_iterations > 1 THEN
9 v_fractal.x := POWER (p_fractal.x, 2)  POWER (p_fractal.y, 2) + 1;
10 v_fractal.y := (2 * p_fractal.x * p_fractal.y) + 1;
11 v_fractal := julia (v_fractal, p_iterations  1);
12 ELSE
13 v_fractal := p_fractal;
14 END IF;
15 RETURN v_fractal;
16 END julia;
17 /
Function created.
SCOTT@orcl_11gR2> SHOW ERRORS
No errors.
SCOTT@orcl_11gR2> SELECT t.fractal.x, t.fractal.y
2 FROM (SELECT julia (fractal_typ (2, 1), ROWNUM) fractal
3 FROM DUAL
4 CONNECT BY LEVEL <= 20) t
5 /
FRACTAL.X FRACTAL.Y
 
2.0E+000 1.0E+000
4.0E+000 5.0E+000
8.0E+000 4.1E+001
1.62E+003 6.55E+002
2.182E+006 2.117E+006
2.815E+011 9.24E+012
8.53E+025 5.202E+024
7.25E+051 8.87E+050
5.177E+103 1.29E+103
2.514E+207 1.33E+207
Nan Inf
Nan Nan
Nan Nan
Nan Nan
Nan Nan
Nan Nan
Nan Nan
Nan Nan
Nan Nan
Nan Nan
20 rows selected.
SCOTT@orcl_11gR2>



Re: Benoit Mandelbrot [message #479488 is a reply to message #479473] 
Mon, 18 October 2010 00:49 
rleishman
Messages: 3728 Registered: October 2005 Location: Melbourne, Australia

Senior Member 


Takes me back to my Uni days. We had a sadistic lecturer who gave a us a simple treetraversal assignment, but insisted we use FORTRAN to code it. For the younguns out there, FORTRAN is a language that does NOT support recursion.
The sadistic bit was that he didn't specify that the whole point of the exercise was NOT to solve the specified requirement, but to ensure that we learned how higher generation procedural languages implement recursion. Some people spent inordinate amounts of time trying to get FORTRAN trying to do recursion out of the box, whereas all the lecturer wanted was a stack and a loop.



Re: Benoit Mandelbrot [message #479706 is a reply to message #479488] 
Mon, 18 October 2010 15:05 
John Watson
Messages: 8301 Registered: January 2010 Location: Global Village

Senior Member 


Wow! Thank you, BB  your code certainly gave me something to think about. I'm not posting anything, my efforts are shameful in comparison. I think the stackandloop approach has to be the way to go: we have a database, so use it and the stack can have infinite height.
But it doesn't take long before you reach the limits of the internal data types. Possibly the solution would involve representing a number with a scale/precision of a zillion by loading digits into an array of a zillion cells. I remember writing code to do that in Pascal (or was it C?)
And here's an odd thing to sign off with. I was looking at algorithms for generating pi. Some are breath taking in their simplicity. But the oddest is the BaileyBorweinPlouffe formula, which can generate the umpteenth digit of pi WITHOUT generating the digits before it. I can't get my head around that one.



Goto Forum:
Current Time: Thu Jul 16 00:09:28 CDT 2020
