瀏覽代碼

Merge branch 'master' of gitea:christian/uni

master
christian 6 年之前
父節點
當前提交
52cef9b878
共有 9 個文件被更改,包括 549 次插入0 次删除
  1. 二進制
      ws2019/ana/lectures/analysis.pdf
  2. +1
    -0
      ws2019/ana/lectures/analysis.tex
  3. +138
    -0
      ws2019/ipi/uebungen/board.hh
  4. +116
    -0
      ws2019/ipi/uebungen/canvas.hh
  5. +125
    -0
      ws2019/ipi/uebungen/gameoflife.cc
  6. 二進制
      ws2019/ipi/uebungen/ipi9.pdf
  7. +44
    -0
      ws2019/ipi/uebungen/ipi9.tex
  8. +61
    -0
      ws2019/ipi/uebungen/mandelbrot.cc
  9. +64
    -0
      ws2019/ipi/uebungen/pgm.hh

二進制
ws2019/ana/lectures/analysis.pdf 查看文件


+ 1
- 0
ws2019/ana/lectures/analysis.tex 查看文件

@@ -33,5 +33,6 @@
\input{analysis16.tex}
\input{analysis17.tex}
\input{analysis18.tex}
\input{analysis19.tex}

\end{document}

+ 138
- 0
ws2019/ipi/uebungen/board.hh 查看文件

@@ -0,0 +1,138 @@
#include <string>

struct BoundaryCondition
{
virtual bool boundary(Board& board, int i, int j) = 0;
};

class Board {
public :
// Konstruktor, erzeuge bool* _fields
Board(int width, int height, BoundaryCondition cond);

// Desktruktor, raeume bool* _fields auf
~Board();
// copy constructor, intializes by copying from 'other'
Board(Board& other);

// assignment operator
Board& operator=(Board& other);

// gibt die Breite des Bretts zurueck
double width();

// gibt die Hoehe des Bretts zurueck
double height();

// schreibe value an den Pixel (i,j)
// Ueberlegen Sie wie aus (i,j) den flachen Index bei row-major bekommen
void updateField(int i, int j, bool value);

// Zugang zum Pixel (i,j) im 1D Array
// Ueberlegen Sie wie aus (i,j) den flachen Index bei row-major bekommen
int operator()(int i, int j);

// Gibt zurueck ob Feld am Rand liegt
bool touchesBoundary(int i, int j);

// Gibt Zahl der lebenden Zellen zurueck, die das Feld umgeben
int livingCells(int i, int j);

// Prueft ob Zelle lebt oder nicht
bool isLiving(int i, int j);

// Gibt die BoundaryCondition zurueck
BoundaryCondition boundaryCondition();

private :
int _width;
int _height;
bool* _fields;
void copy(Board& other);
BoundaryCondition _boundCond;
};

Board::Board(int width, int height, BoundaryCondition cond) {
// initialize all values
_width = width;
_height = height;
_boundCond = cond;
_fields = new bool[width * height];
}

Board::~Board() {
_fields = 0;
}

void Board::copy(Board& other) {
_width = other.width();
_height = other.height();
_boundCond = other.boundaryCondition();
_fields = new bool[_width * _height];
for (int i = 0; i < _height; i++) {
for (int j = 0; j < _width; j++) {
updateField(i, j, other.isLiving(i, j));
}
}
}

Board::Board(Board& other) {
copy(other);
}

Board& Board::operator=(Board& other) {
if (this == &other) {
return *this;
}
copy(other);
return *this;
}

double Board::width() {
return _width;
}

double Board::height() {
return _height;
}

BoundaryCondition Board::BoundaryCondition() {
return _boundCond;
}

void Board::updateField(int i, int j, bool value) {
// i = Zeile und wegen row-major Konvention muss i mit der Breite
// multipliziert werden
_fields[i * _width + j] = value;
}

bool Board::touchesBoundary(int i, int j) {
return i == _height - 1 || i == -1 || j == _width - 1 || j == -1;
}

int Board::livingCells(int i, int j) {
bool surround[8] = { isLiving(i+1, j+1), isLiving(i, j+1), isLiving(i-1, j+1)
, isLiving(i+1, j), isLiving(i-1, j)
, isLiving(i+1, j-1), isLiving(i, j-1), isLiving(i-1, j-1)};
int numLiving = 0;
for (int i = 0; i < 8; i++) {
if (surround[i] == true) {
numLiving += 1;
}
}
}

