Home » Other » Community Hangout » Benoit Mandelbrot
Benoit Mandelbrot [message #479445] Sun, 17 October 2010 05:32 Go to next message
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 ora-4030, ora-6512, ora-6500, 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 Go to previous messageGo to next message
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 Go to previous messageGo to next message
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:
ORA-01426: numeric overflow


SCOTT@orcl_11gR2>





Re: Benoit Mandelbrot [message #479465 is a reply to message #479461] Sun, 17 October 2010 12:34 Go to previous messageGo to next message
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:
ORA-06502: PL/SQL: numeric or value error
ORA-06512: at "SCOTT.JULIA", line 9
ORA-06512: at "SCOTT.JULIA", line 11
ORA-06512: at "SCOTT.JULIA", line 11
ORA-06512: at "SCOTT.JULIA", line 11
ORA-06512: at "SCOTT.JULIA", line 11
ORA-06512: at "SCOTT.JULIA", line 11
ORA-06512: at "SCOTT.JULIA", line 11
ORA-06512: at "SCOTT.JULIA", line 11
ORA-06512: 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 Go to previous messageGo to next message
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:
ORA-06502: PL/SQL: numeric or value error
ORA-06512: at "SCOTT.JULIA", line 14
ORA-06512: at line 1


SCOTT@orcl_11gR2>

Re: Benoit Mandelbrot [message #479471 is a reply to message #479470] Sun, 17 October 2010 13:11 Go to previous messageGo to next message
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:
ORA-06502: PL/SQL: numeric or value error
ORA-06512: at "SCOTT.JULIA", line 18
ORA-06512: at line 1


SCOTT@orcl_11gR2>

Re: Benoit Mandelbrot [message #479472 is a reply to message #479471] Sun, 17 October 2010 13:23 Go to previous messageGo to next message
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 Go to previous messageGo to next message
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 Go to previous messageGo to next message
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 tree-traversal assignment, but insisted we use FORTRAN to code it. For the young-uns 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 Go to previous message
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 stack-and-loop 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 Bailey-Borwein-Plouffe formula, which can generate the umpteenth digit of pi WITHOUT generating the digits before it. I can't get my head around that one.
Previous Topic: square pegs in round holes
Next Topic: HrOUG
Goto Forum:
  


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