mandelbrot fractal

folkert folkert at vanheusden.com
Mon Sep 7 11:58:03 UTC 2015


Hi,

I'm trying to calculate the mandelbrot fractal using GMP.
I've got it working and it is amazingly fast, even for data-types of
256 bits in size!
Now what I'm curious about: can this piece of code be improved in some
way? From a GMP-lib usage point of view I mean.

// written by folkert at vanheusden.com
// released under agpl v3.0
#include <stdio.h>
#include <gmpxx.h>

void my_init_mpf(mpf_t *const what, const int n_bits)
{
	mpf_init(*what);
	mpf_set_prec(*what, n_bits);
}

int main(int argc, char *argv[])
{
	const int n_bits = 256;

	mpf_t x1, x2, y1, y2;
	mpf_init_set_d(x1, -2.0);
	mpf_init_set_d(y1, -2.0);
	mpf_init_set_d(x2, 2.0);
	mpf_init_set_d(y2, 2.0);

	const int max_it = 256;
	const int nx = 640;
	const int ny = 480;

	printf("P6 %d %d %d\n", nx, ny, max_it - 1);

	mpf_t two;
	mpf_init_set_d(two, 2.0);

	mpf_t nxg, nyg;
	mpf_init_set_ui(nxg, nx); // dummyx = xres
	mpf_init_set_ui(nyg, ny); // dummyy = yres

	mpf_t tx, ty;
	mpf_inits(tx, ty, NULL);
	mpf_sub(tx, x2, x1); // d2x = x2 - x1
	mpf_sub(ty, y2, y1); // d2y = y2 - y1

	mpf_t dx, dy;
	my_init_mpf(&dx, n_bits);
	my_init_mpf(&dy, n_bits);
	mpf_div(dx, tx, nxg); // dx = d2x / dummyx
	mpf_div(dy, ty, nyg); // dy = d2y / dummyy

	mpf_t cx, cy;
	my_init_mpf(&cx, n_bits);
	my_init_mpf(&cy, n_bits);

	mpf_t t, wx, wy, sqx, sqy;
	my_init_mpf(&t, n_bits);
	my_init_mpf(&wx, n_bits);
	my_init_mpf(&wy, n_bits);
	my_init_mpf(&sqx, n_bits);
	my_init_mpf(&sqy, n_bits);

	mpf_set(cy, y1);
	for(int y=0; y<ny; y++)
	{
		mpf_set(cx, x1);

		for(int x=0; x<nx; x++)
		{
			mpf_set_d(wx, 0.0);
			mpf_set_d(wy, 0.0);

			mpf_set_d(sqx, 0.0);
			mpf_set_d(sqy, 0.0);

			int it = 0;

			do {
				mpf_mul(t, wy, two);	// y = 2 * y
				mpf_mul(t, t, wx);	// * x
				mpf_add(wy, t, cy);	// + cy

				//

				mpf_sub(wx, sqx, sqy);	// x = x^2 - y^2
				mpf_add(wx, wx, cx);	// x = z + cx

				//

				mpf_mul(sqx, wx, wx);	// sqx = x^2
				mpf_mul(sqy, wy, wy);	// sqy = y^2

				//

				mpf_add(t, sqx, sqy);	// t = x^2 + y^2
			}
			while(mpf_cmp_d(t, 16.0) < 0 && ++it < max_it);

			double dwx = mpf_get_d(wx);
			double dwy = mpf_get_d(wy);

			if (it < max_it)
				printf("%c%c%c", int(it - dwx * 2.0), max_it - it, int(it + dwy * 2.0));
			else
				printf("%c%c%c", 0, 0, 0);

			mpf_add(cx, cx, dx);
		}

		mpf_add(cy, cy, dy);
	}

	return 0;
}


Please note that it emits a .pnm-file to stdout. So if you want to run
it yourself, invoke it like this:

./a.out > test.pnm

This test.pnm-file can be viewed with any Linux graphics viewer.


regards,

Folkert van Heusden

-- 
You've probably gotten really fed up with never winning in the Mega-
Millions lottery. Well, weep no longer: www.smartwinning.info tells
you everything that might help you deciding what numbers to choose.
With nice graphs and pretty animations!


More information about the gmp-discuss mailing list