Mandelbrot mishaps

In the thread RC2014. A retro Cray? we see a distorted Mandelbrot:

I’ve seen that before, and was able to figure out what had gone wrong:
http://forum.6502.org/viewtopic.php?p=65574#p65574

3 Likes

I wish I could replicate an error that I made around age 16 when coding Mandelbrot: I made some error in expanding the formula, and the resulting fractal was wild: no more symmetric at all, but whirling spiky knots. Probably somewhat more like Julia sets. Lost the code years ago, sadly.

1 Like

We can has mandelbrot mishaps thread plz?

I once had a mishap in my fixedpoint maths and that fed a strange “noise” into the calculation.


Edit@20200720-1735-UTC: The output of the corrected program.

As if by magic, we’ve transported to just such a thing. When @hoglet and I were working on his fork of DSPFract, which uses a Beeb-attached FPGA board to implement a Mandelmachine, we had some difficulty fine-tuning the hardware-optimised multiplications. We ended up with some empirical settings which I never quite got to grips with on a theoretical level. (It turns out that complex multiplication needs fewer multiplies than you’d think, and that squaring can be cheaper than general multiplication, and that you can make a 35 bit engine using slightly fewer 18x18 hardware multipliers if you synthesise some assistance logic. But there were some artefacts at extreme zoom which didn’t look right.)

1 Like

I once thought I had introduced some artefacts at extreme zoom level, but it turned out to be just the precision barrier (of the IEEE 754 standard). :slight_smile:


(Compare: <Now Go Bang!> Binary Grain - Chasing the Hare in the Mandelbrot Set)

3 Likes

I had a feel-good moment the other day, when I saw this:
Spikey not-quite-Mandelbrot fractal image on bright colourful LED display screen with homebrew electronics on the desk next to it.

and immediately recognised it as our familiar not-quite-Mandelbrot. So I could recommend the two-line fix (to workaround the aliasing of long variable names treated as two-character names), and the result was posted shortly after, with the caption

Thank you. Yes, changing the ZR2 to ZT so it doesn’t clash with ZREAL worked just right. Looked great before, but so much better now

image

2 Likes

So the ‘bug’ is more about running manky old Microsoft interpreters than anything else?

This would never have happened under PDP-8 BASIC. Not because it’s better, but its compiler immediately keels over with a terse error message (line number plus two character error code) if it sees a variable with a name other than two characters matching /[A-Z][0-9]?/ (so A and A1 are fine, but AA is right out) . In common with many pre-micro BASICs, it also only supports IF «condition» GOTO «line number». It makes for some extremely tangled code. Naturally, I love it.

2 Likes

Yes, the flexibility of allowing long variable names while only have the first part significant is a bit of a misfeature in my view. (Did any other languages do this? I bet they did.)

There’s another not-quite-a-mandelbrot in this Computerphile video.

2 Likes

It was that fault that inspired me to fix and publish my text based Mandelbrot program as a sort of BASIC benchmark. I wrote the program so that it would work in all the BASICs I had access to at the time (hence one statement per line) - Applesoft and other “generic” 6502 Microsoft BASICs as well as 8080 MS BASICs, BBC Basic and a few others.

Code is here:

https://unicorn.drogon.net/mandel.bas

with expected output:

https://unicorn.drogon.net/mandel.txt

Is it a good benchmark? Probably not really, but it does highlight floating point arithmetic speeds over the BASICs I tried (tl;dr BBC Basic 4 faster than other BBC Basics on the 6502 and faster than BBC Basic on Z80 - almost 2x faster than MS Basics - for the same clock speeds).

-Gordon

3 Likes

Several Forths from the 1970s would use 32 bits to store the names in their dictionary: one byte with the length of the name followed by the first three characters. Only names longer than three characters with the exact same length and initial characters would cause confusion and this was considered to be rare enough to not matter.

2 Likes

Thanks, Gordon: that’s nicely structured and will run almost anywhere. It is really giving basic floating point arithmetic a workout. It does take rather a long time to run, and really works best on a big terminal or 80-column printer.

The similar benchmark used by the mostly CP/M (80 and 68K) crowd over on Retrobrew Computing is known as asciiart.bas. It’s likely as portable, but not as well structured:

10 FOR Y=-12 TO 12
20 FOR X=-39 TO 39
30 CA=X*0.0458
40 CB= Y*0.08333
50 A=CA
60 B=CB
70 FOR I=0 TO 15
80 T=A*A-B*B+CA
90 B=2*A*B+CB
100 A=T
110 IF (A*A+B*B)>4 THEN GOTO 200
120 NEXT I
130 PRINT " ";
140 GOTO 210
200 IF I>9 THEN I=I+7
205 PRINT CHR$(48+I);
210 NEXT X
220 PRINT
230 NEXT Y

Output:

000001111111111111111122222222333557BF75433222211111000000000000000000000000000
000111111111111111112222222233445C      643332222111110000000000000000000000000
011111111111111111222222233444556C      654433332211111100000000000000000000000
11111111111111112222233346 D978 BCF    DF9 6556F4221111110000000000000000000000
111111111111122223333334469                 D   6322111111000000000000000000000
1111111111222333333334457DB                    85332111111100000000000000000000
11111122234B744444455556A                      96532211111110000000000000000000
122222233347BAA7AB776679                         A32211111110000000000000000000
2222233334567        9A                         A532221111111000000000000000000
222333346679                                    9432221111111000000000000000000
234445568  F                                   B5432221111111000000000000000000
                                              864332221111111000000000000000000
234445568  F                                   B5432221111111000000000000000000
222333346679                                    9432221111111000000000000000000
2222233334567        9A                         A532221111111000000000000000000
122222233347BAA7AB776679                         A32211111110000000000000000000
11111122234B744444455556A                      96532211111110000000000000000000
1111111111222333333334457DB                    85332111111100000000000000000000
111111111111122223333334469                 D   6322111111000000000000000000000
11111111111111112222233346 D978 BCF    DF9 6556F4221111110000000000000000000000
011111111111111111222222233444556C      654433332211111100000000000000000000000
000111111111111111112222222233445C      643332222111110000000000000000000000000
000001111111111111111122222222333557BF75433222211111000000000000000000000000000
000000011111111111111111122222233347E7AB322222111100000000000000000000000000000

Every BASIC Mandelbrot (or Brooks-Matelski, if you want to be a bit of a hipster) program suffers from the languages lack of complex variables. FORTRAN makes the core of the computation much more readable:

 ...
            DO 100, K=1,MAXIT
               Z = Z**2 + C
               IF (ABS(Z) .GT. 2) THEN
 ...
3 Likes

About that - just stumbled on a stackexchange Q&A where Matelsky himself confirms the parameters on the original image:

(It seems this paper was written before Mandelbrot’s and was available in preprint, even though it was published after.)

Here are the original parameters, according to JPM:

I can confirm that the programming constants used were indeed Δ𝑥=.035, Δy=1.66∗Δx. The grid center is (−.75,0)(−.75,0) which is a boundary point by the way: it is exactly represented in floating point. The original iteration cap was 250.

Note: the UNIVAC mainframe had 36 bit single and 72 bit double precision. Of course, I ran both varieties. The modern choices are 32, 64, or 80 bit. Using 32 bit is problematic.

via

3 Likes

yes, note the name of the commenter in the MetaFilter via … I have been known to be self-similar on different platforms

2 Likes