bool Board::isLiving(int i, int j) {
if (touchesBoundary(i, j)) {
return _boundCond.boundary(i, j);
} else {
return _fields[i * _width + j];
}
}

int Board::operator()(int i, int j) {
// i = Zeile und wegen row-major Konvention muss i mit der Breite
// Pixel multipliziert werden
return _fields[i * _width+ j];
}

+ 116
- 0
ws2019/ipi/uebungen/canvas.hh 查看文件

@@ -0,0 +1,116 @@
#include <string>
#include "pgm.hh"

// Komplexe Zahl
struct Complex
{
double real;
double imag;
};

class Canvas
{
public :
// Konstruktor, erzeuge int* _pixels
Canvas(double center_x, double center_y,
double width, double height,
int horPixels, int vertPixels);

// Desktruktor, raeume int* _pixels auf
~Canvas();

// gibt die Breite des Bildes zurueck
double width();

// gibt die Hoehe des Bildes zurueck
double height();

// gibt die Anzahl an horizontalen Pixeln
int horPixels();

// gibt die Anzahl an vertikalen Pixeln
int vertPixels();

// gebe die Koordinaten des Pixels (i,j) als Complex zurueck
Complex coord(int i, int j);

// schreibe value an den Pixel (i,j)
// Ueberlegen Sie wie aus (i,j) den flachen Index bei row-major bekommen
void writePixel(int i, int j, int value);

// Zugang zum Pixel (i,j) im 1D Array
// Ueberlegen Sie wie aus (i,j) den flachen Index bei row-major bekommen
int operator()(int i, int j);

// schreibe Bild mit Dateinamen filename
void write(std::string filename);
private :
double _center_x;
double _center_y;
double _width;
double _height;
int _horPixels;
int _vertPixels;
int* _pixels;
};

// diese Methode ist bereits implementiert
void Canvas::write(std::string filename)
{
write_pgm(_pixels,_horPixels,_vertPixels,filename);
}

Canvas::Canvas(double center_x, double center_y, double width, double height, int horPixels,
int vertPixels) {
// initialize all values
_center_x = center_x;
_center_y = center_y;
_width = width;
_height = height;
_horPixels = horPixels;
_vertPixels = vertPixels;
_pixels = new int[horPixels * vertPixels];
}

Canvas::~Canvas() {
_pixels = 0;
}

double Canvas::width() {
return _width;
}

double Canvas::height() {
return _height;
}

int Canvas::horPixels() {
return _horPixels;
}

int Canvas::vertPixels() {
return _vertPixels;
}

Complex Canvas::coord(int i, int j) {
Complex c;
// Bringe die Pixel mit den echten Laengen ins Verhaeltnis
double y = i * (_height / _vertPixels) - _height / 2;
double x = j * (_width / _horPixels) - _width / 2;
// Gebe die Koordinaten in Relation zum gewuenschten Zentrum aus
c.imag = y + _center_y;
c.real = x + _center_x;
return c;
}

void Canvas::writePixel(int i, int j, int value) {
// i = Zeile und wegen row-major Konvention muss i mit der Zahl der horizontalen
// Pixel multipliziert werden
_pixels[i*_horPixels + j] = value;
}

int Canvas::operator()(int i, int j) {
// i = Zeile und wegen row-major Konvention muss i mit der Zahl der horizontalen
// Pixel multipliziert werden
return _pixels[i*_horPixels + j];
}

+ 125
- 0
ws2019/ipi/uebungen/gameoflife.cc 查看文件

@@ -0,0 +1,125 @@
#include <iostream>
#include <unistd.h> // needed for usleep
#include <string>
#include <fstream>

#include "board.hh"

// Basisklassen
struct Regel
{
virtual void anwenden(Board& board) = 0;
};

class TorusCondition : public BoundaryCondition
{
bool boundary(Board& board, int i, int j) {
if (i == board.height() - 1) {
return board.isLiving(0, j);
} else if (i == -1) {
return board.isLiving(board.height() - 1, j);
} else if (j == board.width() - 1) {
return board.isLiving(i, 0);
} else if (j == -1) {
return board.isLiving(i, board.width() - 1);
}
}
};

