long double wall of lost precision, now i say farewell to ye
for i can zoom in deep enough that 128 bit precision

glee

http://www.jwm-art.net/art/image/glee.png

this here image generated by [show off show off] a development version of
gkII called gkII-mdz, short for gkII-MandelbrotDeepZoom. thanks to the
MPFR library maths precision far exceeding long double is at hand. if
only i had a super computer.

the glee.png image took 531.467 seconds to generate on an 3ghz 64bit
Intel Core 2 machine. the image measures 480 x 360 pixels with an
anti-aliasing factor of 3.

the program was set to use 128 bit precision for the maths (changeable in
the graphical user interface).

here is the code which generates one line of the image at a time, using
the MPFR library:

<pre><code>
void p_fractal_next_line(image_info* img)
{
    int ix, wz;
    fractal_settings* frs = &img->frac_settings;
    double scale = frs->scale;

    mpfr_t  x,      y;
    mpfr_t  x2,     y2;
    mpfr_t  c_re,   c_im;

/*  working variables:      */
    mpfr_t  wre,    wim;
    mpfr_t  wre2,   wim2;

/*  perturbation:           */
    mpfr_t  f_re,   f_im;

    mpfr_t  frs_bail;
    mpfr_t xdiff,   img_rw, img_xmin;
    mpfr_t t1, t2;

    mpfr_init2(x,       img->precision);
    mpfr_init2(y,       img->precision);
    mpfr_init2(x2,      img->precision);
    mpfr_init2(y2,      img->precision);
    mpfr_init2(c_re,    img->precision);
    mpfr_init2(c_im,    img->precision);
    mpfr_init2(wre,     img->precision);
    mpfr_init2(wim,     img->precision);
    mpfr_init2(wre2,    img->precision);
    mpfr_init2(wim2,    img->precision);
    mpfr_init2(f_re,    img->precision);
    mpfr_init2(f_im,    img->precision);
    mpfr_init2(frs_bail,img->precision);
    mpfr_init2(xdiff,   img->precision);
    mpfr_init2(img_rw,  img->precision);
    mpfr_init2(img_xmin,img->precision);
    mpfr_init2(t1,      img->precision);
    mpfr_init2(t2,      img->precision);

    mpfr_set_ld(f_re,       frs->re_pert,       GMP_RNDN);
    mpfr_set_ld(f_im,       frs->im_pert,       GMP_RNDN);

    mpfr_set_ld(frs_bail,   frs->bail_value,    GMP_RNDN);
    mpfr_set_si(img_rw,     img->real_width,    GMP_RNDN);
    mpfr_set(   img_xmin,   img->p_xmin,        GMP_RNDN);

/*  y = img->ymax - ((img->xmax - img->xmin)
                / (long double)img->real_width)
                * (long double)img->lines_done; */
    mpfr_sub(       xdiff,  img->p_xmax,    img->p_xmin,        GMP_RNDN);
    mpfr_div(       t1,     xdiff,          img_rw,             GMP_RNDN);
    mpfr_mul_si(    t2,     t1,             img->lines_done,    GMP_RNDN);
    mpfr_sub(       y,      img->p_ymax,    t2,                 GMP_RNDN);
    mpfr_mul(       y2,     y,              y,                  GMP_RNDN);

    for (ix=0; ix < img->real_width; ix++)
    {
/*      x = ((long double)ix / (long double)img->real_width)
            * (img->xmax - img->xmin) + img->xmin;              */

        mpfr_si_div(t1,  ix,    img_rw,     GMP_RNDN);

        mpfr_mul(x,      t1,    xdiff,      GMP_RNDN);
        mpfr_add(x,      x,     img_xmin,   GMP_RNDN);

        mpfr_mul(   x2,     x,      x,      GMP_RNDN);
        mpfr_set(   wre,    x,              GMP_RNDN);
        mpfr_set(   wim,    y,              GMP_RNDN);
        mpfr_set(   wre2,   x2,             GMP_RNDN);
        mpfr_set(   wim2,   y2,             GMP_RNDN);

        switch (img->fr_type)
        {
        case MANDELBROT:
            mpfr_set(c_re,  x,  GMP_RNDN);
            mpfr_set(c_im,  y,  GMP_RNDN);
            break;
        case JULIA:
            mpfr_set(c_re,  img->u.julia.p_c_re,  GMP_RNDN);
            mpfr_set(c_im,  img->u.julia.p_c_im,  GMP_RNDN);
            break;
        }
        for (wz=0; wz < img->depth; wz++)
        {
            /* wim = 2.0 * wre * wim+ c_im - f_im; */
            mpfr_mul(   t1,     wre,    wim,    GMP_RNDN);
            mpfr_mul_si(t2,     t1,     2,      GMP_RNDN);
            mpfr_add(   t1,     t2,     c_im,   GMP_RNDN);
            mpfr_sub(   wim,    t1,     f_im,   GMP_RNDN);
            /* wre = wre2 - wim2 + c_re - f_re; */
            mpfr_sub(   t1,     wre2,   wim2,   GMP_RNDN);
            mpfr_add(   t2,     t1,     c_re,   GMP_RNDN);
            mpfr_sub(   wre,    t2,     f_re,   GMP_RNDN);
            /* wim2 = wim * wim; */
            mpfr_mul(   wim2,   wim,    wim,    GMP_RNDN);
            /* wre2 = wre * wre; */
            mpfr_mul(   wre2,   wre,    wre,    GMP_RNDN);
            /* if ((wim2 + wre2) > frs_bail) */
            mpfr_add(   t1,     wim2,   wre2,   GMP_RNDN);
            if (mpfr_greater_p(t1, frs_bail))
            {
                break;
            }
        }
        img->raw_data[img->lines_done * img->real_width + ix]
                = wz * scale;
    }
    img->lines_done++;
    mpfr_clear(x);
    mpfr_clear(y);
    mpfr_clear(x2);
    mpfr_clear(y2);
    mpfr_clear(c_re);
    mpfr_clear(c_im);
    mpfr_clear(wre);
    mpfr_clear(wim);
    mpfr_clear(wre2);
    mpfr_clear(wim2);
    mpfr_clear(f_re);
    mpfr_clear(f_im);
    mpfr_clear(frs_bail);
    mpfr_clear(xdiff);
    mpfr_clear(img_rw);
    mpfr_clear(t1);
    mpfr_clear(t2);
}
</code></pre>

once past the bulk of lines calling mpfr_init2, the lines beginning with
/* are comments showing what the following mpfr_??? calls replace.

Here's that glee image again, the one that took 531 seconds to be
generated:

http://www.jwm-art.net/art/image/glee.png

it should be noted, that despite appearances (of which the subtleties may
not be appreciated by all) no colouring methods beyond the most basic
translation of iterations to colour were used. this is a bog standard
mandelbrot with which i aim to prove you don't need any fancy colouring
methods with the mandelbrot set for it contains all within
_______________________________________________
NetBehaviour mailing list
[email protected]
http://www.netbehaviour.org/mailman/listinfo/netbehaviour

Reply via email to