| 1 | /* ***********************************************************************
|
|---|
| 2 | This program is part of the
|
|---|
| 3 | OpenMP Source Code Repository
|
|---|
| 4 |
|
|---|
| 5 | http://www.pcg.ull.es/ompscr/
|
|---|
| 6 | e-mail: ompscr@etsii.ull.es
|
|---|
| 7 |
|
|---|
| 8 | This program is free software; you can redistribute it and/or modify
|
|---|
| 9 | it under the terms of the GNU General Public License as published by
|
|---|
| 10 | the Free Software Foundation; either version 2 of the License, or
|
|---|
| 11 | (at your option) any later version.
|
|---|
| 12 |
|
|---|
| 13 | This program is distributed in the hope that it will be useful,
|
|---|
| 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|---|
| 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|---|
| 16 | GNU General Public License for more details.
|
|---|
| 17 |
|
|---|
| 18 | You should have received a copy of the GNU General Public License
|
|---|
| 19 | (LICENSE file) along with this program; if not, write to
|
|---|
| 20 | the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
|---|
| 21 | Boston, MA 02111-1307 USA
|
|---|
| 22 |
|
|---|
| 23 | FILE: c_mandel.c
|
|---|
| 24 | VERSION: 1.0
|
|---|
| 25 | DATE: May 2004
|
|---|
| 26 | AUTHOR: F. de Sande
|
|---|
| 27 | COMMENTS TO: sande@csi.ull.es
|
|---|
| 28 | DESCRIPTION: This program computes an estimation to the
|
|---|
| 29 | Mandelbrot Set area using MonteCarlo sampling.
|
|---|
| 30 | The best known estimate so far is 1.50659177 +- 0.00000008.
|
|---|
| 31 | COMMENTS: The Mandelbrot set is a fractal that is defined as the set of points c
|
|---|
| 32 | in the complex plane for which the sequence z_{n+1} = z_n^2 + c
|
|---|
| 33 | with z_0 = 0 does not tend to infinity.
|
|---|
| 34 | The area of the Mandelbrot set is an open question that has been
|
|---|
| 35 | discussed in the recent past.
|
|---|
| 36 | It is not easy to obtain an accurate analytical estimate, and therefore
|
|---|
| 37 | statistical methods have been used.
|
|---|
| 38 | The program explores the rectangle ranging over (-2.0, 0.5) in the
|
|---|
| 39 | real axis and (0.0, 1.125) in the imaginary axis.
|
|---|
| 40 | This rectangle covers the top half of the Mandelbrot Set.
|
|---|
| 41 | REFERENCES: http://www.fractalus.com/kerry/articles/area/mandelbrot-area.html
|
|---|
| 42 | http://www.matthiasbook.de/papers/parallelfractals/mandelbrot.html
|
|---|
| 43 | http://www.mrob.com/pub/muency/areaofthemandelbrotset.html
|
|---|
| 44 | http://en.wikipedia.org/wiki/Mandelbrot_set
|
|---|
| 45 | BASIC PRAGMAS: parallel for
|
|---|
| 46 | USAGE: ./c_mandel.par 8192
|
|---|
| 47 | INPUT: The number of points to explore
|
|---|
| 48 | OUTPUT: An estimation of the area and the error.
|
|---|
| 49 | FILE FORMATS: -
|
|---|
| 50 | RESTRICTIONS: -
|
|---|
| 51 | REVISION HISTORY:
|
|---|
| 52 | **************************************************************************/
|
|---|
| 53 | //#include "OmpSCR.h"
|
|---|
| 54 | #include <omp.h>
|
|---|
| 55 | #include <math.h>
|
|---|
| 56 | #include <stdlib.h>
|
|---|
| 57 | #include <stdio.h>
|
|---|
| 58 |
|
|---|
| 59 | #define OSCR_RAND_MAX 2147483647
|
|---|
| 60 |
|
|---|
| 61 | #define MAXITER 100000
|
|---|
| 62 | #define DEFAULT_NPOINTS 4092
|
|---|
| 63 | #define THRESOLD 2.0
|
|---|
| 64 |
|
|---|
| 65 | #define NPOINTSINIT 10
|
|---|
| 66 |
|
|---|
| 67 | #define NUM_ARGS 1
|
|---|
| 68 | #define NUM_TIMERS 1
|
|---|
| 69 | typedef struct { double re, im; } complex;
|
|---|
| 70 |
|
|---|
| 71 | int NPOINTS; /* Total no. of points */
|
|---|
| 72 | complex *points;
|
|---|
| 73 |
|
|---|
| 74 | /* -----------------------------------------------------------------------
|
|---|
| 75 | IMPLEMENTATION
|
|---|
| 76 | * ----------------------------------------------------------------------- */
|
|---|
| 77 | int main(int argc, char **argv) {
|
|---|
| 78 | int i, j, NUMTHREADS;
|
|---|
| 79 | long inside, /* no. of points inside the Mandelbrot set */
|
|---|
| 80 | outside; /* no. of points outside the Mandelbrot set */
|
|---|
| 81 | double area, error, ztemp, total_time;
|
|---|
| 82 | complex z;
|
|---|
| 83 | // char *PARAM_NAMES[NUM_ARGS] = {"Number of points"};
|
|---|
| 84 | // char *TIMERS_NAMES[NUM_TIMERS] = {"Total_time"};
|
|---|
| 85 | // char *DEFAULT_VALUES[NUM_ARGS] = {"4092"};
|
|---|
| 86 |
|
|---|
| 87 |
|
|---|
| 88 | NUMTHREADS = 1; //omp_get_num_threads();
|
|---|
| 89 | //OSCR_init (NUMTHREADS, "Mandelbrot set area", "Use 'mandel' <Number of points>", NUM_ARGS,
|
|---|
| 90 | // PARAM_NAMES, DEFAULT_VALUES , NUM_TIMERS, NUM_TIMERS, TIMERS_NAMES,
|
|---|
| 91 | // argc, argv);
|
|---|
| 92 |
|
|---|
| 93 | NPOINTS = NPOINTSINIT; // OSCR_getarg_int(1);
|
|---|
| 94 | /* Default: DEFAULT_NPOINTS */
|
|---|
| 95 |
|
|---|
| 96 | points = (complex *)calloc(NPOINTS, sizeof(complex));
|
|---|
| 97 | NUMTHREADS = 1; //omp_get_num_threads();
|
|---|
| 98 |
|
|---|
| 99 | /*1. Generate NPOINTS random points in the complex plane */
|
|---|
| 100 | srandom(31416);
|
|---|
| 101 | for (i = 0; i < NPOINTS; i++) {
|
|---|
| 102 | points[i].re = -2.0 + 2.5 * random() / OSCR_RAND_MAX;
|
|---|
| 103 | points[i].im = 1.125 * random() / OSCR_RAND_MAX;
|
|---|
| 104 | }
|
|---|
| 105 |
|
|---|
| 106 | /* * 2. Monte Carlo sampling
|
|---|
| 107 | * 2a. Outer loop runs over NPOINTS, initialise z=c
|
|---|
| 108 | * 2b. Inner loop has the iteration z=z*z+c, and threshold test
|
|---|
| 109 | */
|
|---|
| 110 | //OSCR_timer_start(0);
|
|---|
| 111 | outside = 0;
|
|---|
| 112 | #pragma omp parallel for default(none) reduction(+:outside) \
|
|---|
| 113 | private(i, j, ztemp, z) shared(NPOINTS, points)
|
|---|
| 114 | for(i = 0; i < NPOINTS; i++) {
|
|---|
| 115 | z.re = points[i].re;
|
|---|
| 116 | z.im = points[i].im;
|
|---|
| 117 | for (j = 0; j < MAXITER; j++) {
|
|---|
| 118 | ztemp = (z.re * z.re) - (z.im * z.im) + points[i].re;
|
|---|
| 119 | z.im = z.re * z.im * 2 + points[i].im;
|
|---|
| 120 | z.re = ztemp;
|
|---|
| 121 | if (z.re * z.re + z.im * z.im > THRESOLD) {
|
|---|
| 122 | outside++;
|
|---|
| 123 | break;
|
|---|
| 124 | }
|
|---|
| 125 | } /* for j */
|
|---|
| 126 | } /* for i */
|
|---|
| 127 | inside = (long)NPOINTS - outside;
|
|---|
| 128 |
|
|---|
| 129 | /*3. Calculate area and error */
|
|---|
| 130 | /* The area is proportional to 2 * the area of the rectangle * no. of points inside it */
|
|---|
| 131 | /* The error is inversely proportional to the square root of the number of test cases */
|
|---|
| 132 | area = 2.0 * (2.5 * 1.125) * inside / NPOINTS;
|
|---|
| 133 | error = area / sqrt(NPOINTS);
|
|---|
| 134 | //OSCR_timer_stop(0);
|
|---|
| 135 | total_time = 1; //OSCR_timer_read(0);
|
|---|
| 136 |
|
|---|
| 137 | /* 4. Output the Results */
|
|---|
| 138 | //OSCR_report(1, TIMERS_NAMES);
|
|---|
| 139 | printf("\n \t# THREADS NPOINTS AREA \t\t\tERROR \t\tTIME (secs.)\n");
|
|---|
| 140 | printf("\t%d \t%d \t%16.12f %16.12f \t%lf\n", NUMTHREADS, NPOINTS, area, error, total_time);
|
|---|
| 141 | return 0;
|
|---|
| 142 |
|
|---|
| 143 | }
|
|---|
| 144 |
|
|---|
| 145 | /*
|
|---|
| 146 | * vim:ts=2:sw=2:
|
|---|
| 147 | */
|
|---|