class AliveCondition : public BoundaryCondition
{
bool boundary(Board& board, int i, int j) {
return true;
}
};

class DeadCondition : public BoundaryCondition
{
bool boundary(Board& board, int i, int j) {
return false;
}
};

class GameOfLifeRules : public Regel
{
public :
//void anwenden(Board& board) {
// // copy new board from old board
// Board updated = Board(board.width(), board.height());
// for (int i = 0; i < board.height(); i++) {
// for (int j = 0; i < board.width(); i++) {
// int n = board.livingCells(i, j);
// int self = board.isLiving(i, j);
// if (self && n < 2) {
// updated.updateField(i, j, false);
// } else if (!self && n == 3) {
// updated.updateField(i, j, true);
// } else if (self && n > 3) {
// updated.updateField(i, j, false);
// } else {
// updated.updateField(i, j, self);
// }
// }
// }
// board = updated;
//}
};

// Ein zellulaerer Automat, der Regeln und Datenstrukturen von aussen bekommt
class Automat
{
public :
// der Datentyp fuer das 2D Bool Array
Automat(Board& board, Regel& regel)
: _board(board)
, _regel(regel)
{}

// mache n Schritte
void doSteps(int n=1)
{
for (int i=0; i<n; ++i)
{
// Linux-spezifische Art und Weise den Inhalt der Konsole zu loeschen
// und den Cursor nach oben links zu setzen.
//std::cout << "\x1B[2J\x1B[H" << "Step " << i << std::endl << _board;
// Das Wiedergeben der Loesung soll immer 10 Sekunden (=1e7 Mikrosekunden)
// dauern. Sie koennen diesen Wert auch aendern.
usleep(1.e7/n);
//_regel.anwenden(_board);
}
}

private :
Board& _board;
Regel& _regel;
};

int main(int argc, char** argv)
{
if (argc != 2)
{
std::cout << "Usage: ./<progname> <txt-file>" << std::endl;
return 1;
}

Board board = Board(2, 2, AliveCondition);
board.updateField(1,1, true);
board.livingCells(1,1);

// Initialisiere Datenstruktur des 2D Bool Array
// TODO
// Ueberlegen Sie sich wie Sie einen Startzustand in das 2D Bool Array bekommen
// Lesen Sie ggf.
// (1) eine solche Textdatei mittels Filestream ein
// (2) ueberladen Sie Operatoren operator<< oder operator>>

// TODO
// - legen Sie eine Instanz der Randbedingung an
// - legen Sie eine Instanz des Regelsystems an
// - Initialisieren Sie den zellulaeren Automaten

// Experimentieren Sie hier mit Ihrem Automaten

return 0;
}

二進制
ws2019/ipi/uebungen/ipi9.pdf 查看文件


+ 44
- 0
ws2019/ipi/uebungen/ipi9.tex 查看文件

@@ -0,0 +1,44 @@
\documentclass[uebung]{../../../lecture}

\title{IPI: Übungsblatt 9}
\author{Samuel Weidemaier, Christian Merten}

\usepackage[]{listings}

\usepackage{xcolor}
\lstdefinestyle{mystyle}{
commentstyle=\color{gray},
language=C++,
keywordstyle=\color{blue},
numberstyle=\tiny\color{gray},
stringstyle=\color{black},
basicstyle=\ttfamily\footnotesize,
breakatwhitespace=false,
breaklines=true,
captionpos=b,
keepspaces=true,
numbers=left,
numbersep=5pt,
showspaces=false,
showstringspaces=false,
showtabs=false,
tabsize=2
}

\lstset{style=mystyle}

\begin{document}

\begin{aufgabe}[Mandelbrot-Menge]
(a) und (b) siehe \textit{mandelbrot.cc} und \textit{canvas.hh}.

(c) Je höher \lstinline{threshold}, desto heller wird das Bild, allerdings ist bereits zwischen 100 und 1000
kein großer Unterschied mehr zu erkennen. Bei sehr kleinen \lstinline{threshold}s werden die Randbereiche
wieder schwarz.

