103 lines
2.5 KiB
C++
103 lines
2.5 KiB
C++
#pragma once
|
|
|
|
#include "Mandelbrot.interface.h"
|
|
#include <complex>
|
|
#include <emmintrin.h>
|
|
|
|
void IMandelbrot::Init(int x_width, int y_height, int iterations, unsigned int threads, bool sse){
|
|
|
|
int** outarray = (int **) calloc(x_width, sizeof(int *));
|
|
for(unsigned int i = 0; i < x_width; i++)
|
|
outarray[i] = (int *) calloc(y_height, sizeof(int));
|
|
|
|
double minRe = -2.0;
|
|
double maxRe = 1.0;
|
|
double step = (abs(maxRe) + abs(minRe)) / x_width; //Schrittweite der zu überprüfenden komplexen Zahlen
|
|
double minIm = -1.2;
|
|
double maxIm = (y_height * step) - abs(minIm); //maximaler Imaginärwert
|
|
|
|
m_Params = new CParams(outarray,minRe,maxRe,minIm,maxIm,step,x_width,y_height,iterations,threads,sse);
|
|
}
|
|
|
|
void IMandelbrot::Exit(){
|
|
|
|
delete m_Params->m_outarray;
|
|
delete m_Params;
|
|
}
|
|
|
|
void IMandelbrot::calculateMandelbrot(){
|
|
calc(*m_Params);
|
|
}
|
|
|
|
int** IMandelbrot::getOutArray(){
|
|
return m_Params->m_outarray;
|
|
}
|
|
|
|
void IMandelbrot::checkNumber(CParams& params, double real, double imag, int rePos, int imPos){
|
|
|
|
complex<double> Zn(real, imag); //komplexe zahl, die sich in der schleife ändert
|
|
complex<double> actual(real, imag); //Speichere Ausgangszahl
|
|
|
|
if(params.m_use_sse){
|
|
for(int i = 0; i < params.m_iterations; i += 2){
|
|
Zn = Zn * Zn; //Zn = Zn^2
|
|
Zn = Zn + actual; //Zn = Zn^2 + c
|
|
|
|
complex<double> Zn2 = Zn * Zn;
|
|
Zn2 = Zn2 + actual;
|
|
|
|
__m128d a;
|
|
a = _mm_loadl_pd(a,&Zn.real());
|
|
a = _mm_loadh_pd(a,&Zn2.real());
|
|
|
|
__m128d b;
|
|
b = _mm_loadl_pd(b,&Zn.imag());
|
|
b = _mm_loadh_pd(b,&Zn2.imag());
|
|
|
|
a = _mm_mul_pd(a,a);
|
|
b = _mm_mul_pd(b,b);
|
|
a = _mm_add_pd(a,b);
|
|
|
|
double _a1;
|
|
double _a2;
|
|
_mm_storeh_pd(&_a1,a);
|
|
_mm_storeh_pd(&_a2,a);
|
|
|
|
double abs_1 = sqrt(_a1);
|
|
double abs_2 = sqrt(_a2);
|
|
if(abs_1 > 2 && abs_2 > 2){
|
|
params.m_outarray[rePos][imPos] = 0; //nicht in Mandelbrotmenge -> schreibe 0 in ASCII-MAP
|
|
return; //Schleifenabbruch
|
|
}
|
|
}
|
|
|
|
params.m_outarray[rePos][imPos] = 1; //in Mandelbrotmenge -> schreibe 1 in ASCII-MAP
|
|
return;
|
|
|
|
} else {
|
|
for(int i = 0; i < params.m_iterations; i++){
|
|
Zn = Zn * Zn; //Zn = Zn^2
|
|
Zn = Zn + actual; //Zn = Zn^2 + c
|
|
|
|
|
|
//Betrag Zn berechnen:
|
|
double a = Zn.real();
|
|
double b = Zn.imag();
|
|
a = a * a;
|
|
b = b * b;
|
|
a = a + b;
|
|
|
|
double abs = sqrt(a);
|
|
|
|
if(abs > 2){
|
|
params.m_outarray[rePos][imPos] = 0; //nicht in Mandelbrotmenge -> schreibe 0 in ASCII-MAP
|
|
return; //Schleifenabbruch
|
|
}
|
|
|
|
|
|
}
|
|
params.m_outarray[rePos][imPos] = 1; //in Mandelbrotmenge -> schreibe 1 in ASCII-MAP
|
|
return;
|
|
}
|
|
|
|
} |