* * * * *
About those eight seconds, part II: mea culpa
The images presented in the previous two [1] posts [2] have been mostly
reconstructions. The only piece of software I have from that project twenty-
some years ago is the piece that drew the chaotic attractors [3], and that
was specific to the SGI [4] and had to be rewritten (extensively) for a
modern system.
The other program—the one that generated the maps? I have no clue as to where
that code went. Or rather, why I neglected to keep a copy of it. So I had to
basically recreate that program from scratch. The original reconstruction
started out as:
> int mainloop(const double A,const double B,const double C,const double D)
> {
> double xn,xn1;
> double yn,yn1;
> int ix;
> int iy;
> int count;
> bool pix[DIM][DIM];
>
> memset(pix,0,sizeof(pix));
>
> for (count = 0 , xn = yn = 0.5 ; count < MAXLOOP ; count++)
> {
> xn1 = ((A * yn) + B) * xn * (1.0 - xn);
> yn1 = ((C * xn) + D) * yn * (1.0 - yn);
> xn = xn1;
> yn = yn1;
>
>
But since I was setting memory and not plotting points, I needed to be very
careful about the values of xn and yn. I remembered that the values needed to
be between 0 and 1, so attempt one I had:
> assert(xn >= 0.0);
> assert(xn < 1.0);
> assert(yn >= 0.0);
> assert(yn < 1.0);
>
But those assumptions were proven false rather quickly. Attempt two I decided
to print the values of xn and yn and as it happened, very quickly (like on
the first pass) the values hit +inf. I interpreted that to mean I could bail
early, and thus finished the reconstruction with attempt three:
> if (xn < 0.0) return MAXLOOP;
> if (xn >= 1.0) return MAXLOOP;
> if (yn < 0.0) return MAXLOOP;
> if (yn >= 1.0) return MAXLOOP;
>
> ix = (int)(xn * DIM);
> iy = (int)(yn * DIM);
>
> if (pix[ix][iy])
> break;
> pix[ix][iy] = true;
> }
>
> return(count);
> }
>
But the sharp edges in the maps were bothering me. So much so that I rewrote
the code to continue the loop if the values of xn and yn were out of range,
thinking that maybe they might come back into range.
And yes, they did:
[As odd as it sounds, that looks much better] [5]
The downside—this revised code now takes a bit longer to run. The LuaJIT [6]
version is still faster than the C version, but the difference (on average 1
minute for the LuaJIT version; 1 minute, 30 seconds for the C version) isn't
as jaw-droppingly great.
Sigh—it's not quite as fast as I made it out to be.
Update on Tuesday, August 6^th, 2013
Yes, it is as fast as I think it was [7] …
[1]
gopher://gopher.conman.org/0Phlog:2013/08/04.1
[2]
gopher://gopher.conman.org/0Phlog:2013/08/04.2
[3]
http://en.wikipedia.org/wiki/Attractor
[4]
http://en.wikipedia.org/wiki/Silicon_Graphics
[5]
gopher://gopher.conman.org/IPhlog:2013/08/05/map.png
[6]
http://luajit.org/
[7]
gopher://gopher.conman.org/0Phlog:2013/08/06.1
Email author at
[email protected]