mesytec-mnode/external/taskflow-3.8.0/benchmarks/mandelbrot/mandel.hpp

119 lines
3 KiB
C++
Raw Normal View History

2025-01-04 01:25:05 +01:00
#include <cmath>
#include <string>
#include <vector>
#include <tuple>
#include <chrono>
#include <cassert>
const int D = 2;
const int MAX_ITERATION = 200;
const double XL = - 2.5;
const double XR = 1.0;
const double YB = -1.0;
const double YT = 1.0;
extern int H;
extern int W;
extern unsigned char* RGB;
inline void dump_tga(int w, int h, unsigned char rgb[], const char *filename) {
FILE *file_unit;
unsigned char header1[12] = {0,0,2,0,0,0,0,0,0,0,0,0};
unsigned char header2[6] = {static_cast<unsigned char>(w%256),
static_cast<unsigned char>(w/256),
static_cast<unsigned char>(h%256),
static_cast<unsigned char>(h/256), 24, 0};
// Create the file.
file_unit = fopen(filename, "wb");
// Write the headers.
fwrite(header1, sizeof(unsigned char), 12, file_unit);
fwrite(header2, sizeof(unsigned char), 6, file_unit);
//Write the image data.
fwrite(rgb, sizeof(unsigned char), 3*w*h, file_unit);
// Close the file.
fclose(file_unit);
printf("Dump figure to '%s'\n", filename);
}
// Computes the value of the point (px, py), which represents the complex
// number (px + i*py), based on whether it is part of the Mandelbrot set or not
inline int escape_time(double px, double py, int n) {
// x and y represent a complex number (x + i*y)
double x = px;
double y = py;
// square both components
double x2 = x * x;
double y2 = y * y;
//// Julia set
//double cr = -0.8;
//double ci = 0.156;
// Mandelbrot set:
double cr = px;
double ci = py;
double xtmp;
// We need i (number of iteration) after the loop, so don't declare the variable inside the for.
int i;
for (i = 0; (x2 + y2) <= 4.0 && i < MAX_ITERATION; i++) {
xtmp = pow((x*x+y*y), (n/2.0))*cos(n*atan2(y,x)) + cr;
y = pow((x*x+y*y), (n/2.0))*sin(n*atan2(y,x)) + ci;
x = xtmp;
// Update our temp variables
x2 = x * x;
y2 = y * y;
}
return i;
}
// Map a given (x, y) coordinate to the range [XL, XR] [YB, YT]
inline std::pair<double, double> scale_xy(double x, double y) {
double xx = XL + (XR - XL)/W * x;
double yy = YB + (YT - YB)/H * y;
return {xx, yy};
}
// Given an iteration, return a RGB color
// Ref: https://stackoverflow.com/questions/16500656/which-color-gradient-is-used-to-color-mandelbrot-in-wikipedia
inline std::tuple<int, int, int> get_color(int n) {
if(n < MAX_ITERATION && n) {
int i = n % 16;
const static std::vector<std::tuple<int, int, int>> colors {
{66, 30, 15},
{25, 7, 26},
{9, 1, 47},
{4, 4, 73},
{0, 7, 100},
{12, 44, 138},
{24, 82, 177},
{57, 125, 209},
{134, 181, 229},
{211, 236, 248},
{241, 233, 191},
{248, 201, 95},
{255, 170, 0},
{204, 128, 0},
{153, 87, 0},
{106, 52, 3}
};
return colors[i];
}
return {0, 0, 0};
}
std::chrono::microseconds measure_time_taskflow(unsigned);
std::chrono::microseconds measure_time_omp(unsigned);
std::chrono::microseconds measure_time_tbb(unsigned);