Bei geringen \lstinline{maxIt}s ist die Genauigkeit sehr gering, je höher desto feiner wird das Bild.
Allerdings ist auch hier zwischen 100 und 1000 bereits kein Unterschied mehr zu erkennen.
\end{aufgabe}

\end{document}

+ 61
- 0
ws2019/ipi/uebungen/mandelbrot.cc 查看文件

@@ -0,0 +1,61 @@
#include <iostream>
#include <cmath>
#include <string>

// Datentyp Complex in der Datei canvas.hh
#include "canvas.hh"

// Summiert zwei komplexe Zahlen z und c und schreibt das Ergebnis in z
void add_complex(Complex& z, Complex& c) {
z.real += c.real;
z.imag += c.imag;
}

// Multipliziert zwei komplexe Zahlen z und c und schreibt das Ergebnis in z
void multiply_complex(Complex& z, Complex& c) {
double re = z.real*c.real - z.imag*c.imag;
double im = z.real*c.imag + z.imag*c.real;
z.real = re;
z.imag = im;
}

// Betrag einer komplexen Zahl
double betrag(Complex z)
{
return std::sqrt(std::pow(z.real, 2) + std::pow(z.imag, 2));
}

// Generiert die Mandelbrot Menge und speichert sie in canvas mit threshold als Entfernung, ab dem
// ein Punkt ,,entkommt'', mit maxIt als maximale Anzahl an Iterationen, die für
// die Folge durchgeführt werden soll. Wird als PGM Bild unter filename gespeichert
void mandelbrot(Canvas& canvas, double threshold, int maxIt, std::string filename) {
for (int i = 0; i < canvas.vertPixels(); i++) {
for (int j = 0; j < canvas.horPixels(); j++) {
Complex c = canvas.coord(i, j);
Complex z;
z.real = 0;
z.imag = 0;
int neededIterations = -1;
for (int k = 1; k <= maxIt; k++) {
multiply_complex(z, z);
add_complex(z, c);
if (betrag(z) > threshold) {
neededIterations = k;
break;
}
}
if (neededIterations == -1) {
canvas.writePixel(i, j, 0);
} else {
canvas.writePixel(i, j, std::log(neededIterations)*100);
}
}
}
canvas.write(filename);
}

int main()
{
Canvas canvas = Canvas(-1, 0, 4, 3, 4000, 3000);
mandelbrot(canvas, 1000, 10000, "mandelbrot.pgm");
}

+ 64
- 0
ws2019/ipi/uebungen/pgm.hh 查看文件

@@ -0,0 +1,64 @@
#include <string>
#include <fstream>
#include <cmath>

void write_pgm(int* pixels, int horPixels, int vertPixels, std::string filename)
{
if(horPixels == 0 || vertPixels == 0)
{
std::cerr << "Leeres Pixel Array" << std::endl;
return;
}

// write file
// unfortunately we cannot use C++-11 which would simplify our life in that case
std::ofstream outfile;
outfile.open(filename.c_str());

outfile << "P2" << std::endl
<< horPixels << " " << vertPixels << std::endl;

// renormalize if necessary
int maxVal = 0;
for(int entry=0; entry<horPixels*vertPixels; entry++)
maxVal = std::max(pixels[entry],maxVal);

// renormalizing output
if(maxVal > 65535)
{
outfile << 65535 << std::endl;
for(int j=0, entry=0; j<vertPixels; j++)
{
for(int i=0; i<horPixels; i++, entry++)
{
if(pixels[entry] < 0)
{
std::cerr << "Negativer Eintrag bei (" << i << ", " << j << ")" << std::endl;
return;
}
outfile << std::floor(pixels[entry] * (65535./maxVal)) << " ";
}
outfile << std::endl;
}
}
// normal output
else
{
outfile << maxVal << std::endl;
for(int j=0; j<vertPixels; j++)
{
for(int i=0; i<horPixels; i++)
{
int entry = i + horPixels*(vertPixels-1-j);
if(pixels[entry] < 0)
{
std::cerr << "Negativer Eintrag bei (" << i << ", " << j << ")" << std::endl;
return;
}
outfile << pixels[entry] << " ";
}
outfile << std::endl;
}
}
outfile.close();
}

Loading…
取消
儲存