/* *********************************************************************** This program is part of the OpenMP Source Code Repository http://www.pcg.ull.es/ompscr/ e-mail: ompscr@etsii.ull.es This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License (LICENSE file) along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA FILE: c_mandel.c VERSION: 1.0 DATE: May 2004 AUTHOR: F. de Sande COMMENTS TO: sande@csi.ull.es DESCRIPTION: This program computes an estimation to the Mandelbrot Set area using MonteCarlo sampling. The best known estimate so far is 1.50659177 +- 0.00000008. COMMENTS: The Mandelbrot set is a fractal that is defined as the set of points c in the complex plane for which the sequence z_{n+1} = z_n^2 + c with z_0 = 0 does not tend to infinity. The area of the Mandelbrot set is an open question that has been discussed in the recent past. It is not easy to obtain an accurate analytical estimate, and therefore statistical methods have been used. The program explores the rectangle ranging over (-2.0, 0.5) in the real axis and (0.0, 1.125) in the imaginary axis. This rectangle covers the top half of the Mandelbrot Set. REFERENCES: http://www.fractalus.com/kerry/articles/area/mandelbrot-area.html http://www.matthiasbook.de/papers/parallelfractals/mandelbrot.html http://www.mrob.com/pub/muency/areaofthemandelbrotset.html http://en.wikipedia.org/wiki/Mandelbrot_set BASIC PRAGMAS: parallel for USAGE: ./c_mandel.par 8192 INPUT: The number of points to explore OUTPUT: An estimation of the area and the error. FILE FORMATS: - RESTRICTIONS: - REVISION HISTORY: **************************************************************************/ //#include "OmpSCR.h" #include #include #include #include #define OSCR_RAND_MAX 2147483647 #define MAXITER 100000 #define DEFAULT_NPOINTS 4092 #define THRESOLD 2.0 #define NPOINTSINIT 10 #define NUM_ARGS 1 #define NUM_TIMERS 1 typedef struct { double re, im; } complex; int NPOINTS; /* Total no. of points */ complex *points; /* ----------------------------------------------------------------------- IMPLEMENTATION * ----------------------------------------------------------------------- */ int main(int argc, char **argv) { int i, j, NUMTHREADS; long inside, /* no. of points inside the Mandelbrot set */ outside; /* no. of points outside the Mandelbrot set */ double area, error, ztemp, total_time; complex z; // char *PARAM_NAMES[NUM_ARGS] = {"Number of points"}; // char *TIMERS_NAMES[NUM_TIMERS] = {"Total_time"}; // char *DEFAULT_VALUES[NUM_ARGS] = {"4092"}; NUMTHREADS = 1; //omp_get_num_threads(); //OSCR_init (NUMTHREADS, "Mandelbrot set area", "Use 'mandel' ", NUM_ARGS, // PARAM_NAMES, DEFAULT_VALUES , NUM_TIMERS, NUM_TIMERS, TIMERS_NAMES, // argc, argv); NPOINTS = NPOINTSINIT; // OSCR_getarg_int(1); /* Default: DEFAULT_NPOINTS */ points = (complex *)calloc(NPOINTS, sizeof(complex)); NUMTHREADS = 1; //omp_get_num_threads(); /*1. Generate NPOINTS random points in the complex plane */ srandom(31416); for (i = 0; i < NPOINTS; i++) { points[i].re = -2.0 + 2.5 * random() / OSCR_RAND_MAX; points[i].im = 1.125 * random() / OSCR_RAND_MAX; } /* * 2. Monte Carlo sampling * 2a. Outer loop runs over NPOINTS, initialise z=c * 2b. Inner loop has the iteration z=z*z+c, and threshold test */ //OSCR_timer_start(0); outside = 0; #pragma omp parallel for default(none) reduction(+:outside) \ private(i, j, ztemp, z) shared(NPOINTS, points) for(i = 0; i < NPOINTS; i++) { z.re = points[i].re; z.im = points[i].im; for (j = 0; j < MAXITER; j++) { ztemp = (z.re * z.re) - (z.im * z.im) + points[i].re; z.im = z.re * z.im * 2 + points[i].im; z.re = ztemp; if (z.re * z.re + z.im * z.im > THRESOLD) { outside++; break; } } /* for j */ } /* for i */ inside = (long)NPOINTS - outside; /*3. Calculate area and error */ /* The area is proportional to 2 * the area of the rectangle * no. of points inside it */ /* The error is inversely proportional to the square root of the number of test cases */ area = 2.0 * (2.5 * 1.125) * inside / NPOINTS; error = area / sqrt(NPOINTS); //OSCR_timer_stop(0); total_time = 1; //OSCR_timer_read(0); /* 4. Output the Results */ //OSCR_report(1, TIMERS_NAMES); printf("\n \t# THREADS NPOINTS AREA \t\t\tERROR \t\tTIME (secs.)\n"); printf("\t%d \t%d \t%16.12f %16.12f \t%lf\n", NUMTHREADS, NPOINTS, area, error, total_time); return 0; } /* * vim:ts=2:sw=2: */