Commit 3fc531d5 authored by Andreas Kempe's avatar Andreas Kempe

Added forgotten files.

parent 0df3feb5
#include "mandelbrot.h"
#include <mpi.h>
#include <iostream>
#include <Magick++.h>
#include <complex>
#include <cmath>
#include <sstream>
#include <iomanip>
#define IMG_WIDTH 1064lu
#define IMG_HEIGHT 800lu
#define ITERATIONS 200lu
#define RE_MAX 1
#define RE_MIN -2
#define IM_MAX 1.4
#define IM_MIN -1.3
using namespace std;
using namespace Magick;
int main(int argc, char** argv)
{
int id;
int procs;
unsigned long *calculated_values;
unsigned long *receive_buffer = nullptr;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &procs);
MPI_Comm_rank(MPI_COMM_WORLD, &id);
unsigned long effective_height = IMG_HEIGHT / procs;
mandel_settings settings = { .re_max = RE_MAX,
.re_min = RE_MIN,
.im_max = get_max_im(IM_MAX, IM_MIN, id, procs),
.im_min = get_min_im(IM_MAX, IM_MIN, id, procs),
.img_width = IMG_WIDTH,
.img_height = effective_height,
.iterations = ITERATIONS };
mandelbrot mandel(settings);
mandel.calculate_set();
if (id == 0)
receive_buffer = new unsigned long[IMG_WIDTH * IMG_HEIGHT];
cout << "Process: " << id << ", Gathering!" << endl;
MPI_Gather(mandel.get_point_array(), IMG_WIDTH * effective_height, MPI_UNSIGNED_LONG, receive_buffer,
IMG_WIDTH * effective_height, MPI_UNSIGNED_LONG, 0, MPI_COMM_WORLD);
cout << "Process: " << id << ", done gathering!" << endl;
if (id == 0)
{
Image my_image(Geometry(IMG_WIDTH, IMG_HEIGHT), "white");
my_image.modifyImage();
Pixels pixel_cache(my_image);
PixelPacket *pixels = pixel_cache.get(0, 0, IMG_WIDTH, IMG_HEIGHT);
cout << "Assembling image!" << endl;
for (unsigned long y = 0; y < IMG_HEIGHT; ++y)
{
cout << "Progress: " << setprecision(3) <<
static_cast<float>(y * 100) / IMG_HEIGHT << " % \r" << flush;
for (unsigned long x = 0; x < IMG_WIDTH; ++x)
{
const unsigned long& iter_res = receive_buffer[y * IMG_WIDTH + x];
if (iter_res == ITERATIONS)
pixels[y * IMG_WIDTH + x] = Color(MaxRGB * 0.55, MaxRGB * 0.35, MaxRGB * 0.6);
else
pixels[y * IMG_WIDTH + x] = Color(MaxRGB * cosf(exp(iter_res)), 0, MaxRGB * sinf(exp(iter_res)));
}
}
pixel_cache.sync();
cout << "Progress: 100 % " << endl;
stringstream ss;
ss << "output.png";
cout << "Saving image!" << endl;
my_image.write(ss.str());
}
delete[] calculated_values;
delete[] receive_buffer;
MPI_Finalize();
}
#include "mandelbrot.h"
#include <stdexcept>
#include <iostream>
using namespace std;
mandelbrot::mandelbrot(mandel_settings settings)
{
re_max = settings.re_max;
re_min = settings.re_min;
im_max = settings.im_max;
im_min = settings.im_min;
img_width = settings.img_width;
img_height = settings.img_height;
iterations = settings.iterations;
calculated_points = new unsigned long[img_width * img_height];
}
mandelbrot::~mandelbrot()
{
delete[] calculated_points;
}
complex<double> mandelbrot::get_pixel_coordinate(int x, int y) const
{
double re_size = fabs(re_max - re_min);
double im_size = fabs(im_max - im_min);
double re_pp = re_size / img_width;
double im_pp = im_size / img_height;
return complex<double>(re_pp * x + re_min, im_pp * y + im_min);
}
unsigned long mandelbrot::is_mandelbrot_point(unsigned long x, unsigned long y, unsigned long iterations) const
{
complex<double> point = get_pixel_coordinate(x, y);
complex<double> series_value(0, 0);
for (unsigned long i = 0; i < iterations; ++i)
{
if (real(series_value) * real(series_value) + imag(series_value) * imag(series_value) >= 4)
return i + 1 - log(log(abs(pow(series_value, 2) + point))) / log(2);
series_value = pow(series_value, 2) + point;
}
return iterations;
}
void mandelbrot::calculate_set()
{
for (unsigned long y = 0; y < img_height; ++y)
{
for (unsigned long x = 0; x < img_width; ++x)
{
unsigned long result = is_mandelbrot_point(x, y, iterations);
calculated_points[y * img_width + x] = result;
}
}
}
size_t mandelbrot::get_number_of_points() const
{
return img_height * img_width;
}
const unsigned long* mandelbrot::get_point_array() const
{
return calculated_points;
}
double get_min_im(double im_max, double im_min, int id, int procs)
{
return im_min + ((fabs(im_max - im_min)) / procs) * id;
}
double get_max_im(double im_max, double im_min, int id, int procs)
{
return im_min + ((fabs(im_max - im_min)) / procs) * (id + 1);
}
#ifndef MANDELBROT_H
#define MANDELBROT_H
#include <complex>
struct mandel_settings
{
double re_max;
double re_min;
double im_max;
double im_min;
unsigned long img_width;
unsigned long img_height;
unsigned long iterations;
};
class mandelbrot
{
public:
mandelbrot(mandel_settings settings);
~mandelbrot();
std::complex<double> get_pixel_coordinate(int x, int y) const;
unsigned long is_mandelbrot_point(unsigned long x, unsigned long y, unsigned long iterations) const;
void calculate_set();
size_t get_number_of_points() const;
const unsigned long* get_point_array() const;
// Deleted contructors.
mandelbrot(const mandelbrot&) = delete;
mandelbrot(mandelbrot&&) = delete;
mandelbrot& operator=(const mandelbrot&) = delete;
mandelbrot& operator=(mandelbrot&&) = delete;
private:
double re_max;
double re_min;
double im_max;
double im_min;
unsigned long img_width;
unsigned long img_height;
unsigned long iterations;
unsigned long* calculated_points;
};
// Helper functions for usage of the class with MPI.
double get_min_im(double im_max, double im_min, int id, int procs);
double get_max_im(double im_max, double im_min, int id, int procs);
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment