/* Berechnung des Apfelmaenchens der Mandelbrot-Menge
 * Ausgabe zum Plotten mit Python mittels: "./a.out > Mandelbrot.dat" */
#include <fstream>    // Schreiben in Dateien ( ofstream )
#include <vector>     // Sequenzieller Container vector<Type> der Standardbibliothek
#include <complex>    // Standardbibliothek fuer komplexwertige Zahlen
using namespace std;  // Benutze den Namensraum std

int main() {
    const int iter_max = 100;             // Maximal Wert der Iterationen

    // Bereich der komplexen Zahlen der Mandelbrotmenge
    const double x_min = -1.9;            // Realteil Minumum
    const double x_max = 0.5;             // Realteil Maximum
    const double y_min = -1.2;            // Imaginaerteil Minumum
    const double y_max = 1.2;             // Imaginaerteil Maximum
    const int N = 1000;                   // Anzahl der Punkte in die das xy-Intervall aufgeteilt wird
    const double h_x = (x_max - x_min)/N; // Abstand zwischen den aequidistanten Punkten des x-Intervalls
    const double h_y = (y_max - y_min)/N; // Abstand zwischen den aequidistanten Punkten des y-Intervalls

    vector<vector<int>> output(N, vector<int>(N, 0));          // Deklaration der int (NxN)-Vektor-Matrix (Initialisierung mit Nullen)

    for (int k = 0; k < N; ++k) {                              // for-Schleife ueber die Punkte des x-Intervalls
        for (int l = 0; l < N; ++l) {                          // for-Schleife ueber die Punkte des y-Intervalls
            complex<double> c( x_min + k*h_x , y_min + l*h_y); // Definition der komplexen Zahl c = x +i*y
            complex<double> z(0, 0);                           // Definition des Anfangswertes der komplexwertigen Folge

            // Iteration fuer die Mandelbrotmenge
            int iter = 0;                                  // Iterationen, die benoetigt werden bis |z|>2
            while ( norm(z) <= 4.0 && iter <  iter_max ) { // while-Schleife ueber die einzelnen Folgenwerte
                z = z * z + c;                             // Bildungsgesetz der komplexwertigen Folge
                iter++;                                    // Benoetigte Iteration + 1
            }                                              // Ende while-Schleife
            output[k][l] = iter;                           // int Vektor-Matrixfüllen mit Anzahl der Iterationen für einen Punkt c
        }                                                  // Ende for-Schleife y-Intervalls
    }                                                      // Ende for-Schleife x-Intervalls

    // Ausgabe der Loesungswerte in eine Datei mittels zweier bereichsbasierter for-Schleifen
    ofstream datei("Mandelbrot.dat");
    if (datei.is_open()) {
        for (const auto& output_k : output) {
            for (const int wert : output_k) {
                datei << wert << " ";
            }
            datei << "\n";
        }
    }
}
