| [5f600f6] | 1 | # include <stdlib.h>
|
|---|
| 2 | # include <stdio.h>
|
|---|
| 3 | # include <math.h>
|
|---|
| 4 | # include <time.h>
|
|---|
| 5 |
|
|---|
| 6 | # include <omp.h>
|
|---|
| 7 |
|
|---|
| 8 | int main ( void );
|
|---|
| 9 | int i4_min ( int i1, int i2 );
|
|---|
| 10 | void timestamp ( void );
|
|---|
| 11 |
|
|---|
| 12 | /******************************************************************************/
|
|---|
| 13 |
|
|---|
| 14 | int main ( void )
|
|---|
| 15 |
|
|---|
| 16 | /******************************************************************************/
|
|---|
| 17 | /*
|
|---|
| 18 | Purpose
|
|---|
| 19 |
|
|---|
| 20 | MAIN is the main program for MANDELBROT_OPENMP.
|
|---|
| 21 |
|
|---|
| 22 | Discussion:
|
|---|
| 23 |
|
|---|
| 24 | MANDELBROT_OPENMP computes an image of the Mandelbrot set.
|
|---|
| 25 |
|
|---|
| 26 | Licensing:
|
|---|
| 27 |
|
|---|
| 28 | This code is distributed under the GNU LGPL license.
|
|---|
| 29 |
|
|---|
| 30 | Modified:
|
|---|
| 31 |
|
|---|
| 32 | 03 September 2012
|
|---|
| 33 |
|
|---|
| 34 | Author:
|
|---|
| 35 |
|
|---|
| 36 | John Burkardt
|
|---|
| 37 |
|
|---|
| 38 | Local Parameters:
|
|---|
| 39 |
|
|---|
| 40 | Local, int COUNT_MAX, the maximum number of iterations taken
|
|---|
| 41 | for a particular pixel.
|
|---|
| 42 | */
|
|---|
| 43 | {
|
|---|
| [20ac35f] | 44 | int m = 10;
|
|---|
| 45 | int n = 10;
|
|---|
| [5f600f6] | 46 |
|
|---|
| 47 | int b[m][n];
|
|---|
| 48 | int c;
|
|---|
| 49 | int c_max;
|
|---|
| 50 | int count[m][n];
|
|---|
| [20ac35f] | 51 | int count_max = 10;
|
|---|
| [5f600f6] | 52 | int g[m][n];
|
|---|
| 53 | int i;
|
|---|
| 54 | int ierror;
|
|---|
| 55 | int j;
|
|---|
| 56 | int jhi;
|
|---|
| 57 | int jlo;
|
|---|
| 58 | int k;
|
|---|
| 59 | char *output_filename = "mandelbrot.ppm";
|
|---|
| 60 | FILE *output_unit;
|
|---|
| 61 | int r[m][n];
|
|---|
| 62 | double wtime;
|
|---|
| 63 | double wtime_total;
|
|---|
| 64 | double x_max = 1.25;
|
|---|
| 65 | double x_min = - 2.25;
|
|---|
| 66 | double x;
|
|---|
| 67 | double x1;
|
|---|
| 68 | double x2;
|
|---|
| 69 | double y_max = 1.75;
|
|---|
| 70 | double y_min = - 1.75;
|
|---|
| 71 | double y;
|
|---|
| 72 | double y1;
|
|---|
| 73 | double y2;
|
|---|
| 74 |
|
|---|
| 75 | timestamp ( );
|
|---|
| 76 | printf ( "\n" );
|
|---|
| 77 | printf ( "MANDELBROT_OPENMP\n" );
|
|---|
| 78 | printf ( " C/OpenMP version\n" );
|
|---|
| 79 | printf ( "\n" );
|
|---|
| 80 | printf ( " Create an ASCII PPM image of the Mandelbrot set.\n" );
|
|---|
| 81 | printf ( "\n" );
|
|---|
| 82 | printf ( " For each point C = X + i*Y\n" );
|
|---|
| 83 | printf ( " with X range [%g,%g]\n", x_min, x_max );
|
|---|
| 84 | printf ( " and Y range [%g,%g]\n", y_min, y_max );
|
|---|
| 85 | printf ( " carry out %d iterations of the map\n", count_max );
|
|---|
| 86 | printf ( " Z(n+1) = Z(n)^2 + C.\n" );
|
|---|
| 87 | printf ( " If the iterates stay bounded (norm less than 2)\n" );
|
|---|
| 88 | printf ( " then C is taken to be a member of the set.\n" );
|
|---|
| 89 | printf ( "\n" );
|
|---|
| 90 | printf ( " An ASCII PPM image of the set is created using\n" );
|
|---|
| 91 | printf ( " M = %d pixels in the X direction and\n", m );
|
|---|
| 92 | printf ( " N = %d pixels in the Y direction.\n", n );
|
|---|
| 93 |
|
|---|
| 94 | wtime = omp_get_wtime ( );
|
|---|
| 95 | /*
|
|---|
| 96 | Carry out the iteration for each pixel, determining COUNT.
|
|---|
| 97 | */
|
|---|
| 98 | # pragma omp parallel \
|
|---|
| 99 | shared ( b, count, count_max, g, r, x_max, x_min, y_max, y_min ) \
|
|---|
| 100 | private ( i, j, k, x, x1, x2, y, y1, y2 )
|
|---|
| 101 | {
|
|---|
| 102 | # pragma omp for
|
|---|
| 103 |
|
|---|
| 104 | for ( i = 0; i < m; i++ )
|
|---|
| 105 | {
|
|---|
| 106 | for ( j = 0; j < n; j++ )
|
|---|
| 107 | {
|
|---|
| 108 | x = ( ( double ) ( j - 1 ) * x_max
|
|---|
| 109 | + ( double ) ( m - j ) * x_min )
|
|---|
| 110 | / ( double ) ( m - 1 );
|
|---|
| 111 |
|
|---|
| 112 | y = ( ( double ) ( i - 1 ) * y_max
|
|---|
| 113 | + ( double ) ( n - i ) * y_min )
|
|---|
| 114 | / ( double ) ( n - 1 );
|
|---|
| 115 |
|
|---|
| 116 | count[i][j] = 0;
|
|---|
| 117 |
|
|---|
| 118 | x1 = x;
|
|---|
| 119 | y1 = y;
|
|---|
| 120 |
|
|---|
| 121 | for ( k = 1; k <= count_max; k++ )
|
|---|
| 122 | {
|
|---|
| 123 | x2 = x1 * x1 - y1 * y1 + x;
|
|---|
| 124 | y2 = 2 * x1 * y1 + y;
|
|---|
| 125 |
|
|---|
| 126 | if ( x2 < -2.0 || 2.0 < x2 || y2 < -2.0 || 2.0 < y2 )
|
|---|
| 127 | {
|
|---|
| 128 | count[i][j] = k;
|
|---|
| 129 | break;
|
|---|
| 130 | }
|
|---|
| 131 | x1 = x2;
|
|---|
| 132 | y1 = y2;
|
|---|
| 133 | }
|
|---|
| 134 |
|
|---|
| 135 | if ( ( count[i][j] % 2 ) == 1 )
|
|---|
| 136 | {
|
|---|
| 137 | r[i][j] = 255;
|
|---|
| 138 | g[i][j] = 255;
|
|---|
| 139 | b[i][j] = 255;
|
|---|
| 140 | }
|
|---|
| 141 | else
|
|---|
| 142 | {
|
|---|
| 143 | c = ( int ) ( 255.0 * sqrt ( sqrt ( sqrt (
|
|---|
| 144 | ( ( double ) ( count[i][j] ) / ( double ) ( count_max ) ) ) ) ) );
|
|---|
| 145 | r[i][j] = 3 * c / 5;
|
|---|
| 146 | g[i][j] = 3 * c / 5;
|
|---|
| 147 | b[i][j] = c;
|
|---|
| 148 | }
|
|---|
| 149 | }
|
|---|
| 150 | }
|
|---|
| 151 | }
|
|---|
| 152 |
|
|---|
| 153 | wtime = omp_get_wtime ( ) - wtime;
|
|---|
| 154 | printf ( "\n" );
|
|---|
| 155 | printf ( " Time = %g seconds.\n", wtime );
|
|---|
| 156 | /*
|
|---|
| 157 | Write data to an ASCII PPM file.
|
|---|
| 158 | */
|
|---|
| [bb1d7b3] | 159 | output_unit = fopen ( output_filename, "w" );
|
|---|
| [5f600f6] | 160 |
|
|---|
| 161 | fprintf ( output_unit, "P3\n" );
|
|---|
| 162 | fprintf ( output_unit, "%d %d\n", n, m );
|
|---|
| 163 | fprintf ( output_unit, "%d\n", 255 );
|
|---|
| 164 | for ( i = 0; i < m; i++ )
|
|---|
| 165 | {
|
|---|
| 166 | for ( jlo = 0; jlo < n; jlo = jlo + 4 )
|
|---|
| 167 | {
|
|---|
| 168 | jhi = i4_min ( jlo + 4, n );
|
|---|
| 169 | for ( j = jlo; j < jhi; j++ )
|
|---|
| 170 | {
|
|---|
| 171 | fprintf ( output_unit, " %d %d %d", r[i][j], g[i][j], b[i][j] );
|
|---|
| 172 | }
|
|---|
| 173 | fprintf ( output_unit, "\n" );
|
|---|
| 174 | }
|
|---|
| 175 | }
|
|---|
| 176 |
|
|---|
| 177 | fclose ( output_unit );
|
|---|
| 178 | printf ( "\n" );
|
|---|
| 179 | printf ( " Graphics data written to \"%s\".\n", output_filename );
|
|---|
| 180 | /*
|
|---|
| 181 | Terminate.
|
|---|
| 182 | */
|
|---|
| 183 | printf ( "\n" );
|
|---|
| 184 | printf ( "MANDELBROT_OPENMP\n" );
|
|---|
| 185 | printf ( " Normal end of execution.\n" );
|
|---|
| 186 | printf ( "\n" );
|
|---|
| 187 | timestamp ( );
|
|---|
| 188 |
|
|---|
| 189 | return 0;
|
|---|
| 190 | }
|
|---|
| 191 | /******************************************************************************/
|
|---|
| 192 |
|
|---|
| 193 | int i4_min ( int i1, int i2 )
|
|---|
| 194 |
|
|---|
| 195 | /******************************************************************************/
|
|---|
| 196 | /*
|
|---|
| 197 | Purpose:
|
|---|
| 198 |
|
|---|
| 199 | I4_MIN returns the smaller of two I4's.
|
|---|
| 200 |
|
|---|
| 201 | Licensing:
|
|---|
| 202 |
|
|---|
| 203 | This code is distributed under the GNU LGPL license.
|
|---|
| 204 |
|
|---|
| 205 | Modified:
|
|---|
| 206 |
|
|---|
| 207 | 29 August 2006
|
|---|
| 208 |
|
|---|
| 209 | Author:
|
|---|
| 210 |
|
|---|
| 211 | John Burkardt
|
|---|
| 212 |
|
|---|
| 213 | Parameters:
|
|---|
| 214 |
|
|---|
| 215 | Input, int I1, I2, two integers to be compared.
|
|---|
| 216 |
|
|---|
| 217 | Output, int I4_MIN, the smaller of I1 and I2.
|
|---|
| 218 | */
|
|---|
| 219 | {
|
|---|
| 220 | int value;
|
|---|
| 221 |
|
|---|
| 222 | if ( i1 < i2 )
|
|---|
| 223 | {
|
|---|
| 224 | value = i1;
|
|---|
| 225 | }
|
|---|
| 226 | else
|
|---|
| 227 | {
|
|---|
| 228 | value = i2;
|
|---|
| 229 | }
|
|---|
| 230 | return value;
|
|---|
| 231 | }
|
|---|
| 232 | /******************************************************************************/
|
|---|
| 233 |
|
|---|
| 234 | void timestamp ( void )
|
|---|
| 235 |
|
|---|
| 236 | /******************************************************************************/
|
|---|
| 237 | /*
|
|---|
| 238 | Purpose:
|
|---|
| 239 |
|
|---|
| 240 | TIMESTAMP prints the current YMDHMS date as a time stamp.
|
|---|
| 241 |
|
|---|
| 242 | Example:
|
|---|
| 243 |
|
|---|
| 244 | 31 May 2001 09:45:54 AM
|
|---|
| 245 |
|
|---|
| 246 | Modified:
|
|---|
| 247 |
|
|---|
| 248 | 24 September 2003
|
|---|
| 249 |
|
|---|
| 250 | Author:
|
|---|
| 251 |
|
|---|
| 252 | John Burkardt
|
|---|
| 253 |
|
|---|
| 254 | Parameters:
|
|---|
| 255 |
|
|---|
| 256 | None
|
|---|
| 257 | */
|
|---|
| 258 | {
|
|---|
| 259 | # define TIME_SIZE 40
|
|---|
| 260 |
|
|---|
| 261 | static char time_buffer[TIME_SIZE];
|
|---|
| 262 | const struct tm *tm;
|
|---|
| 263 | size_t len;
|
|---|
| 264 | time_t now;
|
|---|
| 265 |
|
|---|
| 266 | now = time ( NULL );
|
|---|
| 267 | tm = localtime ( &now );
|
|---|
| 268 |
|
|---|
| 269 | len = strftime ( time_buffer, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm );
|
|---|
| 270 |
|
|---|
| 271 | printf ( "%s\n", time_buffer );
|
|---|
| 272 |
|
|---|
| 273 | return;
|
|---|
| 274 | # undef TIME_SIZE
|
|---|
| 275 | }
|
|---|