|
Packit Service |
c5cf8c |
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* (C) 2001 by Argonne National Laboratory.
|
|
Packit Service |
c5cf8c |
* See COPYRIGHT in top-level directory.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
#include <stdio.h>
|
|
Packit Service |
c5cf8c |
#include <stdlib.h>
|
|
Packit Service |
c5cf8c |
#include <math.h>
|
|
Packit Service |
c5cf8c |
#include <string.h>
|
|
Packit Service |
c5cf8c |
#include "mpi.h"
|
|
Packit Service |
c5cf8c |
#ifdef HAVE_WINDOWS_H
|
|
Packit Service |
c5cf8c |
#include <process.h>
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* definitions */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#define PROMPT 1
|
|
Packit Service |
c5cf8c |
#define USE_PPM /* define to output a color image, otherwise output is a grayscale pgm image */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#ifndef MIN
|
|
Packit Service |
c5cf8c |
#define MIN(x, y) (((x) < (y))?(x):(y))
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
#ifndef MAX
|
|
Packit Service |
c5cf8c |
#define MAX(x, y) (((x) > (y))?(x):(y))
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#define NOVALUE 99999 /* indicates a parameter is as of yet unspecified */
|
|
Packit Service |
c5cf8c |
#define MAX_ITERATIONS 10000 /* maximum 'depth' to look for mandelbrot value */
|
|
Packit Service |
c5cf8c |
#define INFINITE_LIMIT 4.0 /* evalue when fractal is considered diverging */
|
|
Packit Service |
c5cf8c |
#define MAX_X_VALUE 2.0 /* the highest x can go for the mandelbrot, usually 1.0 */
|
|
Packit Service |
c5cf8c |
#define MIN_X_VALUE -2.0 /* the lowest x can go for the mandelbrot, usually -1.0 */
|
|
Packit Service |
c5cf8c |
#define MAX_Y_VALUE 2.0 /* the highest y can go for the mandelbrot, usually 1.0 */
|
|
Packit Service |
c5cf8c |
#define MIN_Y_VALUE -2.0 /* the lowest y can go for the mandelbrot, usually -1.0 */
|
|
Packit Service |
c5cf8c |
#define IDEAL_ITERATIONS 100 /* my favorite 'depth' to default to */
|
|
Packit Service |
c5cf8c |
/* the ideal default x and y are currently the same as the max area */
|
|
Packit Service |
c5cf8c |
#define IDEAL_MAX_X_VALUE 1.0
|
|
Packit Service |
c5cf8c |
#define IDEAL_MIN_X_VALUE -1.0
|
|
Packit Service |
c5cf8c |
#define IDEAL_MAX_Y_VALUE 1.0
|
|
Packit Service |
c5cf8c |
#define IDEAL_MIN_Y_VALUE -1.0
|
|
Packit Service |
c5cf8c |
#define MAX_WIDTH 2048 /* maximum size of image, across, in pixels */
|
|
Packit Service |
c5cf8c |
#define MAX_HEIGHT 2048 /* maximum size of image, down, in pixels */
|
|
Packit Service |
c5cf8c |
#define IDEAL_WIDTH 768 /* my favorite size of image, across, in pixels */
|
|
Packit Service |
c5cf8c |
#define IDEAL_HEIGHT 768 /* my favorite size of image, down, in pixels */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#define RGBtocolor_t(r,g,b) ((color_t)(((unsigned char)(r)|((unsigned short)((unsigned char)(g))<<8))|(((unsigned long)(unsigned char)(b))<<16)))
|
|
Packit Service |
c5cf8c |
#define getR(r) ((int)((r) & 0xFF))
|
|
Packit Service |
c5cf8c |
#define getG(g) ((int)((g>>8) & 0xFF))
|
|
Packit Service |
c5cf8c |
#define getB(b) ((int)((b>>16) & 0xFF))
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
typedef int color_t;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
typedef struct complex_t {
|
|
Packit Service |
c5cf8c |
/* real + imaginary * sqrt(-1) i.e. x + iy */
|
|
Packit Service |
c5cf8c |
double real, imaginary;
|
|
Packit Service |
c5cf8c |
} complex_t;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* prototypes */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
void read_mand_args(int argc, char *argv[], int *o_max_iterations,
|
|
Packit Service |
c5cf8c |
int *o_pixels_across, int *o_pixels_down,
|
|
Packit Service |
c5cf8c |
double *o_x_min, double *o_x_max,
|
|
Packit Service |
c5cf8c |
double *o_y_min, double *o_y_max, int *o_julia,
|
|
Packit Service |
c5cf8c |
double *o_julia_real_x, double *o_julia_imaginary_y,
|
|
Packit Service |
c5cf8c |
double *o_divergent_limit, int *o_alternate,
|
|
Packit Service |
c5cf8c |
char *filename, int *num_colors, int *use_stdin, int *save_image);
|
|
Packit Service |
c5cf8c |
void check_mand_params(int *m_max_iterations,
|
|
Packit Service |
c5cf8c |
int *m_pixels_across, int *m_pixels_down,
|
|
Packit Service |
c5cf8c |
double *m_x_min, double *m_x_max,
|
|
Packit Service |
c5cf8c |
double *m_y_min, double *m_y_max, double *m_divergent_limit);
|
|
Packit Service |
c5cf8c |
void check_julia_params(double *julia_x_constant, double *julia_y_constant);
|
|
Packit Service |
c5cf8c |
int additive_mandelbrot_point(complex_t coord_point,
|
|
Packit Service |
c5cf8c |
complex_t c_constant, int Max_iterations, double divergent_limit);
|
|
Packit Service |
c5cf8c |
int additive_mandelbrot_point(complex_t coord_point,
|
|
Packit Service |
c5cf8c |
complex_t c_constant, int Max_iterations, double divergent_limit);
|
|
Packit Service |
c5cf8c |
int subtractive_mandelbrot_point(complex_t coord_point,
|
|
Packit Service |
c5cf8c |
complex_t c_constant, int Max_iterations, double divergent_limit);
|
|
Packit Service |
c5cf8c |
complex_t exponential_complex(complex_t in_complex);
|
|
Packit Service |
c5cf8c |
complex_t multiply_complex(complex_t in_one_complex, complex_t in_two_complex);
|
|
Packit Service |
c5cf8c |
complex_t divide_complex(complex_t in_one_complex, complex_t in_two_complex);
|
|
Packit Service |
c5cf8c |
complex_t inverse_complex(complex_t in_complex);
|
|
Packit Service |
c5cf8c |
complex_t add_complex(complex_t in_one_complex, complex_t in_two_complex);
|
|
Packit Service |
c5cf8c |
complex_t subtract_complex(complex_t in_one_complex, complex_t in_two_complex);
|
|
Packit Service |
c5cf8c |
double absolute_complex(complex_t in_complex);
|
|
Packit Service |
c5cf8c |
void dumpimage(char *filename, int in_grid_array[], int in_pixels_across, int in_pixels_down,
|
|
Packit Service |
c5cf8c |
int in_max_pixel_value, char input_string[], int num_colors, color_t colors[]);
|
|
Packit Service |
c5cf8c |
int single_mandelbrot_point(complex_t coord_point,
|
|
Packit Service |
c5cf8c |
complex_t c_constant, int Max_iterations, double divergent_limit);
|
|
Packit Service |
c5cf8c |
color_t getColor(double fraction, double intensity);
|
|
Packit Service |
c5cf8c |
int Make_color_array(int num_colors, color_t colors[]);
|
|
Packit Service |
c5cf8c |
void output_data(int *in_grid_array, int coord[4], int *out_grid_array, int width, int height);
|
|
Packit Service |
c5cf8c |
void PrintUsage(void);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#ifdef USE_PPM
|
|
Packit Service |
c5cf8c |
const char *default_filename = "pmandel.ppm";
|
|
Packit Service |
c5cf8c |
#else
|
|
Packit Service |
c5cf8c |
const char *default_filename = "pmandel.pgm";
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Solving the Mandelbrot set
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Set a maximum number of iterations to calculate before forcing a terminate
|
|
Packit Service |
c5cf8c |
in the Mandelbrot loop.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Command-line parameters are all optional, and include:
|
|
Packit Service |
c5cf8c |
-xmin # -xmax # Limits for the x-axis for calculating and plotting
|
|
Packit Service |
c5cf8c |
-ymin # -ymax # Limits for the y-axis for calculating and plotting
|
|
Packit Service |
c5cf8c |
-xscale # -yscale # output pixel width and height
|
|
Packit Service |
c5cf8c |
-depth # Number of iterations before we give up on a given
|
|
Packit Service |
c5cf8c |
point and move on to calculate the next
|
|
Packit Service |
c5cf8c |
-diverge # Criteria for assuming the calculation has been
|
|
Packit Service |
c5cf8c |
"solved"-- for each point z, when
|
|
Packit Service |
c5cf8c |
abs(z=z^2+c) > diverge_value
|
|
Packit Service |
c5cf8c |
-julia Plot a Julia set instead of a Mandelbrot set
|
|
Packit Service |
c5cf8c |
-jx # -jy # The Julia point that defines the set
|
|
Packit Service |
c5cf8c |
-alternate # Plot an alternate Mandelbrot equation (varient 1 or 2 so far)
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int myid;
|
|
Packit Service |
c5cf8c |
int use_stdin = 0;
|
|
Packit Service |
c5cf8c |
MPI_Comm comm;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
void swap(int *i, int *j)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int x;
|
|
Packit Service |
c5cf8c |
x = *i;
|
|
Packit Service |
c5cf8c |
*i = *j;
|
|
Packit Service |
c5cf8c |
*j = x;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int main(int argc, char *argv[])
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
complex_t coord_point, julia_constant;
|
|
Packit Service |
c5cf8c |
double x_max, x_min, y_max, y_min, x_resolution, y_resolution;
|
|
Packit Service |
c5cf8c |
double divergent_limit;
|
|
Packit Service |
c5cf8c |
char file_message[160];
|
|
Packit Service |
c5cf8c |
char filename[100];
|
|
Packit Service |
c5cf8c |
int icount, imax_iterations;
|
|
Packit Service |
c5cf8c |
int ipixels_across, ipixels_down;
|
|
Packit Service |
c5cf8c |
int i, j, k, julia, alternate_equation;
|
|
Packit Service |
c5cf8c |
int imin, imax, jmin, jmax;
|
|
Packit Service |
c5cf8c |
int temp[5];
|
|
Packit Service |
c5cf8c |
/* make an integer array of size [N x M] to hold answers. */
|
|
Packit Service |
c5cf8c |
int *in_grid_array, *out_grid_array = NULL;
|
|
Packit Service |
c5cf8c |
int numprocs;
|
|
Packit Service |
c5cf8c |
int namelen;
|
|
Packit Service |
c5cf8c |
char processor_name[MPI_MAX_PROCESSOR_NAME];
|
|
Packit Service |
c5cf8c |
int num_colors;
|
|
Packit Service |
c5cf8c |
color_t *colors = NULL;
|
|
Packit Service |
c5cf8c |
MPI_Status status;
|
|
Packit Service |
c5cf8c |
int save_image = 0;
|
|
Packit Service |
c5cf8c |
int result;
|
|
Packit Service |
c5cf8c |
char mpi_port[MPI_MAX_PORT_NAME];
|
|
Packit Service |
c5cf8c |
MPI_Info info;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Init(&argc, &argv);
|
|
Packit Service |
c5cf8c |
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
|
|
Packit Service |
c5cf8c |
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
|
|
Packit Service |
c5cf8c |
MPI_Get_processor_name(processor_name, &namelen);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (numprocs == 1) {
|
|
Packit Service |
c5cf8c |
PrintUsage();
|
|
Packit Service |
c5cf8c |
MPI_Finalize();
|
|
Packit Service |
c5cf8c |
exit(0);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (myid == 0) {
|
|
Packit Service |
c5cf8c |
printf("Welcome to the Mandelbrot/Julia set explorer.\n");
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Get inputs-- region to view (must be within x/ymin to x/ymax, make sure
|
|
Packit Service |
c5cf8c |
* xmax>xmin and ymax>ymin) and resolution (number of pixels along an edge,
|
|
Packit Service |
c5cf8c |
* N x M, i.e. 256x256)
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
read_mand_args(argc, argv, &imax_iterations, &ipixels_across, &ipixels_down,
|
|
Packit Service |
c5cf8c |
&x_min, &x_max, &y_min, &y_max, &julia, &julia_constant.real,
|
|
Packit Service |
c5cf8c |
&julia_constant.imaginary, &divergent_limit,
|
|
Packit Service |
c5cf8c |
&alternate_equation, filename, &num_colors, &use_stdin, &save_image);
|
|
Packit Service |
c5cf8c |
check_mand_params(&imax_iterations, &ipixels_across, &ipixels_down,
|
|
Packit Service |
c5cf8c |
&x_min, &x_max, &y_min, &y_max, &divergent_limit);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (julia == 1) /* we're doing a julia figure */
|
|
Packit Service |
c5cf8c |
check_julia_params(&julia_constant.real, &julia_constant.imaginary);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&use_stdin, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&num_colors, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&imax_iterations, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&ipixels_across, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&ipixels_down, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&divergent_limit, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&julia, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&julia_constant.real, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&julia_constant.imaginary, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&alternate_equation, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&use_stdin, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&num_colors, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&imax_iterations, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&ipixels_across, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&ipixels_down, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&divergent_limit, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&julia, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&julia_constant.real, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&julia_constant.imaginary, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&alternate_equation, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (myid == 0) {
|
|
Packit Service |
c5cf8c |
colors = malloc((num_colors + 1) * sizeof(color_t));
|
|
Packit Service |
c5cf8c |
if (colors == NULL) {
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit Service |
c5cf8c |
exit(-1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
Make_color_array(num_colors, colors);
|
|
Packit Service |
c5cf8c |
colors[num_colors] = 0; /* add one on the top to avoid edge errors */
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* allocate memory */
|
|
Packit Service |
c5cf8c |
if ((in_grid_array = (int *) calloc(ipixels_across * ipixels_down, sizeof(int))) == NULL) {
|
|
Packit Service |
c5cf8c |
printf("Memory allocation failed for data array, aborting.\n");
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit Service |
c5cf8c |
exit(-1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (myid == 0) {
|
|
Packit Service |
c5cf8c |
int istep, jstep, cur_proc;
|
|
Packit Service |
c5cf8c |
int i1[400], i2[400], j1[400], j2[400];
|
|
Packit Service |
c5cf8c |
int ii, jj;
|
|
Packit Service |
c5cf8c |
char line[1024], *token;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if ((out_grid_array = (int *) calloc(ipixels_across * ipixels_down, sizeof(int))) == NULL) {
|
|
Packit Service |
c5cf8c |
printf("Memory allocation failed for data array, aborting.\n");
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit Service |
c5cf8c |
exit(-1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
srand(getpid());
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (!use_stdin) {
|
|
Packit Service |
c5cf8c |
result = MPI_Info_create(&info;;
|
|
Packit Service |
c5cf8c |
if (result != MPI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
printf("Unable to create an MPI_Info to be used in MPI_Open_port.\n");
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
result = MPI_Open_port(/*info */ MPI_INFO_NULL, mpi_port);
|
|
Packit Service |
c5cf8c |
if (result != MPI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
printf("MPI_Open_port failed, aborting.\n");
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit Service |
c5cf8c |
exit(-1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
result = MPI_Bcast(mpi_port, MPI_MAX_PORT_NAME, MPI_CHAR, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
if (result != MPI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
printf("Unable to broadcast the port name to COMM_WORLD.\n");
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
printf("%s listening on port:\n%s\n", processor_name, mpi_port);
|
|
Packit Service |
c5cf8c |
fflush(stdout);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
result = MPI_Comm_accept(mpi_port, info, 0, MPI_COMM_WORLD, &comm);
|
|
Packit Service |
c5cf8c |
if (result != MPI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
printf("MPI_Comm_accept failed, aborting.\n");
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit Service |
c5cf8c |
exit(-1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
printf("accepted connection from visualization program.\n");
|
|
Packit Service |
c5cf8c |
fflush(stdout);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
printf("sending image size to visualizer.\n");
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* printf("sending pixels_across.\n");
|
|
Packit Service |
c5cf8c |
* fflush(stdout);
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
result = MPI_Send(&ipixels_across, 1, MPI_INT, 0, 0, comm);
|
|
Packit Service |
c5cf8c |
if (result != MPI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
printf("Unable to send pixel width to visualizer, aborting.\n");
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* printf("sending pixels_down.\n");
|
|
Packit Service |
c5cf8c |
* fflush(stdout);
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
result = MPI_Send(&ipixels_down, 1, MPI_INT, 0, 0, comm);
|
|
Packit Service |
c5cf8c |
if (result != MPI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
printf("Unable to send pixel height to visualizer, aborting.\n");
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* printf("sending num_colors.\n");
|
|
Packit Service |
c5cf8c |
* fflush(stdout);
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
result = MPI_Send(&num_colors, 1, MPI_INT, 0, 0, comm);
|
|
Packit Service |
c5cf8c |
if (result != MPI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
printf("Unable to send num_colors to visualizer, aborting.\n");
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
result = MPI_Send(&imax_iterations, 1, MPI_INT, 0, 0, comm);
|
|
Packit Service |
c5cf8c |
if (result != MPI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
printf("Unable to send imax_iterations to visualizer, aborting.\n");
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
for (;;) {
|
|
Packit Service |
c5cf8c |
/* get x_min, x_max, y_min, and y_max */
|
|
Packit Service |
c5cf8c |
if (use_stdin) {
|
|
Packit Service |
c5cf8c |
printf("input xmin ymin xmax ymax max_iter, (0 0 0 0 0 to quit):\n");
|
|
Packit Service |
c5cf8c |
fflush(stdout);
|
|
Packit Service |
c5cf8c |
fgets(line, 1024, stdin);
|
|
Packit Service |
c5cf8c |
/*printf("read <%s> from stdin\n", line);fflush(stdout); */
|
|
Packit Service |
c5cf8c |
token = strtok(line, " \n");
|
|
Packit Service |
c5cf8c |
x_min = atof(token);
|
|
Packit Service |
c5cf8c |
token = strtok(NULL, " \n");
|
|
Packit Service |
c5cf8c |
y_min = atof(token);
|
|
Packit Service |
c5cf8c |
token = strtok(NULL, " \n");
|
|
Packit Service |
c5cf8c |
x_max = atof(token);
|
|
Packit Service |
c5cf8c |
token = strtok(NULL, " \n");
|
|
Packit Service |
c5cf8c |
y_max = atof(token);
|
|
Packit Service |
c5cf8c |
token = strtok(NULL, " \n");
|
|
Packit Service |
c5cf8c |
imax_iterations = atoi(token);
|
|
Packit Service |
c5cf8c |
/*sscanf(line, "%g %g %g %g", &x_min, &y_min, &x_max, &y_max); */
|
|
Packit Service |
c5cf8c |
/*scanf("%g %g %g %g", &x_min, &y_min, &x_max, &y_max); */
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
printf("reading xmin,ymin,xmax,ymax.\n");
|
|
Packit Service |
c5cf8c |
fflush(stdout);
|
|
Packit Service |
c5cf8c |
result = MPI_Recv(&x_min, 1, MPI_DOUBLE, 0, 0, comm, &status);
|
|
Packit Service |
c5cf8c |
if (result != MPI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
printf("Unable to receive x_min from the visualizer, aborting.\n");
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
result = MPI_Recv(&y_min, 1, MPI_DOUBLE, 0, 0, comm, &status);
|
|
Packit Service |
c5cf8c |
if (result != MPI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
printf("Unable to receive y_min from the visualizer, aborting.\n");
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
result = MPI_Recv(&x_max, 1, MPI_DOUBLE, 0, 0, comm, &status);
|
|
Packit Service |
c5cf8c |
if (result != MPI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
printf("Unable to receive x_max from the visualizer, aborting.\n");
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
result = MPI_Recv(&y_max, 1, MPI_DOUBLE, 0, 0, comm, &status);
|
|
Packit Service |
c5cf8c |
if (result != MPI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
printf("Unable to receive y_max from the visualizer, aborting.\n");
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
result = MPI_Recv(&imax_iterations, 1, MPI_INT, 0, 0, comm, &status);
|
|
Packit Service |
c5cf8c |
if (result != MPI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
printf("Unable to receive imax_iterations from the visualizer, aborting.\n");
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
printf("x0,y0 = (%f, %f) x1,y1 = (%f,%f) max_iter = %d\n", x_min, y_min, x_max, y_max,
|
|
Packit Service |
c5cf8c |
imax_iterations);
|
|
Packit Service |
c5cf8c |
fflush(stdout);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* break the work up into 400 pieces */
|
|
Packit Service |
c5cf8c |
istep = ipixels_across / 20;
|
|
Packit Service |
c5cf8c |
jstep = ipixels_down / 20;
|
|
Packit Service |
c5cf8c |
if (istep < 1)
|
|
Packit Service |
c5cf8c |
istep = 1;
|
|
Packit Service |
c5cf8c |
if (jstep < 1)
|
|
Packit Service |
c5cf8c |
jstep = 1;
|
|
Packit Service |
c5cf8c |
k = 0;
|
|
Packit Service |
c5cf8c |
for (i = 0; i < 20; i++) {
|
|
Packit Service |
c5cf8c |
for (j = 0; j < 20; j++) {
|
|
Packit Service |
c5cf8c |
i1[k] = MIN(istep * i, ipixels_across - 1);
|
|
Packit Service |
c5cf8c |
i2[k] = MIN((istep * (i + 1)) - 1, ipixels_across - 1);
|
|
Packit Service |
c5cf8c |
j1[k] = MIN(jstep * j, ipixels_down - 1);
|
|
Packit Service |
c5cf8c |
j2[k] = MIN((jstep * (j + 1)) - 1, ipixels_down - 1);
|
|
Packit Service |
c5cf8c |
k++;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* shuffle the work */
|
|
Packit Service |
c5cf8c |
for (i = 0; i < 500; i++) {
|
|
Packit Service |
c5cf8c |
ii = rand() % 400;
|
|
Packit Service |
c5cf8c |
jj = rand() % 400;
|
|
Packit Service |
c5cf8c |
swap(&i1[ii], &i1[jj]);
|
|
Packit Service |
c5cf8c |
swap(&i2[ii], &i2[jj]);
|
|
Packit Service |
c5cf8c |
swap(&j1[ii], &j1[jj]);
|
|
Packit Service |
c5cf8c |
swap(&j2[ii], &j2[jj]);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/*printf("bcasting the limits: (%f,%f)(%f,%f)\n", x_min, y_min, x_max, y_max);fflush(stdout); */
|
|
Packit Service |
c5cf8c |
/* let everyone know the limits */
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&x_min, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&x_max, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&y_min, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&y_max, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&imax_iterations, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* check for the end condition */
|
|
Packit Service |
c5cf8c |
if (x_min == x_max && y_min == y_max) {
|
|
Packit Service |
c5cf8c |
break;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* send a piece of work to each worker (there must be more work than workers) */
|
|
Packit Service |
c5cf8c |
cur_proc = 1;
|
|
Packit Service |
c5cf8c |
k = 0;
|
|
Packit Service |
c5cf8c |
for (i = 1; i < numprocs; i++) {
|
|
Packit Service |
c5cf8c |
temp[0] = k + 1;
|
|
Packit Service |
c5cf8c |
temp[1] = i1[k]; /* imin */
|
|
Packit Service |
c5cf8c |
temp[2] = i2[k]; /* imax */
|
|
Packit Service |
c5cf8c |
temp[3] = j1[k]; /* jmin */
|
|
Packit Service |
c5cf8c |
temp[4] = j2[k]; /* jmax */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/*printf("sending work(%d) to %d\n", k+1, cur_proc);fflush(stdout); */
|
|
Packit Service |
c5cf8c |
MPI_Send(temp, 5, MPI_INT, cur_proc, 100, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
cur_proc++;
|
|
Packit Service |
c5cf8c |
k++;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/* receive the results and hand out more work until the image is complete */
|
|
Packit Service |
c5cf8c |
while (k < 400) {
|
|
Packit Service |
c5cf8c |
MPI_Recv(temp, 5, MPI_INT, MPI_ANY_SOURCE, 200, MPI_COMM_WORLD, &status);
|
|
Packit Service |
c5cf8c |
cur_proc = temp[0];
|
|
Packit Service |
c5cf8c |
MPI_Recv(in_grid_array, (temp[2] + 1 - temp[1]) * (temp[4] + 1 - temp[3]), MPI_INT,
|
|
Packit Service |
c5cf8c |
cur_proc, 201, MPI_COMM_WORLD, &status);
|
|
Packit Service |
c5cf8c |
/* draw data */
|
|
Packit Service |
c5cf8c |
output_data(in_grid_array, &temp[1], out_grid_array, ipixels_across, ipixels_down);
|
|
Packit Service |
c5cf8c |
temp[0] = k + 1;
|
|
Packit Service |
c5cf8c |
temp[1] = i1[k];
|
|
Packit Service |
c5cf8c |
temp[2] = i2[k];
|
|
Packit Service |
c5cf8c |
temp[3] = j1[k];
|
|
Packit Service |
c5cf8c |
temp[4] = j2[k];
|
|
Packit Service |
c5cf8c |
/*printf("sending work(%d) to %d\n", k+1, cur_proc);fflush(stdout); */
|
|
Packit Service |
c5cf8c |
MPI_Send(temp, 5, MPI_INT, cur_proc, 100, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
k++;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/* receive the last pieces of work */
|
|
Packit Service |
c5cf8c |
/* and tell everyone to stop */
|
|
Packit Service |
c5cf8c |
for (i = 1; i < numprocs; i++) {
|
|
Packit Service |
c5cf8c |
MPI_Recv(temp, 5, MPI_INT, MPI_ANY_SOURCE, 200, MPI_COMM_WORLD, &status);
|
|
Packit Service |
c5cf8c |
cur_proc = temp[0];
|
|
Packit Service |
c5cf8c |
MPI_Recv(in_grid_array, (temp[2] + 1 - temp[1]) * (temp[4] + 1 - temp[3]), MPI_INT,
|
|
Packit Service |
c5cf8c |
cur_proc, 201, MPI_COMM_WORLD, &status);
|
|
Packit Service |
c5cf8c |
/* draw data */
|
|
Packit Service |
c5cf8c |
output_data(in_grid_array, &temp[1], out_grid_array, ipixels_across, ipixels_down);
|
|
Packit Service |
c5cf8c |
temp[0] = 0;
|
|
Packit Service |
c5cf8c |
temp[1] = 0;
|
|
Packit Service |
c5cf8c |
temp[2] = 0;
|
|
Packit Service |
c5cf8c |
temp[3] = 0;
|
|
Packit Service |
c5cf8c |
temp[4] = 0;
|
|
Packit Service |
c5cf8c |
/*printf("sending %d to tell %d to stop\n", temp[0], cur_proc);fflush(stdout); */
|
|
Packit Service |
c5cf8c |
MPI_Send(temp, 5, MPI_INT, cur_proc, 100, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* tell the visualizer the image is done */
|
|
Packit Service |
c5cf8c |
if (!use_stdin) {
|
|
Packit Service |
c5cf8c |
temp[0] = 0;
|
|
Packit Service |
c5cf8c |
temp[1] = 0;
|
|
Packit Service |
c5cf8c |
temp[2] = 0;
|
|
Packit Service |
c5cf8c |
temp[3] = 0;
|
|
Packit Service |
c5cf8c |
result = MPI_Send(temp, 4, MPI_INT, 0, 0, comm);
|
|
Packit Service |
c5cf8c |
if (result != MPI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
printf("Unable to send a done command to the visualizer, aborting.\n");
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
if (!use_stdin) {
|
|
Packit Service |
c5cf8c |
result = MPI_Info_create(&info;;
|
|
Packit Service |
c5cf8c |
if (result != MPI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
printf("Unable to create an MPI_Info to be used in MPI_Open_port.\n");
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
result = MPI_Bcast(mpi_port, MPI_MAX_PORT_NAME, MPI_CHAR, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
if (result != MPI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
printf("Unable to broadcast the port name on COMM_WORLD.\n");
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* printf("%s listening on port: %s\n", processor_name, mpi_port);
|
|
Packit Service |
c5cf8c |
* fflush(stdout);
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
result = MPI_Comm_accept(mpi_port, info, 0, MPI_COMM_WORLD, &comm);
|
|
Packit Service |
c5cf8c |
if (result != MPI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
printf("MPI_Comm_accept failed, aborting.\n");
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit Service |
c5cf8c |
exit(-1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
for (;;) {
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&x_min, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&x_max, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&y_min, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&y_max, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&imax_iterations, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* check for the end condition */
|
|
Packit Service |
c5cf8c |
if (x_min == x_max && y_min == y_max) {
|
|
Packit Service |
c5cf8c |
break;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
x_resolution = (x_max - x_min) / ((double) ipixels_across);
|
|
Packit Service |
c5cf8c |
y_resolution = (y_max - y_min) / ((double) ipixels_down);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Recv(temp, 5, MPI_INT, 0, 100, MPI_COMM_WORLD, &status);
|
|
Packit Service |
c5cf8c |
while (temp[0] != 0) {
|
|
Packit Service |
c5cf8c |
imin = temp[1];
|
|
Packit Service |
c5cf8c |
imax = temp[2];
|
|
Packit Service |
c5cf8c |
jmin = temp[3];
|
|
Packit Service |
c5cf8c |
jmax = temp[4];
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
k = 0;
|
|
Packit Service |
c5cf8c |
for (j = jmin; j <= jmax; ++j) {
|
|
Packit Service |
c5cf8c |
coord_point.imaginary = y_max - j * y_resolution; /* go top to bottom */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
for (i = imin; i <= imax; ++i) {
|
|
Packit Service |
c5cf8c |
/* Call Mandelbrot routine for each code, fill array with number of iterations. */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
coord_point.real = x_min + i * x_resolution; /* go left to right */
|
|
Packit Service |
c5cf8c |
if (julia == 1) {
|
|
Packit Service |
c5cf8c |
/* doing Julia set */
|
|
Packit Service |
c5cf8c |
/* julia eq: z = z^2 + c, z_0 = grid coordinate, c = constant */
|
|
Packit Service |
c5cf8c |
icount =
|
|
Packit Service |
c5cf8c |
single_mandelbrot_point(coord_point, julia_constant,
|
|
Packit Service |
c5cf8c |
imax_iterations, divergent_limit);
|
|
Packit Service |
c5cf8c |
} else if (alternate_equation == 1) {
|
|
Packit Service |
c5cf8c |
/* doing experimental form 1 */
|
|
Packit Service |
c5cf8c |
icount =
|
|
Packit Service |
c5cf8c |
subtractive_mandelbrot_point(coord_point, julia_constant,
|
|
Packit Service |
c5cf8c |
imax_iterations, divergent_limit);
|
|
Packit Service |
c5cf8c |
} else if (alternate_equation == 2) {
|
|
Packit Service |
c5cf8c |
/* doing experimental form 2 */
|
|
Packit Service |
c5cf8c |
icount =
|
|
Packit Service |
c5cf8c |
additive_mandelbrot_point(coord_point, julia_constant,
|
|
Packit Service |
c5cf8c |
imax_iterations, divergent_limit);
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
/* default to doing Mandelbrot set */
|
|
Packit Service |
c5cf8c |
/* mandelbrot eq: z = z^2 + c, z_0 = c, c = grid coordinate */
|
|
Packit Service |
c5cf8c |
icount =
|
|
Packit Service |
c5cf8c |
single_mandelbrot_point(coord_point, coord_point, imax_iterations,
|
|
Packit Service |
c5cf8c |
divergent_limit);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
in_grid_array[k] = icount;
|
|
Packit Service |
c5cf8c |
++k;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/* send the result to the root */
|
|
Packit Service |
c5cf8c |
temp[0] = myid;
|
|
Packit Service |
c5cf8c |
MPI_Send(temp, 5, MPI_INT, 0, 200, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Send(in_grid_array, (temp[2] + 1 - temp[1]) * (temp[4] + 1 - temp[3]), MPI_INT,
|
|
Packit Service |
c5cf8c |
0, 201, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
/* get the next piece of work */
|
|
Packit Service |
c5cf8c |
MPI_Recv(temp, 5, MPI_INT, 0, 100, MPI_COMM_WORLD, &status);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (myid == 0 && save_image) {
|
|
Packit Service |
c5cf8c |
imax_iterations = 0;
|
|
Packit Service |
c5cf8c |
for (i = 0; i < ipixels_across * ipixels_down; ++i) {
|
|
Packit Service |
c5cf8c |
/* look for "brightest" pixel value, for image use */
|
|
Packit Service |
c5cf8c |
if (out_grid_array[i] > imax_iterations)
|
|
Packit Service |
c5cf8c |
imax_iterations = out_grid_array[i];
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (julia == 0)
|
|
Packit Service |
c5cf8c |
printf("Done calculating mandelbrot, now creating file\n");
|
|
Packit Service |
c5cf8c |
else
|
|
Packit Service |
c5cf8c |
printf("Done calculating julia, now creating file\n");
|
|
Packit Service |
c5cf8c |
fflush(stdout);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Print out the array in some appropriate form. */
|
|
Packit Service |
c5cf8c |
if (julia == 0) {
|
|
Packit Service |
c5cf8c |
/* it's a mandelbrot */
|
|
Packit Service |
c5cf8c |
sprintf(file_message, "Mandelbrot over (%lf-%lf,%lf-%lf), size %d x %d",
|
|
Packit Service |
c5cf8c |
x_min, x_max, y_min, y_max, ipixels_across, ipixels_down);
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
/* it's a julia */
|
|
Packit Service |
c5cf8c |
sprintf(file_message, "Julia over (%lf-%lf,%lf-%lf), size %d x %d, center (%lf, %lf)",
|
|
Packit Service |
c5cf8c |
x_min, x_max, y_min, y_max, ipixels_across, ipixels_down,
|
|
Packit Service |
c5cf8c |
julia_constant.real, julia_constant.imaginary);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
dumpimage(filename, out_grid_array, ipixels_across, ipixels_down, imax_iterations,
|
|
Packit Service |
c5cf8c |
file_message, num_colors, colors);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Comm_disconnect(&comm);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Finalize();
|
|
Packit Service |
c5cf8c |
free(colors);
|
|
Packit Service |
c5cf8c |
return 0;
|
|
Packit Service |
c5cf8c |
} /* end of main */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
void PrintUsage(void)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
printf("usage: mpiexec -n x pmandel [options]\n");
|
|
Packit Service |
c5cf8c |
printf
|
|
Packit Service |
c5cf8c |
("options:\n -xmin # -xmax #\n -ymin # -ymax #\n -depth #\n -xscale # -yscale #\n -out filename\n -i\n");
|
|
Packit Service |
c5cf8c |
printf("All options are optional.\n");
|
|
Packit Service |
c5cf8c |
printf
|
|
Packit Service |
c5cf8c |
("-i will allow you to input the min/max parameters from stdin and output the resulting image to a ppm file.");
|
|
Packit Service |
c5cf8c |
printf
|
|
Packit Service |
c5cf8c |
(" Otherwise the root process will listen for a separate visualizer program to connect to it.\n");
|
|
Packit Service |
c5cf8c |
printf
|
|
Packit Service |
c5cf8c |
("The defaults are:\n xmin %f, xmax %f\n ymin %f, ymax %f\n depth %d\n xscale %d, yscale %d\n %s\n",
|
|
Packit Service |
c5cf8c |
IDEAL_MIN_X_VALUE, IDEAL_MAX_X_VALUE, IDEAL_MIN_Y_VALUE, IDEAL_MAX_Y_VALUE,
|
|
Packit Service |
c5cf8c |
IDEAL_ITERATIONS, IDEAL_WIDTH, IDEAL_HEIGHT, default_filename);
|
|
Packit Service |
c5cf8c |
fflush(stdout);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
color_t getColor(double fraction, double intensity)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
/* fraction is a part of the rainbow (0.0 - 1.0) = (Red-Yellow-Green-Cyan-Blue-Magenta-Red)
|
|
Packit Service |
c5cf8c |
* intensity (0.0 - 1.0) 0 = black, 1 = full color, 2 = white
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
double red, green, blue;
|
|
Packit Service |
c5cf8c |
int r, g, b;
|
|
Packit Service |
c5cf8c |
double dtemp;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
fraction = fabs(modf(fraction, &dtemp));
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (intensity > 2.0)
|
|
Packit Service |
c5cf8c |
intensity = 2.0;
|
|
Packit Service |
c5cf8c |
if (intensity < 0.0)
|
|
Packit Service |
c5cf8c |
intensity = 0.0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
dtemp = 1.0 / 6.0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (fraction < 1.0 / 6.0) {
|
|
Packit Service |
c5cf8c |
red = 1.0;
|
|
Packit Service |
c5cf8c |
green = fraction / dtemp;
|
|
Packit Service |
c5cf8c |
blue = 0.0;
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
if (fraction < 1.0 / 3.0) {
|
|
Packit Service |
c5cf8c |
red = 1.0 - ((fraction - dtemp) / dtemp);
|
|
Packit Service |
c5cf8c |
green = 1.0;
|
|
Packit Service |
c5cf8c |
blue = 0.0;
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
if (fraction < 0.5) {
|
|
Packit Service |
c5cf8c |
red = 0.0;
|
|
Packit Service |
c5cf8c |
green = 1.0;
|
|
Packit Service |
c5cf8c |
blue = (fraction - (dtemp * 2.0)) / dtemp;
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
if (fraction < 2.0 / 3.0) {
|
|
Packit Service |
c5cf8c |
red = 0.0;
|
|
Packit Service |
c5cf8c |
green = 1.0 - ((fraction - (dtemp * 3.0)) / dtemp);
|
|
Packit Service |
c5cf8c |
blue = 1.0;
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
if (fraction < 5.0 / 6.0) {
|
|
Packit Service |
c5cf8c |
red = (fraction - (dtemp * 4.0)) / dtemp;
|
|
Packit Service |
c5cf8c |
green = 0.0;
|
|
Packit Service |
c5cf8c |
blue = 1.0;
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
red = 1.0;
|
|
Packit Service |
c5cf8c |
green = 0.0;
|
|
Packit Service |
c5cf8c |
blue = 1.0 - ((fraction - (dtemp * 5.0)) / dtemp);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (intensity > 1) {
|
|
Packit Service |
c5cf8c |
intensity = intensity - 1.0;
|
|
Packit Service |
c5cf8c |
red = red + ((1.0 - red) * intensity);
|
|
Packit Service |
c5cf8c |
green = green + ((1.0 - green) * intensity);
|
|
Packit Service |
c5cf8c |
blue = blue + ((1.0 - blue) * intensity);
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
red = red * intensity;
|
|
Packit Service |
c5cf8c |
green = green * intensity;
|
|
Packit Service |
c5cf8c |
blue = blue * intensity;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
r = (int) (red * 255.0);
|
|
Packit Service |
c5cf8c |
g = (int) (green * 255.0);
|
|
Packit Service |
c5cf8c |
b = (int) (blue * 255.0);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return RGBtocolor_t(r, g, b);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int Make_color_array(int num_colors, color_t colors[])
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
double fraction, intensity;
|
|
Packit Service |
c5cf8c |
int i;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
intensity = 1.0;
|
|
Packit Service |
c5cf8c |
for (i = 0; i < num_colors; i++) {
|
|
Packit Service |
c5cf8c |
fraction = (double) i / (double) num_colors;
|
|
Packit Service |
c5cf8c |
colors[i] = getColor(fraction, intensity);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
return 0;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
void getRGB(color_t color, int *r, int *g, int *b)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
*r = getR(color);
|
|
Packit Service |
c5cf8c |
*g = getG(color);
|
|
Packit Service |
c5cf8c |
*b = getB(color);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
void read_mand_args(int argc, char *argv[], int *o_max_iterations,
|
|
Packit Service |
c5cf8c |
int *o_pixels_across, int *o_pixels_down,
|
|
Packit Service |
c5cf8c |
double *o_x_min, double *o_x_max,
|
|
Packit Service |
c5cf8c |
double *o_y_min, double *o_y_max, int *o_julia,
|
|
Packit Service |
c5cf8c |
double *o_julia_real_x, double *o_julia_imaginary_y,
|
|
Packit Service |
c5cf8c |
double *o_divergent_limit, int *o_alternate,
|
|
Packit Service |
c5cf8c |
char *filename, int *o_num_colors, int *use_stdin, int *save_image)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int i;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
*o_julia_real_x = NOVALUE;
|
|
Packit Service |
c5cf8c |
*o_julia_imaginary_y = NOVALUE;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* set defaults */
|
|
Packit Service |
c5cf8c |
*o_max_iterations = IDEAL_ITERATIONS;
|
|
Packit Service |
c5cf8c |
*o_pixels_across = IDEAL_WIDTH;
|
|
Packit Service |
c5cf8c |
*o_pixels_down = IDEAL_HEIGHT;
|
|
Packit Service |
c5cf8c |
*o_x_min = IDEAL_MIN_X_VALUE;
|
|
Packit Service |
c5cf8c |
*o_x_max = IDEAL_MAX_X_VALUE;
|
|
Packit Service |
c5cf8c |
*o_y_min = IDEAL_MIN_Y_VALUE;
|
|
Packit Service |
c5cf8c |
*o_y_max = IDEAL_MAX_Y_VALUE;
|
|
Packit Service |
c5cf8c |
*o_divergent_limit = INFINITE_LIMIT;
|
|
Packit Service |
c5cf8c |
strcpy(filename, default_filename);
|
|
Packit Service |
c5cf8c |
*o_num_colors = IDEAL_ITERATIONS;
|
|
Packit Service |
c5cf8c |
*use_stdin = 0; /* default is to listen for a controller */
|
|
Packit Service |
c5cf8c |
*save_image = NOVALUE;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
*o_julia = 0; /* default is "generate Mandelbrot" */
|
|
Packit Service |
c5cf8c |
*o_alternate = 0; /* default is still "generate Mandelbrot" */
|
|
Packit Service |
c5cf8c |
*o_divergent_limit = INFINITE_LIMIT; /* default total range is assumed
|
|
Packit Service |
c5cf8c |
* if not explicitly overwritten */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* We just cycle through all given parameters, matching what we can.
|
|
Packit Service |
c5cf8c |
* Note that we force casting, because we expect that a nonsensical
|
|
Packit Service |
c5cf8c |
* value is better than a poorly formatted one (fewer crashes), and
|
|
Packit Service |
c5cf8c |
* we'll later sort out the good from the bad
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
for (i = 0; i < argc; ++i) /* grab command line arguments */
|
|
Packit Service |
c5cf8c |
if (strcmp(argv[i], "-xmin\0") == 0 && argv[i + 1] != NULL)
|
|
Packit Service |
c5cf8c |
sscanf(argv[i + 1], "%lf", &*o_x_min);
|
|
Packit Service |
c5cf8c |
else if (strcmp(argv[i], "-xmax\0") == 0 && argv[i + 1] != NULL)
|
|
Packit Service |
c5cf8c |
sscanf(argv[i + 1], "%lf", &*o_x_max);
|
|
Packit Service |
c5cf8c |
else if (strcmp(argv[i], "-ymin\0") == 0 && argv[i + 1] != NULL)
|
|
Packit Service |
c5cf8c |
sscanf(argv[i + 1], "%lf", &*o_y_min);
|
|
Packit Service |
c5cf8c |
else if (strcmp(argv[i], "-ymax\0") == 0 && argv[i + 1] != NULL)
|
|
Packit Service |
c5cf8c |
sscanf(argv[i + 1], "%lf", &*o_y_max);
|
|
Packit Service |
c5cf8c |
else if (strcmp(argv[i], "-depth\0") == 0 && argv[i + 1] != NULL)
|
|
Packit Service |
c5cf8c |
sscanf(argv[i + 1], "%d", &*o_max_iterations);
|
|
Packit Service |
c5cf8c |
else if (strcmp(argv[i], "-xscale\0") == 0 && argv[i + 1] != NULL)
|
|
Packit Service |
c5cf8c |
sscanf(argv[i + 1], "%d", &*o_pixels_across);
|
|
Packit Service |
c5cf8c |
else if (strcmp(argv[i], "-yscale\0") == 0 && argv[i + 1] != NULL)
|
|
Packit Service |
c5cf8c |
sscanf(argv[i + 1], "%d", &*o_pixels_down);
|
|
Packit Service |
c5cf8c |
else if (strcmp(argv[i], "-diverge\0") == 0 && argv[i + 1] != NULL)
|
|
Packit Service |
c5cf8c |
sscanf(argv[i + 1], "%lf", &*o_divergent_limit);
|
|
Packit Service |
c5cf8c |
else if (strcmp(argv[i], "-jx\0") == 0 && argv[i + 1] != NULL)
|
|
Packit Service |
c5cf8c |
sscanf(argv[i + 1], "%lf", &*o_julia_real_x);
|
|
Packit Service |
c5cf8c |
else if (strcmp(argv[i], "-jy\0") == 0 && argv[i + 1] != NULL)
|
|
Packit Service |
c5cf8c |
sscanf(argv[i + 1], "%lf", &*o_julia_imaginary_y);
|
|
Packit Service |
c5cf8c |
else if (strcmp(argv[i], "-alternate\0") == 0 && argv[i + 1] != NULL)
|
|
Packit Service |
c5cf8c |
sscanf(argv[i + 1], "%d", &*o_alternate);
|
|
Packit Service |
c5cf8c |
else if (strcmp(argv[i], "-julia\0") == 0)
|
|
Packit Service |
c5cf8c |
*o_julia = 1;
|
|
Packit Service |
c5cf8c |
else if (strcmp(argv[i], "-out\0") == 0 && argv[i + 1] != NULL)
|
|
Packit Service |
c5cf8c |
strcpy(filename, argv[i + 1]);
|
|
Packit Service |
c5cf8c |
else if (strcmp(argv[i], "-colors\0") == 0 && argv[i + 1] != NULL)
|
|
Packit Service |
c5cf8c |
sscanf(argv[i + 1], "%d", &*o_num_colors);
|
|
Packit Service |
c5cf8c |
else if (strcmp(argv[i], "-i\0") == 0)
|
|
Packit Service |
c5cf8c |
*use_stdin = 1;
|
|
Packit Service |
c5cf8c |
else if (strcmp(argv[i], "-save\0") == 0)
|
|
Packit Service |
c5cf8c |
*save_image = 1;
|
|
Packit Service |
c5cf8c |
else if (strcmp(argv[i], "-nosave\0") == 0)
|
|
Packit Service |
c5cf8c |
*save_image = 0;
|
|
Packit Service |
c5cf8c |
else if (strcmp(argv[i], "-help\0") == 0) {
|
|
Packit Service |
c5cf8c |
PrintUsage();
|
|
Packit Service |
c5cf8c |
MPI_Finalize();
|
|
Packit Service |
c5cf8c |
exit(0);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (*save_image == NOVALUE) {
|
|
Packit Service |
c5cf8c |
if (*use_stdin == 1)
|
|
Packit Service |
c5cf8c |
*save_image = 1;
|
|
Packit Service |
c5cf8c |
else
|
|
Packit Service |
c5cf8c |
*save_image = 0;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
#if DEBUG2
|
|
Packit Service |
c5cf8c |
if (myid == 0) {
|
|
Packit Service |
c5cf8c |
printf("Doing %d iterations over (%.2lf:%.2lf,%.2lf:%.2lf) on a %d x %d grid\n",
|
|
Packit Service |
c5cf8c |
*o_max_iterations, *o_x_min, *o_x_max, *o_y_min, *o_y_max,
|
|
Packit Service |
c5cf8c |
*o_pixels_across, *o_pixels_down);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
void check_mand_params(int *m_max_iterations,
|
|
Packit Service |
c5cf8c |
int *m_pixels_across, int *m_pixels_down,
|
|
Packit Service |
c5cf8c |
double *m_x_min, double *m_x_max,
|
|
Packit Service |
c5cf8c |
double *m_y_min, double *m_y_max, double *m_divergent_limit)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
/* Get first batch of limits */
|
|
Packit Service |
c5cf8c |
#if PROMPT
|
|
Packit Service |
c5cf8c |
if (*m_x_min == NOVALUE || *m_x_max == NOVALUE) {
|
|
Packit Service |
c5cf8c |
/* grab unspecified limits */
|
|
Packit Service |
c5cf8c |
printf("Enter lower and higher limits on x (within -1 to 1): ");
|
|
Packit Service |
c5cf8c |
scanf("%lf %lf", &*m_x_min, &*m_x_max);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (*m_y_min == NOVALUE || *m_y_max == NOVALUE) {
|
|
Packit Service |
c5cf8c |
/* grab unspecified limits */
|
|
Packit Service |
c5cf8c |
printf("Enter lower and higher limits on y (within -1 to 1): ");
|
|
Packit Service |
c5cf8c |
scanf("%lf %lf", &*m_y_min, &*m_y_max);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Verify limits are reasonable */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (*m_x_min < MIN_X_VALUE || *m_x_min > *m_x_max) {
|
|
Packit Service |
c5cf8c |
printf("Chosen lower x limit is too low, resetting to %lf\n", MIN_X_VALUE);
|
|
Packit Service |
c5cf8c |
*m_x_min = MIN_X_VALUE;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
if (*m_x_max > MAX_X_VALUE || *m_x_max <= *m_x_min) {
|
|
Packit Service |
c5cf8c |
printf("Chosen upper x limit is too high, resetting to %lf\n", MAX_X_VALUE);
|
|
Packit Service |
c5cf8c |
*m_x_max = MAX_X_VALUE;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
if (*m_y_min < MIN_Y_VALUE || *m_y_min > *m_y_max) {
|
|
Packit Service |
c5cf8c |
printf("Chosen lower y limit is too low, resetting to %lf\n", MIN_Y_VALUE);
|
|
Packit Service |
c5cf8c |
*m_y_min = MIN_Y_VALUE;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
if (*m_y_max > MAX_Y_VALUE || *m_y_max <= *m_y_min) {
|
|
Packit Service |
c5cf8c |
printf("Chosen upper y limit is too high, resetting to %lf\n", MAX_Y_VALUE);
|
|
Packit Service |
c5cf8c |
*m_y_max = MAX_Y_VALUE;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Get second set of limits */
|
|
Packit Service |
c5cf8c |
#if PROMPT
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (*m_max_iterations == NOVALUE) {
|
|
Packit Service |
c5cf8c |
/* grab unspecified limit */
|
|
Packit Service |
c5cf8c |
printf("Enter max interations to do: ");
|
|
Packit Service |
c5cf8c |
scanf("%d", &*m_max_iterations);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Verify second set of limits */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (*m_max_iterations > MAX_ITERATIONS || *m_max_iterations < 0) {
|
|
Packit Service |
c5cf8c |
printf("Warning, unreasonable number of iterations, setting to %d\n", MAX_ITERATIONS);
|
|
Packit Service |
c5cf8c |
*m_max_iterations = MAX_ITERATIONS;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Get third set of limits */
|
|
Packit Service |
c5cf8c |
#if PROMPT
|
|
Packit Service |
c5cf8c |
if (*m_pixels_across == NOVALUE || *m_pixels_down == NOVALUE) {
|
|
Packit Service |
c5cf8c |
/* grab unspecified limits */
|
|
Packit Service |
c5cf8c |
printf("Enter pixel size (horizonal by vertical, i.e. 256 256): ");
|
|
Packit Service |
c5cf8c |
scanf(" %d %d", &*m_pixels_across, &*m_pixels_down);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Verify third set of limits */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (*m_pixels_across > MAX_WIDTH) {
|
|
Packit Service |
c5cf8c |
printf("Warning, image requested is too wide, setting to %d pixel width\n", MAX_WIDTH);
|
|
Packit Service |
c5cf8c |
*m_pixels_across = MAX_WIDTH;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
if (*m_pixels_down > MAX_HEIGHT) {
|
|
Packit Service |
c5cf8c |
printf("Warning, image requested is too tall, setting to %d pixel height\n", MAX_HEIGHT);
|
|
Packit Service |
c5cf8c |
*m_pixels_down = MAX_HEIGHT;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
#if DEBUG2
|
|
Packit Service |
c5cf8c |
printf("%d iterations over (%.2lf:%.2lf,%.2lf:%.2lf), %d x %d grid, diverge value %lf\n",
|
|
Packit Service |
c5cf8c |
*m_max_iterations, *m_x_min, *m_x_max, *m_y_min, *m_y_max,
|
|
Packit Service |
c5cf8c |
*m_pixels_across, *m_pixels_down, *m_divergent_limit);
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
void check_julia_params(double *julia_x_constant, double *julia_y_constant)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Hey, we're not stupid-- if they must Prompt, we will also be Noisy */
|
|
Packit Service |
c5cf8c |
#if PROMPT
|
|
Packit Service |
c5cf8c |
if (*julia_x_constant == NOVALUE || *julia_y_constant == NOVALUE) {
|
|
Packit Service |
c5cf8c |
/* grab unspecified limits */
|
|
Packit Service |
c5cf8c |
printf("Enter Coordinates for Julia expansion: ");
|
|
Packit Service |
c5cf8c |
scanf("%lf %lf", &*julia_x_constant, &*julia_y_constant);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#if DEBUG2
|
|
Packit Service |
c5cf8c |
/* In theory, any point can be investigated, although it's not much point
|
|
Packit Service |
c5cf8c |
* if it's outside of the area viewed. But, hey, that's not our problem */
|
|
Packit Service |
c5cf8c |
printf("Exploring julia set around (%lf, %lf)\n", *julia_x_constant, *julia_y_constant);
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* This is a Mandelbrot variant, solving the code for the equation:
|
|
Packit Service |
c5cf8c |
z = z(1-z)
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* This routine takes a complex coordinate point (x+iy) and a value stating
|
|
Packit Service |
c5cf8c |
what the upper limit to the number of iterations is. It eventually
|
|
Packit Service |
c5cf8c |
returns an integer of how many counts the code iterated for within
|
|
Packit Service |
c5cf8c |
the given point/region until the exit condition (abs(x+iy) > limit) was met.
|
|
Packit Service |
c5cf8c |
This value is returned as an integer.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int subtractive_mandelbrot_point(complex_t coord_point,
|
|
Packit Service |
c5cf8c |
complex_t c_constant, int Max_iterations, double divergent_limit)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
complex_t z_point, a_point; /* we need 2 pts to use in our calculation */
|
|
Packit Service |
c5cf8c |
int num_iterations; /* a counter to track the number of iterations done */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
num_iterations = 0; /* zero our counter */
|
|
Packit Service |
c5cf8c |
z_point = coord_point; /* initialize to the given start coordinate */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* loop while the absolute value of the complex coordinate is < our limit
|
|
Packit Service |
c5cf8c |
* (for a mandelbrot) or until we've done our specified maximum number of
|
|
Packit Service |
c5cf8c |
* iterations (both julia and mandelbrot) */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
while (absolute_complex(z_point) < divergent_limit && num_iterations < Max_iterations) {
|
|
Packit Service |
c5cf8c |
/* z = z(1-z) */
|
|
Packit Service |
c5cf8c |
a_point.real = 1.0;
|
|
Packit Service |
c5cf8c |
a_point.imaginary = 0.0; /* make "1" */
|
|
Packit Service |
c5cf8c |
a_point = subtract_complex(a_point, z_point);
|
|
Packit Service |
c5cf8c |
z_point = multiply_complex(z_point, a_point);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
++num_iterations;
|
|
Packit Service |
c5cf8c |
} /* done iterating for one point */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return num_iterations;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* This is a Mandelbrot variant, solving the code for the equation:
|
|
Packit Service |
c5cf8c |
z = z(z+c)
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* This routine takes a complex coordinate point (x+iy) and a value stating
|
|
Packit Service |
c5cf8c |
what the upper limit to the number of iterations is. It eventually
|
|
Packit Service |
c5cf8c |
returns an integer of how many counts the code iterated for within
|
|
Packit Service |
c5cf8c |
the given point/region until the exit condition (abs(x+iy) > limit) was met.
|
|
Packit Service |
c5cf8c |
This value is returned as an integer.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int additive_mandelbrot_point(complex_t coord_point,
|
|
Packit Service |
c5cf8c |
complex_t c_constant, int Max_iterations, double divergent_limit)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
complex_t z_point, a_point; /* we need 2 pts to use in our calculation */
|
|
Packit Service |
c5cf8c |
int num_iterations; /* a counter to track the number of iterations done */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
num_iterations = 0; /* zero our counter */
|
|
Packit Service |
c5cf8c |
z_point = coord_point; /* initialize to the given start coordinate */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* loop while the absolute value of the complex coordinate is < our limit
|
|
Packit Service |
c5cf8c |
* (for a mandelbrot) or until we've done our specified maximum number of
|
|
Packit Service |
c5cf8c |
* iterations (both julia and mandelbrot) */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
while (absolute_complex(z_point) < divergent_limit && num_iterations < Max_iterations) {
|
|
Packit Service |
c5cf8c |
/* z = z(z+C) */
|
|
Packit Service |
c5cf8c |
a_point = add_complex(z_point, coord_point);
|
|
Packit Service |
c5cf8c |
z_point = multiply_complex(z_point, a_point);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
++num_iterations;
|
|
Packit Service |
c5cf8c |
} /* done iterating for one point */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return num_iterations;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* This is a Mandelbrot variant, solving the code for the equation:
|
|
Packit Service |
c5cf8c |
z = z(z+1)
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* This routine takes a complex coordinate point (x+iy) and a value stating
|
|
Packit Service |
c5cf8c |
what the upper limit to the number of iterations is. It eventually
|
|
Packit Service |
c5cf8c |
returns an integer of how many counts the code iterated for within
|
|
Packit Service |
c5cf8c |
the given point/region until the exit condition (abs(x+iy) > limit) was met.
|
|
Packit Service |
c5cf8c |
This value is returned as an integer.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int exponential_mandelbrot_point(complex_t coord_point,
|
|
Packit Service |
c5cf8c |
complex_t c_constant, int Max_iterations, double divergent_limit)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
complex_t z_point, a_point; /* we need 2 pts to use in our calculation */
|
|
Packit Service |
c5cf8c |
int num_iterations; /* a counter to track the number of iterations done */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
num_iterations = 0; /* zero our counter */
|
|
Packit Service |
c5cf8c |
z_point = coord_point; /* initialize to the given start coordinate */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* loop while the absolute value of the complex coordinate is < our limit
|
|
Packit Service |
c5cf8c |
* (for a mandelbrot) or until we've done our specified maximum number of
|
|
Packit Service |
c5cf8c |
* iterations (both julia and mandelbrot) */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
while (absolute_complex(z_point) < divergent_limit && num_iterations < Max_iterations) {
|
|
Packit Service |
c5cf8c |
/* z = z(1-z) */
|
|
Packit Service |
c5cf8c |
a_point.real = 1.0;
|
|
Packit Service |
c5cf8c |
a_point.imaginary = 0.0; /* make "1" */
|
|
Packit Service |
c5cf8c |
a_point = subtract_complex(a_point, z_point);
|
|
Packit Service |
c5cf8c |
z_point = multiply_complex(z_point, a_point);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
++num_iterations;
|
|
Packit Service |
c5cf8c |
} /* done iterating for one point */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return num_iterations;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
void complex_points_to_image(complex_t in_julia_coord_set[],
|
|
Packit Service |
c5cf8c |
int in_julia_set_size,
|
|
Packit Service |
c5cf8c |
int i_pixels_across, int i_pixels_down,
|
|
Packit Service |
c5cf8c |
int *out_image_final, int *out_max_colors)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int i, i_temp_quantize;
|
|
Packit Service |
c5cf8c |
double x_resolution_element, y_resolution_element, temp_quantize;
|
|
Packit Service |
c5cf8c |
double x_max, x_min, y_max, y_min;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Convert the complex points into an image--
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* first, find the min and max for each axis. */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
x_min = in_julia_coord_set[0].real;
|
|
Packit Service |
c5cf8c |
x_max = x_min;
|
|
Packit Service |
c5cf8c |
y_min = in_julia_coord_set[0].imaginary;
|
|
Packit Service |
c5cf8c |
y_max = y_min;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
for (i = 0; i < in_julia_set_size; ++i) {
|
|
Packit Service |
c5cf8c |
if (in_julia_coord_set[i].real < x_min)
|
|
Packit Service |
c5cf8c |
x_min = in_julia_coord_set[i].real;
|
|
Packit Service |
c5cf8c |
if (in_julia_coord_set[i].real > x_max)
|
|
Packit Service |
c5cf8c |
x_max = in_julia_coord_set[i].real;
|
|
Packit Service |
c5cf8c |
if (in_julia_coord_set[i].imaginary < y_min)
|
|
Packit Service |
c5cf8c |
y_min = in_julia_coord_set[i].imaginary;
|
|
Packit Service |
c5cf8c |
if (in_julia_coord_set[i].imaginary > y_max)
|
|
Packit Service |
c5cf8c |
y_max = in_julia_coord_set[i].imaginary;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* convert to fit image grid size: */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
x_resolution_element = (x_max - x_min) / (double) i_pixels_across;
|
|
Packit Service |
c5cf8c |
y_resolution_element = (y_max - y_min) / (double) i_pixels_down;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#ifdef DEBUG
|
|
Packit Service |
c5cf8c |
printf("%lf %lf\n", x_resolution_element, y_resolution_element);
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* now we can put each point into a grid space, and up the count of
|
|
Packit Service |
c5cf8c |
* said grid. Since calloc initialized it to zero, this is safe */
|
|
Packit Service |
c5cf8c |
/* A point x,y goes to grid region i,j, where
|
|
Packit Service |
c5cf8c |
* xi = (x-xmin)/x_resolution (position relative to far left)
|
|
Packit Service |
c5cf8c |
* yj = (ymax-y)/y_resolution (position relative to top)
|
|
Packit Service |
c5cf8c |
* This gets mapped to our 1-d array as xi + yj*i_pixels_across,
|
|
Packit Service |
c5cf8c |
* taken as an integer (rounding down) and checking array limits
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
for (i = 0; i < in_julia_set_size; ++i) {
|
|
Packit Service |
c5cf8c |
temp_quantize =
|
|
Packit Service |
c5cf8c |
(in_julia_coord_set[i].real - x_min) / x_resolution_element +
|
|
Packit Service |
c5cf8c |
(y_max - in_julia_coord_set[i].imaginary) / y_resolution_element *
|
|
Packit Service |
c5cf8c |
(double) i_pixels_across;
|
|
Packit Service |
c5cf8c |
i_temp_quantize = (int) temp_quantize;
|
|
Packit Service |
c5cf8c |
if (i_temp_quantize > i_pixels_across * i_pixels_down)
|
|
Packit Service |
c5cf8c |
i_temp_quantize = i_pixels_across * i_pixels_down;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#ifdef DEBUG
|
|
Packit Service |
c5cf8c |
printf("%d %lf %lf %lf %lf %lf %lf %lf\n",
|
|
Packit Service |
c5cf8c |
i_temp_quantize, temp_quantize, x_min, x_resolution_element,
|
|
Packit Service |
c5cf8c |
in_julia_coord_set[i].real, y_max, y_resolution_element,
|
|
Packit Service |
c5cf8c |
in_julia_coord_set[i].imaginary);
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
++out_image_final[i_temp_quantize];
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* find the highest value (most occupied bin) */
|
|
Packit Service |
c5cf8c |
*out_max_colors = 0;
|
|
Packit Service |
c5cf8c |
for (i = 0; i < i_pixels_across * i_pixels_down; ++i) {
|
|
Packit Service |
c5cf8c |
if (out_image_final[i] > *out_max_colors) {
|
|
Packit Service |
c5cf8c |
*out_max_colors = out_image_final[i];
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
complex_t exponential_complex(complex_t in_complex)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
complex_t out_complex;
|
|
Packit Service |
c5cf8c |
double e_to_x;
|
|
Packit Service |
c5cf8c |
/* taking the exponential, e^(x+iy) = e^xe^iy = e^x(cos(y)+isin(y) */
|
|
Packit Service |
c5cf8c |
e_to_x = exp(in_complex.real);
|
|
Packit Service |
c5cf8c |
out_complex.real = e_to_x * cos(in_complex.imaginary);
|
|
Packit Service |
c5cf8c |
out_complex.imaginary = e_to_x * sin(in_complex.imaginary);
|
|
Packit Service |
c5cf8c |
return out_complex;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
complex_t multiply_complex(complex_t in_one_complex, complex_t in_two_complex)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
complex_t out_complex;
|
|
Packit Service |
c5cf8c |
/* multiplying complex variables-- (x+iy) * (a+ib) = xa - yb + i(xb + ya) */
|
|
Packit Service |
c5cf8c |
out_complex.real = in_one_complex.real * in_two_complex.real -
|
|
Packit Service |
c5cf8c |
in_one_complex.imaginary * in_two_complex.imaginary;
|
|
Packit Service |
c5cf8c |
out_complex.imaginary = in_one_complex.real * in_two_complex.imaginary +
|
|
Packit Service |
c5cf8c |
in_one_complex.imaginary * in_two_complex.real;
|
|
Packit Service |
c5cf8c |
return out_complex;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
complex_t divide_complex(complex_t in_one_complex, complex_t in_two_complex)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
complex_t out_complex;
|
|
Packit Service |
c5cf8c |
double divider;
|
|
Packit Service |
c5cf8c |
/* dividing complex variables-- (x+iy)/(a+ib) = (xa - yb)/(a^2+b^2)
|
|
Packit Service |
c5cf8c |
* + i (y*a-x*b)/(a^2+b^2) */
|
|
Packit Service |
c5cf8c |
divider = (in_two_complex.real * in_two_complex.real -
|
|
Packit Service |
c5cf8c |
in_two_complex.imaginary * in_two_complex.imaginary);
|
|
Packit Service |
c5cf8c |
out_complex.real = (in_one_complex.real * in_two_complex.real -
|
|
Packit Service |
c5cf8c |
in_one_complex.imaginary * in_two_complex.imaginary) / divider;
|
|
Packit Service |
c5cf8c |
out_complex.imaginary = (in_one_complex.imaginary * in_two_complex.real -
|
|
Packit Service |
c5cf8c |
in_one_complex.real * in_two_complex.imaginary) / divider;
|
|
Packit Service |
c5cf8c |
return out_complex;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
complex_t inverse_complex(complex_t in_complex)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
complex_t out_complex;
|
|
Packit Service |
c5cf8c |
double divider;
|
|
Packit Service |
c5cf8c |
/* inverting a complex variable: 1/(x+iy) */
|
|
Packit Service |
c5cf8c |
divider = (in_complex.real * in_complex.real - in_complex.imaginary * in_complex.imaginary);
|
|
Packit Service |
c5cf8c |
out_complex.real = (in_complex.real - in_complex.imaginary) / divider;
|
|
Packit Service |
c5cf8c |
out_complex.imaginary = (in_complex.real - in_complex.imaginary) / divider;
|
|
Packit Service |
c5cf8c |
return out_complex;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
complex_t add_complex(complex_t in_one_complex, complex_t in_two_complex)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
complex_t out_complex;
|
|
Packit Service |
c5cf8c |
/* adding complex variables-- do by component */
|
|
Packit Service |
c5cf8c |
out_complex.real = in_one_complex.real + in_two_complex.real;
|
|
Packit Service |
c5cf8c |
out_complex.imaginary = in_one_complex.imaginary + in_two_complex.imaginary;
|
|
Packit Service |
c5cf8c |
return out_complex;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
complex_t subtract_complex(complex_t in_one_complex, complex_t in_two_complex)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
complex_t out_complex;
|
|
Packit Service |
c5cf8c |
/* subtracting complex variables-- do by component */
|
|
Packit Service |
c5cf8c |
out_complex.real = in_one_complex.real - in_two_complex.real;
|
|
Packit Service |
c5cf8c |
out_complex.imaginary = in_one_complex.imaginary - in_two_complex.imaginary;
|
|
Packit Service |
c5cf8c |
return out_complex;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
double absolute_complex(complex_t in_complex)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
double out_double;
|
|
Packit Service |
c5cf8c |
/* absolute value is (for x+yi) sqrt(x^2 + y^2) */
|
|
Packit Service |
c5cf8c |
out_double =
|
|
Packit Service |
c5cf8c |
sqrt(in_complex.real * in_complex.real + in_complex.imaginary * in_complex.imaginary);
|
|
Packit Service |
c5cf8c |
return out_double;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* This routine takes a complex coordinate point (x+iy) and a value stating
|
|
Packit Service |
c5cf8c |
what the upper limit to the number of iterations is. It eventually
|
|
Packit Service |
c5cf8c |
returns an integer of how many counts the code iterated for within
|
|
Packit Service |
c5cf8c |
the given point/region until the exit condition (abs(x+iy) > limit) was met.
|
|
Packit Service |
c5cf8c |
This value is returned as an integer.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int single_mandelbrot_point(complex_t coord_point,
|
|
Packit Service |
c5cf8c |
complex_t c_constant, int Max_iterations, double divergent_limit)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
complex_t z_point; /* we need a point to use in our calculation */
|
|
Packit Service |
c5cf8c |
int num_iterations; /* a counter to track the number of iterations done */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
num_iterations = 0; /* zero our counter */
|
|
Packit Service |
c5cf8c |
z_point = coord_point; /* initialize to the given start coordinate */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* loop while the absolute value of the complex coordinate is < our limit
|
|
Packit Service |
c5cf8c |
* (for a mandelbrot) or until we've done our specified maximum number of
|
|
Packit Service |
c5cf8c |
* iterations (both julia and mandelbrot) */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
while (absolute_complex(z_point) < divergent_limit && num_iterations < Max_iterations) {
|
|
Packit Service |
c5cf8c |
/* z = z*z + c */
|
|
Packit Service |
c5cf8c |
z_point = multiply_complex(z_point, z_point);
|
|
Packit Service |
c5cf8c |
z_point = add_complex(z_point, c_constant);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
++num_iterations;
|
|
Packit Service |
c5cf8c |
} /* done iterating for one point */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return num_iterations;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
void output_data(int *in_grid_array, int coord[4], int *out_grid_array, int width, int height)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int i, j, k;
|
|
Packit Service |
c5cf8c |
int result;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
k = 0;
|
|
Packit Service |
c5cf8c |
for (j = coord[2]; j <= coord[3]; j++) {
|
|
Packit Service |
c5cf8c |
for (i = coord[0]; i <= coord[1]; i++) {
|
|
Packit Service |
c5cf8c |
out_grid_array[(j * height) + i] = in_grid_array[k];
|
|
Packit Service |
c5cf8c |
k++;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
if (!use_stdin) {
|
|
Packit Service |
c5cf8c |
result = MPI_Send(coord, 4, MPI_INT, 0, 0, comm);
|
|
Packit Service |
c5cf8c |
if (result != MPI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
printf("Unable to send coordinates to the visualizer, aborting.\n");
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
result =
|
|
Packit Service |
c5cf8c |
MPI_Send(in_grid_array, (coord[1] + 1 - coord[0]) * (coord[3] + 1 - coord[2]), MPI_INT,
|
|
Packit Service |
c5cf8c |
0, 0, comm);
|
|
Packit Service |
c5cf8c |
if (result != MPI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
printf("Unable to send coordinate data to the visualizer, aborting.\n");
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Writes out a linear integer array of grayscale pixel values to a
|
|
Packit Service |
c5cf8c |
pgm-format file (with header). The exact format details are given
|
|
Packit Service |
c5cf8c |
at the end of this routine in case you don't have the man pages
|
|
Packit Service |
c5cf8c |
installed locally. Essentially, it's a 2-dimensional integer array
|
|
Packit Service |
c5cf8c |
of pixel grayscale values. Very easy to manipulate externally.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* You need the following inputs:
|
|
Packit Service |
c5cf8c |
A linear integer array with the actual pixel values (read in as
|
|
Packit Service |
c5cf8c |
consecutive rows),
|
|
Packit Service |
c5cf8c |
The width and height of the grid, and
|
|
Packit Service |
c5cf8c |
The maximum pixel value (to set greyscale range). We are assuming
|
|
Packit Service |
c5cf8c |
that the lowest value is "0".
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
void dumpimage(char *filename, int in_grid_array[], int in_pixels_across, int in_pixels_down,
|
|
Packit Service |
c5cf8c |
int in_max_pixel_value, char input_string[], int num_colors, color_t colors[])
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
FILE *ifp;
|
|
Packit Service |
c5cf8c |
int i, j, k;
|
|
Packit Service |
c5cf8c |
#ifdef USE_PPM
|
|
Packit Service |
c5cf8c |
int r, g, b;
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
printf("%s\nwidth: %d\nheight: %d\ncolors: %d\nstr: %s\n",
|
|
Packit Service |
c5cf8c |
filename, in_pixels_across, in_pixels_down, num_colors, input_string);
|
|
Packit Service |
c5cf8c |
fflush(stdout);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if ((ifp = fopen(filename, "w")) == NULL) {
|
|
Packit Service |
c5cf8c |
printf("Error, could not open output file\n");
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit Service |
c5cf8c |
exit(-1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
#ifdef USE_PPM
|
|
Packit Service |
c5cf8c |
fprintf(ifp, "P3\n"); /* specifies type of file, in this case ppm */
|
|
Packit Service |
c5cf8c |
fprintf(ifp, "# %s\n", input_string); /* an arbitrary file identifier */
|
|
Packit Service |
c5cf8c |
/* now give the file size in pixels by pixels */
|
|
Packit Service |
c5cf8c |
fprintf(ifp, "%d %d\n", in_pixels_across, in_pixels_down);
|
|
Packit Service |
c5cf8c |
/* give the max r,g,b level */
|
|
Packit Service |
c5cf8c |
fprintf(ifp, "255\n");
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
k = 0; /* counter for the linear array of the final image */
|
|
Packit Service |
c5cf8c |
/* assumes first point is upper left corner (element 0 of array) */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (in_max_pixel_value < 1) {
|
|
Packit Service |
c5cf8c |
for (j = 0; j < in_pixels_down; ++j) { /* start at the top row and work down */
|
|
Packit Service |
c5cf8c |
for (i = 0; i < in_pixels_across; ++i) { /* go along the row */
|
|
Packit Service |
c5cf8c |
fprintf(ifp, "0 0 0 ");
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
fprintf(ifp, "\n"); /* done writing one row, begin next line */
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
for (j = 0; j < in_pixels_down; ++j) { /* start at the top row and work down */
|
|
Packit Service |
c5cf8c |
for (i = 0; i < in_pixels_across; ++i) { /* go along the row */
|
|
Packit Service |
c5cf8c |
getRGB(colors[(in_grid_array[k] * num_colors) / in_max_pixel_value], &r, &g, &b);
|
|
Packit Service |
c5cf8c |
fprintf(ifp, "%d %d %d ", r, g, b); /* +1 since 0 = first color */
|
|
Packit Service |
c5cf8c |
++k;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
fprintf(ifp, "\n"); /* done writing one row, begin next line */
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
#else
|
|
Packit Service |
c5cf8c |
fprintf(ifp, "P2\n"); /* specifies type of file, in this case pgm */
|
|
Packit Service |
c5cf8c |
fprintf(ifp, "# %s\n", input_string); /* an arbitrary file identifier */
|
|
Packit Service |
c5cf8c |
/* now give the file size in pixels by pixels */
|
|
Packit Service |
c5cf8c |
fprintf(ifp, "%d %d\n", in_pixels_across, in_pixels_down);
|
|
Packit Service |
c5cf8c |
/* gives max number of grayscale levels */
|
|
Packit Service |
c5cf8c |
fprintf(ifp, "%d\n", in_max_pixel_value + 1); /* plus 1 because 0=first color */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
k = 0; /* counter for the linear array of the final image */
|
|
Packit Service |
c5cf8c |
/* assumes first point is upper left corner (element 0 of array) */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
for (j = 0; j < in_pixels_down; ++j) { /* start at the top row and work down */
|
|
Packit Service |
c5cf8c |
for (i = 0; i < in_pixels_across; ++i) { /* go along the row */
|
|
Packit Service |
c5cf8c |
fprintf(ifp, "%d ", in_grid_array[k] + 1); /* +1 since 0 = first color */
|
|
Packit Service |
c5cf8c |
++k;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
fprintf(ifp, "\n"); /* done writing one row, begin next line */
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
fclose(ifp);
|
|
Packit Service |
c5cf8c |
}
|