init
15
CMakeLists.txt
Executable file
@@ -0,0 +1,15 @@
|
||||
# Set the minimum required version of CMake
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
|
||||
# Aktiviert die Generierung der compile_commands.json
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
# Set the project name
|
||||
project(HM2_Praktika)
|
||||
|
||||
# Add the subdirectories for each praktikum
|
||||
add_subdirectory(P1)
|
||||
add_subdirectory(P2)
|
||||
add_subdirectory(P3)
|
||||
add_subdirectory(P4)
|
||||
add_subdirectory(P5)
|
||||
12
P1/CMakeLists.txt
Executable file
@@ -0,0 +1,12 @@
|
||||
# Set the minimum required version of CMake
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
|
||||
# Set the project name
|
||||
project(HM_P1)
|
||||
|
||||
# Specify the C++ standard
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# Add all source files
|
||||
add_executable(HM_P1 main.cpp CMyVektor.cpp)
|
||||
199
P1/CMyVektor.cpp
Executable file
@@ -0,0 +1,199 @@
|
||||
#include "CMyVektor.h"
|
||||
#include <math.h>
|
||||
#include <iostream>
|
||||
|
||||
int CMyVektor::getDimension() {
|
||||
return dimension;
|
||||
}
|
||||
|
||||
// Vektor Element bei index i
|
||||
double& CMyVektor::operator[](int i) {
|
||||
return werte.at(i);
|
||||
}
|
||||
|
||||
// Betrag des Vektors
|
||||
double CMyVektor::length() {
|
||||
double l = 0.0;
|
||||
for (int i = 0; i < werte.size(); i++)
|
||||
l += pow(werte.at(i), 2);
|
||||
|
||||
return(sqrt(l));
|
||||
}
|
||||
|
||||
// Ausgabe im Vektorformat
|
||||
std::ostream& operator<< (std::ostream& os, CMyVektor& vektor) {
|
||||
os << "(";
|
||||
for (int i = 0; i < vektor.getDimension(); i++) {
|
||||
os << vektor[i];
|
||||
if (i < vektor.getDimension() - 1) os << "|";
|
||||
}
|
||||
os << ")";
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
/* Vektor Addition
|
||||
a1 + b1 = a1+b1
|
||||
a2 + b2 = a2+b2
|
||||
: : :
|
||||
ai + bi = ai+bi
|
||||
*/
|
||||
CMyVektor operator+(CMyVektor a, CMyVektor b) {
|
||||
// Vektoren addierbar?
|
||||
if (a.getDimension() != b.getDimension())
|
||||
return a;
|
||||
|
||||
CMyVektor sum(a.getDimension());
|
||||
|
||||
for (int i = 0; i < a.getDimension(); i++)
|
||||
sum[i] = a[i] + b[i];
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* Skalare Multiplikation
|
||||
a1 * s = v1
|
||||
a2 * s = v2
|
||||
: : :
|
||||
ai * s = vi
|
||||
*/
|
||||
CMyVektor operator*(double s, CMyVektor a) {
|
||||
CMyVektor vektor(a.getDimension());
|
||||
|
||||
for (int i = 0; i < a.getDimension(); i++)
|
||||
vektor[i] = s * a[i];
|
||||
|
||||
return vektor;
|
||||
}
|
||||
|
||||
CMyVektor gradient(double f(CMyVektor x), CMyVektor x) {
|
||||
CMyVektor grad(x.getDimension());
|
||||
CMyVektor xh(x.getDimension()); // x mit "Wackelei" an x_i
|
||||
xh = x;
|
||||
|
||||
double fx = f(x);
|
||||
double h = 1e-8;
|
||||
|
||||
// Berechnung der partiellen Ableitung nach x_i und Zusammenfassung in grad
|
||||
for (int i = 0; i < x.getDimension(); i++) {
|
||||
// xh[0] xh[1] ... xh[n]
|
||||
// x_1+h,x_2,...,x_n x_1,x_2+h,...,x_n x_1,x_2,...,x_n+1
|
||||
xh[i] += h;
|
||||
|
||||
// grad[i] = df/dx_i => numerische Ableitung nach dem jeweilige x_i
|
||||
grad[i] = (f(xh) - fx) / h;
|
||||
|
||||
// Zurücksetzen der "Wackelei"
|
||||
xh[i] -= h;
|
||||
}
|
||||
return grad;
|
||||
}
|
||||
|
||||
CMyVektor gradientenverfahren(double f(CMyVektor x), CMyVektor x, double lambda) {
|
||||
int schritt_zaehler = 0;
|
||||
CMyVektor gradfx(x.getDimension());
|
||||
CMyVektor x_neu(x.getDimension());
|
||||
gradfx = gradient(f, x);
|
||||
|
||||
while (gradient(f, x).length() >= 1e-5 && schritt_zaehler < 25) {
|
||||
x_neu = x + lambda * gradfx;
|
||||
|
||||
std::cout
|
||||
<< "Schritt " << schritt_zaehler << ": " << std::endl
|
||||
<< " x = " << x << std::endl
|
||||
<< " λ = " << lambda << std::endl
|
||||
<< " f(x) = " << f(x) << std::endl
|
||||
<< " grad f(x) = " << gradfx << std::endl
|
||||
<< " ||grad f(x)|| = " << gradfx.length() << std::endl << std::endl
|
||||
<< " x_neu = " << x_neu << std::endl
|
||||
<< " f(x_neu) = " << f(x_neu) << std::endl << std::endl;
|
||||
|
||||
// Halbierung
|
||||
if (f(x_neu) <= f(x)) {
|
||||
double lamda_test = lambda * 0.5;
|
||||
CMyVektor x_test = x + lamda_test * gradfx;
|
||||
|
||||
std::cout
|
||||
<< " ↯ f(x) = " << f(x) << " ≥ f(x_neu) = " << f(x_neu) << std::endl << std::endl
|
||||
<< " ? Test mit halbierter Schrittweite (λ = " << lamda_test << "): " << std::endl
|
||||
<< " x_test = " << x_test << std::endl
|
||||
<< " f(x_test) = " << f(x_test) << std::endl << std::endl;
|
||||
|
||||
if (f(x) < f(x_test))
|
||||
std::cout
|
||||
<< " ✓ f(x) = " << f(x) << " < f(x_test) = " << f(x_test) << std::endl
|
||||
<< " ! Übernehme Schrittweite." << std::endl << std::endl;
|
||||
|
||||
// weiter Halbieren wenn f(x_test) <= f(x)
|
||||
while (f(x_test) <= f(x)) {
|
||||
std::cout
|
||||
<< " ↯ f(x) = " << f(x) << " ≥ f(x_test) = " << f(x_test) << std::endl << std::endl;
|
||||
|
||||
lamda_test *= 0.5;
|
||||
x_test = x + lamda_test * gradfx;
|
||||
|
||||
std::cout
|
||||
<< " ? Test mit halbierter Schrittweite (λ = " << lamda_test << "): " << std::endl
|
||||
<< " x_test = " << x_test << std::endl
|
||||
<< " f(x_test) = " << f(x_test) << std::endl << std::endl;
|
||||
|
||||
// Ausgabe beim letzten Durchlauf der Schleife
|
||||
if (!(f(x_test) <= f(x)))
|
||||
std::cout
|
||||
<< " ✓ f(x) = " << f(x) << " < f(x_test) = " << f(x_test) << std::endl << std::endl
|
||||
<< " ! Übernehme Schrittweite λ = " << lamda_test << std::endl << std::endl;
|
||||
}
|
||||
|
||||
lambda = lamda_test;
|
||||
x_neu = x_test;
|
||||
}
|
||||
|
||||
// Verdopplung
|
||||
else {
|
||||
double lamda_test = lambda * 2;
|
||||
CMyVektor x_test = x + lamda_test * gradfx;
|
||||
|
||||
std::cout
|
||||
<< " ? Test mit doppelter Schrittweite (λ = " << lamda_test << "): " << std::endl
|
||||
<< " x_test = " << x_test << std::endl
|
||||
<< " f(x_test) = " << f(x_test) << std::endl << std::endl;
|
||||
|
||||
if (f(x_test) > f(x_neu)) {
|
||||
x_neu = x_test;
|
||||
lambda = lamda_test;
|
||||
std::cout
|
||||
<< " ! Übernehme verdoppelte Schrittweite λ = " << lamda_test << std::endl
|
||||
<< " ✓ f(x_neu) = " << f(x_neu) << " < f(x_test) = " << f(x_test) << std::endl << std::endl;
|
||||
}
|
||||
else {
|
||||
std::cout
|
||||
<< " ↯ f(x_neu) = " << f(x_neu) << " ≥ f(x_test) = " << f(x_test) << std::endl
|
||||
<< " ! behalte aktuelle Schrittweite λ = " << lambda << std::endl << std::endl;
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
x = x_neu;
|
||||
gradfx = gradient(f, x);
|
||||
schritt_zaehler++;
|
||||
}
|
||||
|
||||
// Zusammenfassung des Endes
|
||||
if (gradfx.length() < 1e-5)
|
||||
std::cout
|
||||
<< "Ende wegen ||grad f(x)|| < 10^-5 bei" << std::endl;
|
||||
|
||||
else
|
||||
std::cout
|
||||
<< "Ende wegen 25. Schritt" << std::endl;
|
||||
|
||||
std::cout
|
||||
<< " x = " << x << std::endl
|
||||
<< " λ = " << lambda << std::endl
|
||||
<< " f(x) = " << f(x) << std::endl
|
||||
<< " grad f(x) = " << gradfx << std::endl
|
||||
<< " ||grad f(x)|| = " << gradfx.length() << std::endl
|
||||
<< "-----------------------------------------------------" << std::endl << std::endl;
|
||||
|
||||
return x_neu;
|
||||
}
|
||||
34
P1/CMyVektor.h
Executable file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
class CMyVektor {
|
||||
private:
|
||||
int dimension;
|
||||
std::vector<double> werte;
|
||||
public:
|
||||
// Vektor mit Dimension anlegen
|
||||
CMyVektor(int n) : dimension { n } {
|
||||
werte.resize(n);
|
||||
}
|
||||
|
||||
CMyVektor(std::vector<double> x) : dimension { (int) x.size() } {
|
||||
werte.resize(x.size());
|
||||
for (int i = 0; i < x.size(); i++)
|
||||
werte[i] = x[i];
|
||||
}
|
||||
|
||||
int getDimension();
|
||||
double length();
|
||||
|
||||
// Komponente von Vektor übergeben
|
||||
double& operator[](int index);
|
||||
};
|
||||
|
||||
CMyVektor operator+(CMyVektor a, CMyVektor b);
|
||||
CMyVektor operator*(double lambda, CMyVektor a);
|
||||
|
||||
std::ostream& operator<< (std::ostream& os, CMyVektor& vektor);
|
||||
|
||||
CMyVektor gradient(double f(CMyVektor x), CMyVektor x);
|
||||
CMyVektor gradientenverfahren(double f(CMyVektor x), CMyVektor x, double lambda = 1.0);
|
||||
36
P1/main.cpp
Executable file
@@ -0,0 +1,36 @@
|
||||
#include <math.h>
|
||||
#include "CMyVektor.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
// f( [x,y] ) = sin(x * y) + sin(x) + cos(y)
|
||||
double f(CMyVektor X) {
|
||||
double x = X[0];
|
||||
double y = X[1];
|
||||
|
||||
return (sin(x * y) + sin(x) + cos(y));
|
||||
}
|
||||
|
||||
// g( [x,y,z] ) = -(2x^2 - 2xy + y^2 + z^2 - 2x - 4z)
|
||||
double g(CMyVektor X) {
|
||||
double x = X[0];
|
||||
double y = X[1];
|
||||
double z = X[2];
|
||||
|
||||
return -(2 * pow(x,2) - 2 * x * y + pow(y,2) + pow(z,2) - 2 * x - 4 * z);
|
||||
}
|
||||
|
||||
int main() {
|
||||
CMyVektor X0(std::vector<double>{1,3,5});
|
||||
CMyVektor gradX0 = gradient(f, X0);
|
||||
cout << "grad f" << X0 << "=" << gradX0 << std::endl;
|
||||
|
||||
CMyVektor X1(std::vector<double>{0.2,-2.1});
|
||||
gradientenverfahren(f, X1);
|
||||
|
||||
CMyVektor X2(std::vector<double>{0,0,0});
|
||||
gradientenverfahren(g, X2, 0.1);
|
||||
|
||||
system("pause");
|
||||
return 0;
|
||||
}
|
||||
12
P2/CMakeLists.txt
Executable file
@@ -0,0 +1,12 @@
|
||||
# Set the minimum required version of CMake
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
# Set the project name and specify the C++ as the project language
|
||||
project(HM_P2)
|
||||
|
||||
# Specify the C++ standard
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# Add an executable with the above sources
|
||||
add_executable(HM_P2 main.cpp CMyVektor.cpp CMyMatrix.cpp)
|
||||
145
P2/CMyMatrix.cpp
Executable file
@@ -0,0 +1,145 @@
|
||||
#include "CMyMatrix.h"
|
||||
#include "CMyVektor.h"
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <math.h>
|
||||
|
||||
// Konstruktor
|
||||
CMyMatrix::CMyMatrix(int z, int s) {
|
||||
zeilen = z;
|
||||
spalten = s;
|
||||
matrix.resize(zeilen);
|
||||
for (int i = 0; i < zeilen; ++i)
|
||||
matrix[i].resize(spalten);
|
||||
}
|
||||
|
||||
double CMyMatrix::getZeilen() {
|
||||
return zeilen;
|
||||
}
|
||||
|
||||
double CMyMatrix::getSpalten() {
|
||||
return spalten;
|
||||
}
|
||||
|
||||
void CMyMatrix::setWert(double wert, int zeile, int spalte) {
|
||||
matrix[zeile][spalte] = wert;
|
||||
}
|
||||
|
||||
double CMyMatrix::getWert(int zeile, int spalte) {
|
||||
return matrix[zeile][spalte];
|
||||
}
|
||||
|
||||
double& CMyMatrix::operator()(int zeile, int spalte) {
|
||||
return matrix[zeile][spalte];
|
||||
}
|
||||
|
||||
CMyMatrix CMyMatrix::invers() {
|
||||
if (this->getZeilen() != 2 || this->getSpalten() != 2)
|
||||
throw std::runtime_error("Keine 2x2 Matrix");
|
||||
|
||||
double a = this->getWert(0, 0);
|
||||
double b = this->getWert(1, 0);
|
||||
double c = this->getWert(0, 1);
|
||||
double d = this->getWert(1, 1);
|
||||
|
||||
double determinate = a * d - b * c;
|
||||
|
||||
if (determinate == 0)
|
||||
throw std::runtime_error("detA == 0");
|
||||
|
||||
double kehrwertDeterminante = 1 / determinate;
|
||||
CMyMatrix inverse(2,2);
|
||||
|
||||
inverse.setWert(kehrwertDeterminante * d, 0, 0);
|
||||
inverse.setWert(kehrwertDeterminante * -c, 0, 1);
|
||||
inverse.setWert(kehrwertDeterminante * -b, 1, 0);
|
||||
inverse.setWert(kehrwertDeterminante * a, 1, 1);
|
||||
|
||||
return inverse;
|
||||
}
|
||||
|
||||
// Matrix-Vektor Multiplikation
|
||||
CMyVektor operator*(CMyMatrix A, CMyVektor x) {
|
||||
// M Spalten == V Zeilen
|
||||
if (A.getSpalten() != x.getDimension())
|
||||
throw std::runtime_error("Matrix(m x n) * Vektor(i) n != i");
|
||||
|
||||
CMyVektor ergebnis(A.getZeilen());
|
||||
|
||||
for (int i = 0; i < A.getZeilen(); i++) { // Zeile
|
||||
for (int j = 0; j < A.getSpalten(); j++) // Spalte
|
||||
ergebnis[i] += A(i, j) * x[j]; // Aufsummierung
|
||||
}
|
||||
return ergebnis;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, CMyMatrix x) {
|
||||
|
||||
for (int i = 0; i < x.getZeilen(); ++i) {
|
||||
os << "\t\t\t(";
|
||||
for (int j = 0; j < x.getSpalten(); ++j)
|
||||
j == x.getSpalten() - 1 ? os << std::fixed << std::setprecision(10) << x(i, j) : os << std::fixed << std::setprecision(10) << x(i, j) << "|";
|
||||
|
||||
os << ")\n";
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
CMyMatrix jacobi(CMyVektor x, CMyVektor(*f)(CMyVektor)) {
|
||||
double const h = pow(10, -4);
|
||||
CMyVektor f_x = f(x);
|
||||
CMyVektor tmp{ x };
|
||||
|
||||
CMyMatrix jacobiMatrix(f_x.getDimension(), x.getDimension());
|
||||
|
||||
for (int i = 0; i < f_x.getDimension(); ++i) { // Zeile bzw. Teilfunktion f_i
|
||||
for (int j = 0; j < x.getDimension(); ++j) { // Spalte bzw. Variable x_j
|
||||
tmp[j] += h;
|
||||
jacobiMatrix(i, j) = (f(tmp)[i] - f_x[i]) / h;
|
||||
tmp[j] -= h;
|
||||
}
|
||||
}
|
||||
return jacobiMatrix;
|
||||
};
|
||||
|
||||
void newtonverfahren(CMyVektor x, CMyVektor(*f)(CMyVektor)) {
|
||||
int schritt = 0;
|
||||
CMyVektor f_x = f(x);
|
||||
CMyMatrix jacobi_f_x = jacobi(x, f);
|
||||
CMyMatrix jacobiInvers = jacobi_f_x.invers();
|
||||
|
||||
double funktionLaenge = f_x.length();
|
||||
|
||||
CMyVektor dx = -1 * (jacobiInvers * f_x);
|
||||
|
||||
while (schritt != 50 && funktionLaenge >= 1e-5) {
|
||||
std::cout << "Schritt " << schritt << ":"
|
||||
<< "\n\t 𝐱 = " << x
|
||||
<< "\n\t 𝑓(𝐱) = " << f_x << "\n"
|
||||
<< "\n\t ∂𝑓(𝐱) = \n " << jacobi_f_x
|
||||
<< "\n\t ∂𝑓(𝐱)⁻¹ = \n" << jacobiInvers
|
||||
<< "\n\t Δ𝐱 = " << dx
|
||||
<< "\n\t ||𝑓(𝐱)|| = " << funktionLaenge << std::endl << std::endl;
|
||||
|
||||
schritt++;
|
||||
x = x + dx;
|
||||
f_x = f(x);
|
||||
jacobi_f_x = jacobi(x, f);
|
||||
jacobiInvers = jacobi_f_x.invers();
|
||||
dx = -1 * (jacobiInvers * f_x);
|
||||
funktionLaenge = f_x.length();
|
||||
|
||||
if (schritt == 50) {
|
||||
std::cout << "Ende wegen Schrittanzahl = 50 bei";
|
||||
std::cout << "\n\t x = " << x
|
||||
<< "\n\t 𝑓(𝐱) = " << f_x
|
||||
<< "\n\t ||𝑓(𝐱)|| = " << funktionLaenge << std::endl;
|
||||
}
|
||||
else if (funktionLaenge < 1e-5) {
|
||||
std::cout << "Ende wegen ||𝑓(𝐱)||<1e-5 bei";
|
||||
std::cout << "\n\t x = " << x
|
||||
<< "\n\t 𝑓(𝐱) = " << f_x
|
||||
<< "\n\t ||𝑓(𝐱)|| = " << funktionLaenge << std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
31
P2/CMyMatrix.h
Executable file
@@ -0,0 +1,31 @@
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include "CMyVektor.h"
|
||||
|
||||
class CMyMatrix {
|
||||
private:
|
||||
std::vector<std::vector<double>> matrix;
|
||||
int zeilen = 0;
|
||||
int spalten = 0;
|
||||
|
||||
public:
|
||||
CMyMatrix(int zeilen, int spalten);
|
||||
|
||||
double getZeilen();
|
||||
double getSpalten();
|
||||
|
||||
void setWert(double wert, int zeile, int spalte);
|
||||
|
||||
double getWert(int zeile, int spalte);
|
||||
|
||||
double& operator()(int zeile, int spalte);
|
||||
|
||||
CMyMatrix invers();
|
||||
|
||||
friend CMyVektor operator*(CMyMatrix A, CMyVektor x);
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, CMyMatrix x);
|
||||
};
|
||||
|
||||
CMyMatrix jacobi(CMyVektor x, CMyVektor(*funktion)(CMyVektor)); //como friend-> error de compiler "C3767"
|
||||
void newtonverfahren(CMyVektor x, CMyVektor(*funktion)(CMyVektor)); //libro pagina 221
|
||||
199
P2/CMyVektor.cpp
Executable file
@@ -0,0 +1,199 @@
|
||||
#include "CMyVektor.h"
|
||||
#include <math.h>
|
||||
#include <iostream>
|
||||
|
||||
int CMyVektor::getDimension() {
|
||||
return dimension;
|
||||
}
|
||||
|
||||
// Vektor Element bei index i
|
||||
double& CMyVektor::operator[](int i) {
|
||||
return werte.at(i);
|
||||
}
|
||||
|
||||
// Betrag des Vektors
|
||||
double CMyVektor::length() {
|
||||
double l = 0.0;
|
||||
for (int i = 0; i < werte.size(); i++)
|
||||
l += pow(werte.at(i), 2);
|
||||
|
||||
return(sqrt(l));
|
||||
}
|
||||
|
||||
// Ausgabe im Vektorformat
|
||||
std::ostream& operator<< (std::ostream& os, CMyVektor& vektor) {
|
||||
os << "(";
|
||||
for (int i = 0; i < vektor.getDimension(); i++) {
|
||||
os << vektor[i];
|
||||
if (i < vektor.getDimension() - 1) os << "|";
|
||||
}
|
||||
os << ")";
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
/* Vektor Addition
|
||||
a1 + b1 = a1+b1
|
||||
a2 + b2 = a2+b2
|
||||
: : :
|
||||
ai + bi = ai+bi
|
||||
*/
|
||||
CMyVektor operator+(CMyVektor a, CMyVektor b) {
|
||||
// Vektoren addierbar?
|
||||
if (a.getDimension() != b.getDimension())
|
||||
return a;
|
||||
|
||||
CMyVektor sum(a.getDimension());
|
||||
|
||||
for (int i = 0; i < a.getDimension(); i++)
|
||||
sum[i] = a[i] + b[i];
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* Skalare Multiplikation
|
||||
a1 * s = v1
|
||||
a2 * s = v2
|
||||
: : :
|
||||
ai * s = vi
|
||||
*/
|
||||
CMyVektor operator*(double s, CMyVektor a) {
|
||||
CMyVektor vektor(a.getDimension());
|
||||
|
||||
for (int i = 0; i < a.getDimension(); i++)
|
||||
vektor[i] = s * a[i];
|
||||
|
||||
return vektor;
|
||||
}
|
||||
|
||||
CMyVektor gradient(double f(CMyVektor x), CMyVektor x) {
|
||||
CMyVektor grad(x.getDimension());
|
||||
CMyVektor xh(x.getDimension()); // x mit "Wackelei" an x_i
|
||||
xh = x;
|
||||
|
||||
double fx = f(x);
|
||||
double h = 1e-8;
|
||||
|
||||
// Berechnung der partiellen Ableitung nach x_i und Zusammenfassung in grad
|
||||
for (int i = 0; i < x.getDimension(); i++) {
|
||||
// xh[0] xh[1] ... xh[n]
|
||||
// x_1+h,x_2,...,x_n x_1,x_2+h,...,x_n x_1,x_2,...,x_n+1
|
||||
xh[i] += h;
|
||||
|
||||
// grad[i] = df/dx_i => numerische Ableitung nach dem jeweilige x_i
|
||||
grad[i] = (f(xh) - fx) / h;
|
||||
|
||||
// Zurücksetzen der "Wackelei"
|
||||
xh[i] -= h;
|
||||
}
|
||||
return grad;
|
||||
}
|
||||
|
||||
CMyVektor gradientenverfahren(double f(CMyVektor x), CMyVektor x, double lambda) {
|
||||
int schritt_zaehler = 0;
|
||||
CMyVektor gradfx(x.getDimension());
|
||||
CMyVektor x_neu(x.getDimension());
|
||||
gradfx = gradient(f, x);
|
||||
|
||||
while (gradient(f, x).length() >= 1e-5 && schritt_zaehler < 25) {
|
||||
x_neu = x + lambda * gradfx;
|
||||
|
||||
std::cout
|
||||
<< "Schritt " << schritt_zaehler << ": " << std::endl
|
||||
<< " x = " << x << std::endl
|
||||
<< " λ = " << lambda << std::endl
|
||||
<< " f(x) = " << f(x) << std::endl
|
||||
<< " grad f(x) = " << gradfx << std::endl
|
||||
<< " ||grad f(x)|| = " << gradfx.length() << std::endl << std::endl
|
||||
<< " x_neu = " << x_neu << std::endl
|
||||
<< " f(x_neu) = " << f(x_neu) << std::endl << std::endl;
|
||||
|
||||
// Halbierung
|
||||
if (f(x_neu) <= f(x)) {
|
||||
double lamda_test = lambda * 0.5;
|
||||
CMyVektor x_test = x + lamda_test * gradfx;
|
||||
|
||||
std::cout
|
||||
<< " ↯ f(x) = " << f(x) << " ≥ f(x_neu) = " << f(x_neu) << std::endl << std::endl
|
||||
<< " ? Test mit halbierter Schrittweite (λ = " << lamda_test << "): " << std::endl
|
||||
<< " x_test = " << x_test << std::endl
|
||||
<< " f(x_test) = " << f(x_test) << std::endl << std::endl;
|
||||
|
||||
if (f(x) < f(x_test))
|
||||
std::cout
|
||||
<< " ✓ f(x) = " << f(x) << " < f(x_test) = " << f(x_test) << std::endl
|
||||
<< " ! Übernehme Schrittweite." << std::endl << std::endl;
|
||||
|
||||
// weiter Halbieren wenn f(x_test) <= f(x)
|
||||
while (f(x_test) <= f(x)) {
|
||||
std::cout
|
||||
<< " ↯ f(x) = " << f(x) << " ≥ f(x_test) = " << f(x_test) << std::endl << std::endl;
|
||||
|
||||
lamda_test *= 0.5;
|
||||
x_test = x + lamda_test * gradfx;
|
||||
|
||||
std::cout
|
||||
<< " ? Test mit halbierter Schrittweite (λ = " << lamda_test << "): " << std::endl
|
||||
<< " x_test = " << x_test << std::endl
|
||||
<< " f(x_test) = " << f(x_test) << std::endl << std::endl;
|
||||
|
||||
// Ausgabe beim letzten Durchlauf der Schleife
|
||||
if (!(f(x_test) <= f(x)))
|
||||
std::cout
|
||||
<< " ✓ f(x) = " << f(x) << " < f(x_test) = " << f(x_test) << std::endl << std::endl
|
||||
<< " ! Übernehme Schrittweite λ = " << lamda_test << std::endl << std::endl;
|
||||
}
|
||||
|
||||
lambda = lamda_test;
|
||||
x_neu = x_test;
|
||||
}
|
||||
|
||||
// Verdopplung
|
||||
else {
|
||||
double lamda_test = lambda * 2;
|
||||
CMyVektor x_test = x + lamda_test * gradfx;
|
||||
|
||||
std::cout
|
||||
<< " ? Test mit doppelter Schrittweite (λ = " << lamda_test << "): " << std::endl
|
||||
<< " x_test = " << x_test << std::endl
|
||||
<< " f(x_test) = " << f(x_test) << std::endl << std::endl;
|
||||
|
||||
if (f(x_test) > f(x_neu)) {
|
||||
x_neu = x_test;
|
||||
lambda = lamda_test;
|
||||
std::cout
|
||||
<< " ! Übernehme verdoppelte Schrittweite λ = " << lamda_test << std::endl
|
||||
<< " ✓ f(x_neu) = " << f(x_neu) << " < f(x_test) = " << f(x_test) << std::endl << std::endl;
|
||||
}
|
||||
else {
|
||||
std::cout
|
||||
<< " ↯ f(x_neu) = " << f(x_neu) << " ≥ f(x_test) = " << f(x_test) << std::endl
|
||||
<< " ! behalte aktuelle Schrittweite λ = " << lambda << std::endl << std::endl;
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
x = x_neu;
|
||||
gradfx = gradient(f, x);
|
||||
schritt_zaehler++;
|
||||
}
|
||||
|
||||
// Zusammenfassung des Endes
|
||||
if (gradfx.length() < 1e-5)
|
||||
std::cout
|
||||
<< "Ende wegen ||grad f(x)|| < 10^-5 bei" << std::endl;
|
||||
|
||||
else
|
||||
std::cout
|
||||
<< "Ende wegen 25. Schritt" << std::endl;
|
||||
|
||||
std::cout
|
||||
<< " x = " << x << std::endl
|
||||
<< " λ = " << lambda << std::endl
|
||||
<< " f(x) = " << f(x) << std::endl
|
||||
<< " grad f(x) = " << gradfx << std::endl
|
||||
<< " ||grad f(x)|| = " << gradfx.length() << std::endl
|
||||
<< "-----------------------------------------------------" << std::endl << std::endl;
|
||||
|
||||
return x_neu;
|
||||
}
|
||||
34
P2/CMyVektor.h
Executable file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
class CMyVektor {
|
||||
private:
|
||||
int dimension;
|
||||
std::vector<double> werte;
|
||||
public:
|
||||
// Vektor mit Dimension anlegen
|
||||
CMyVektor(int n) : dimension{ n } {
|
||||
werte.resize(n);
|
||||
}
|
||||
|
||||
CMyVektor(std::vector<double> x) : dimension{ (int)x.size() } {
|
||||
werte.resize(x.size());
|
||||
for (int i = 0; i < x.size(); i++)
|
||||
werte[i] = x[i];
|
||||
}
|
||||
|
||||
int getDimension();
|
||||
double length();
|
||||
|
||||
// Komponente von Vektor übergeben
|
||||
double& operator[](int index);
|
||||
};
|
||||
|
||||
CMyVektor operator+(CMyVektor a, CMyVektor b);
|
||||
CMyVektor operator*(double lambda, CMyVektor a);
|
||||
|
||||
std::ostream& operator<< (std::ostream& os, CMyVektor& vektor);
|
||||
|
||||
CMyVektor gradient(double f(CMyVektor x), CMyVektor x);
|
||||
CMyVektor gradientenverfahren(double f(CMyVektor x), CMyVektor x, double lambda = 1.0);
|
||||
BIN
P2/Praktikum2.pdf
Executable file
41
P2/main.cpp
Executable file
@@ -0,0 +1,41 @@
|
||||
#include <math.h>
|
||||
#include "CMyVektor.h"
|
||||
#include "CMyMatrix.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
// f( [x,y] ) = sin(x * y) + sin(x) + cos(y)
|
||||
double ff(CMyVektor X) {
|
||||
double x = X[0];
|
||||
double y = X[1];
|
||||
|
||||
return (sin(x * y) + sin(x) + cos(y));
|
||||
}
|
||||
|
||||
// g( [x,y,z] ) = -(2x^2 - 2xy + y^2 + z^2 - 2x - 4z)
|
||||
double gg(CMyVektor X) {
|
||||
double x = X[0];
|
||||
double y = X[1];
|
||||
double z = X[2];
|
||||
|
||||
return -(2 * pow(x, 2) - 2 * x * y + pow(y, 2) + pow(z, 2) - 2 * x - 4 * z);
|
||||
}
|
||||
|
||||
CMyVektor f(CMyVektor x) {
|
||||
CMyVektor result(3); // da f: R^4 -> R^3
|
||||
result[0] = x[0] * x[1] * exp(x[2]);
|
||||
result[1] = x[1] * x[2] * x[3];
|
||||
result[2] = x[3];
|
||||
return result;
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
cout << "Aufgabe_2 :\n" << jacobi(CMyVektor{ {1, 2, 0, 3} },
|
||||
[](CMyVektor x) -> CMyVektor { return { {x[0] * x[1] * exp(x[2]), x[1] * x[2] * x[3], x[3]} }; })
|
||||
<< endl;
|
||||
|
||||
newtonverfahren({ {1, 1} },
|
||||
[](CMyVektor x) -> CMyVektor { return { {pow(x[0], 3) * pow(x[1], 3) - 2 * x[1], x[0] - 2} }; });
|
||||
return 0;
|
||||
}
|
||||
12
P3/CMakeLists.txt
Executable file
@@ -0,0 +1,12 @@
|
||||
# Set the minimum required version of CMake
|
||||
cmake_minimum_required(VERSION 3.11)
|
||||
|
||||
# Set the project name and specify the C++ as the project language
|
||||
project(HM_P3)
|
||||
|
||||
# Specify the C++ standard
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# Add an executable with the above sources
|
||||
add_executable(HM_P3 main.cpp CMyVektor.cpp CMyMatrix.cpp C_DGLSolver.cpp)
|
||||
145
P3/CMyMatrix.cpp
Executable file
@@ -0,0 +1,145 @@
|
||||
#include "CMyMatrix.h"
|
||||
#include "CMyVektor.h"
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <math.h>
|
||||
|
||||
// Konstruktor
|
||||
CMyMatrix::CMyMatrix(int z, int s) {
|
||||
zeilen = z;
|
||||
spalten = s;
|
||||
matrix.resize(zeilen);
|
||||
for (int i = 0; i < zeilen; ++i)
|
||||
matrix[i].resize(spalten);
|
||||
}
|
||||
|
||||
double CMyMatrix::getZeilen() {
|
||||
return zeilen;
|
||||
}
|
||||
|
||||
double CMyMatrix::getSpalten() {
|
||||
return spalten;
|
||||
}
|
||||
|
||||
void CMyMatrix::setWert(double wert, int zeile, int spalte) {
|
||||
matrix[zeile][spalte] = wert;
|
||||
}
|
||||
|
||||
double CMyMatrix::getWert(int zeile, int spalte) {
|
||||
return matrix[zeile][spalte];
|
||||
}
|
||||
|
||||
double& CMyMatrix::operator()(int zeile, int spalte) {
|
||||
return matrix[zeile][spalte];
|
||||
}
|
||||
|
||||
CMyMatrix CMyMatrix::invers() {
|
||||
if (this->getZeilen() != 2 || this->getSpalten() != 2)
|
||||
throw std::runtime_error("Keine 2x2 Matrix");
|
||||
|
||||
double a = this->getWert(0, 0);
|
||||
double b = this->getWert(1, 0);
|
||||
double c = this->getWert(0, 1);
|
||||
double d = this->getWert(1, 1);
|
||||
|
||||
double determinate = a * d - b * c;
|
||||
|
||||
if (determinate == 0)
|
||||
throw std::runtime_error("detA == 0");
|
||||
|
||||
double kehrwertDeterminante = 1 / determinate;
|
||||
CMyMatrix inverse(2,2);
|
||||
|
||||
inverse.setWert(kehrwertDeterminante * d, 0, 0);
|
||||
inverse.setWert(kehrwertDeterminante * -c, 0, 1);
|
||||
inverse.setWert(kehrwertDeterminante * -b, 1, 0);
|
||||
inverse.setWert(kehrwertDeterminante * a, 1, 1);
|
||||
|
||||
return inverse;
|
||||
}
|
||||
|
||||
// Matrix-Vektor Multiplikation
|
||||
CMyVektor operator*(CMyMatrix A, CMyVektor x) {
|
||||
// M Spalten == V Zeilen
|
||||
if (A.getSpalten() != x.getDimension())
|
||||
throw std::runtime_error("Matrix(m x n) * Vektor(i) n != i");
|
||||
|
||||
CMyVektor ergebnis(A.getZeilen());
|
||||
|
||||
for (int i = 0; i < A.getZeilen(); i++) { // Zeile
|
||||
for (int j = 0; j < A.getSpalten(); j++) // Spalte
|
||||
ergebnis[i] += A(i, j) * x[j]; // Aufsummierung
|
||||
}
|
||||
return ergebnis;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, CMyMatrix x) {
|
||||
|
||||
for (int i = 0; i < x.getZeilen(); ++i) {
|
||||
os << "\t\t\t(";
|
||||
for (int j = 0; j < x.getSpalten(); ++j)
|
||||
j == x.getSpalten() - 1 ? os << std::fixed << std::setprecision(10) << x(i, j) : os << std::fixed << std::setprecision(10) << x(i, j) << "|";
|
||||
|
||||
os << ")\n";
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
CMyMatrix jacobi(CMyVektor x, CMyVektor(*f)(CMyVektor)) {
|
||||
double const h = pow(10, -4);
|
||||
CMyVektor f_x = f(x);
|
||||
CMyVektor tmp{ x };
|
||||
|
||||
CMyMatrix jacobiMatrix(f_x.getDimension(), x.getDimension());
|
||||
|
||||
for (int i = 0; i < f_x.getDimension(); ++i) { // Zeile bzw. Teilfunktion f_i
|
||||
for (int j = 0; j < x.getDimension(); ++j) { // Spalte bzw. Variable x_j
|
||||
tmp[j] += h;
|
||||
jacobiMatrix(i, j) = (f(tmp)[i] - f_x[i]) / h;
|
||||
tmp[j] -= h;
|
||||
}
|
||||
}
|
||||
return jacobiMatrix;
|
||||
};
|
||||
|
||||
void newtonverfahren(CMyVektor x, CMyVektor(*f)(CMyVektor)) {
|
||||
int schritt = 0;
|
||||
CMyVektor f_x = f(x);
|
||||
CMyMatrix jacobi_f_x = jacobi(x, f);
|
||||
CMyMatrix jacobiInvers = jacobi_f_x.invers();
|
||||
|
||||
double funktionLaenge = f_x.length();
|
||||
|
||||
CMyVektor dx = -1 * (jacobiInvers * f_x);
|
||||
|
||||
while (schritt != 50 && funktionLaenge >= 1e-5) {
|
||||
std::cout << "Schritt " << schritt << ":"
|
||||
<< "\n\t 𝐱 = " << x
|
||||
<< "\n\t 𝑓(𝐱) = " << f_x << "\n"
|
||||
<< "\n\t ∂𝑓(𝐱) = \n " << jacobi_f_x
|
||||
<< "\n\t ∂𝑓(𝐱)⁻¹ = \n" << jacobiInvers
|
||||
<< "\n\t Δ𝐱 = " << dx
|
||||
<< "\n\t ||𝑓(𝐱)|| = " << funktionLaenge << std::endl << std::endl;
|
||||
|
||||
schritt++;
|
||||
x = x + dx;
|
||||
f_x = f(x);
|
||||
jacobi_f_x = jacobi(x, f);
|
||||
jacobiInvers = jacobi_f_x.invers();
|
||||
dx = -1 * (jacobiInvers * f_x);
|
||||
funktionLaenge = f_x.length();
|
||||
|
||||
if (schritt == 50) {
|
||||
std::cout << "Ende wegen Schrittanzahl = 50 bei";
|
||||
std::cout << "\n\t x = " << x
|
||||
<< "\n\t 𝑓(𝐱) = " << f_x
|
||||
<< "\n\t ||𝑓(𝐱)|| = " << funktionLaenge << std::endl;
|
||||
}
|
||||
else if (funktionLaenge < 1e-5) {
|
||||
std::cout << "Ende wegen ||𝑓(𝐱)||<1e-5 bei";
|
||||
std::cout << "\n\t x = " << x
|
||||
<< "\n\t 𝑓(𝐱) = " << f_x
|
||||
<< "\n\t ||𝑓(𝐱)|| = " << funktionLaenge << std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
31
P3/CMyMatrix.h
Executable file
@@ -0,0 +1,31 @@
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include "CMyVektor.h"
|
||||
|
||||
class CMyMatrix {
|
||||
private:
|
||||
std::vector<std::vector<double>> matrix;
|
||||
int zeilen = 0;
|
||||
int spalten = 0;
|
||||
|
||||
public:
|
||||
CMyMatrix(int zeilen, int spalten);
|
||||
|
||||
double getZeilen();
|
||||
double getSpalten();
|
||||
|
||||
void setWert(double wert, int zeile, int spalte);
|
||||
|
||||
double getWert(int zeile, int spalte);
|
||||
|
||||
double& operator()(int zeile, int spalte);
|
||||
|
||||
CMyMatrix invers();
|
||||
|
||||
friend CMyVektor operator*(CMyMatrix A, CMyVektor x);
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, CMyMatrix x);
|
||||
};
|
||||
|
||||
CMyMatrix jacobi(CMyVektor x, CMyVektor(*funktion)(CMyVektor)); //como friend-> error de compiler "C3767"
|
||||
void newtonverfahren(CMyVektor x, CMyVektor(*funktion)(CMyVektor)); //libro pagina 221
|
||||
212
P3/CMyVektor.cpp
Executable file
@@ -0,0 +1,212 @@
|
||||
#include "CMyVektor.h"
|
||||
#include <math.h>
|
||||
#include <iostream>
|
||||
|
||||
int CMyVektor::getDimension() {
|
||||
return dimension;
|
||||
}
|
||||
|
||||
// Vektor Element bei index i
|
||||
double& CMyVektor::operator[](int i) {
|
||||
return werte.at(i);
|
||||
}
|
||||
|
||||
double CMyVektor::getElement(int i) {
|
||||
return werte.at(i - 1);
|
||||
}
|
||||
|
||||
void CMyVektor::setElement(int i, double j) {
|
||||
werte.at(i - 1) = j;
|
||||
}
|
||||
|
||||
void CMyVektor::setElements(std::vector<double> x) {
|
||||
for (int i = 0; i < x.size(); i++)
|
||||
werte[i] = x[i];
|
||||
}
|
||||
|
||||
// Betrag des Vektors
|
||||
double CMyVektor::length() {
|
||||
double l = 0.0;
|
||||
for (int i = 0; i < werte.size(); i++)
|
||||
l += pow(werte.at(i), 2);
|
||||
|
||||
return(sqrt(l));
|
||||
}
|
||||
|
||||
// Ausgabe im Vektorformat
|
||||
std::ostream& operator<< (std::ostream& os, CMyVektor& vektor) {
|
||||
os << "(";
|
||||
for (int i = 0; i < vektor.getDimension(); i++) {
|
||||
os << vektor[i];
|
||||
if (i < vektor.getDimension() - 1) os << "|";
|
||||
}
|
||||
os << ")";
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
/* Vektor Addition
|
||||
a1 + b1 = a1+b1
|
||||
a2 + b2 = a2+b2
|
||||
: : :
|
||||
ai + bi = ai+bi
|
||||
*/
|
||||
CMyVektor operator+(CMyVektor a, CMyVektor b) {
|
||||
// Vektoren addierbar?
|
||||
if (a.getDimension() != b.getDimension())
|
||||
return a;
|
||||
|
||||
CMyVektor sum(a.getDimension());
|
||||
|
||||
for (int i = 0; i < a.getDimension(); i++)
|
||||
sum[i] = a[i] + b[i];
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* Skalare Multiplikation
|
||||
a1 * s = v1
|
||||
a2 * s = v2
|
||||
: : :
|
||||
ai * s = vi
|
||||
*/
|
||||
CMyVektor operator*(double s, CMyVektor a) {
|
||||
CMyVektor vektor(a.getDimension());
|
||||
|
||||
for (int i = 0; i < a.getDimension(); i++)
|
||||
vektor[i] = s * a[i];
|
||||
|
||||
return vektor;
|
||||
}
|
||||
|
||||
CMyVektor gradient(double f(CMyVektor x), CMyVektor x) {
|
||||
CMyVektor grad(x.getDimension());
|
||||
CMyVektor xh(x.getDimension()); // x mit "Wackelei" an x_i
|
||||
xh = x;
|
||||
|
||||
double fx = f(x);
|
||||
double h = 1e-8;
|
||||
|
||||
// Berechnung der partiellen Ableitung nach x_i und Zusammenfassung in grad
|
||||
for (int i = 0; i < x.getDimension(); i++) {
|
||||
// xh[0] xh[1] ... xh[n]
|
||||
// x_1+h,x_2,...,x_n x_1,x_2+h,...,x_n x_1,x_2,...,x_n+1
|
||||
xh[i] += h;
|
||||
|
||||
// grad[i] = df/dx_i => numerische Ableitung nach dem jeweilige x_i
|
||||
grad[i] = (f(xh) - fx) / h;
|
||||
|
||||
// Zurücksetzen der "Wackelei"
|
||||
xh[i] -= h;
|
||||
}
|
||||
return grad;
|
||||
}
|
||||
|
||||
CMyVektor gradientenverfahren(double f(CMyVektor x), CMyVektor x, double lambda) {
|
||||
int schritt_zaehler = 0;
|
||||
CMyVektor gradfx(x.getDimension());
|
||||
CMyVektor x_neu(x.getDimension());
|
||||
gradfx = gradient(f, x);
|
||||
|
||||
while (gradient(f, x).length() >= 1e-5 && schritt_zaehler < 25) {
|
||||
x_neu = x + lambda * gradfx;
|
||||
|
||||
std::cout
|
||||
<< "Schritt " << schritt_zaehler << ": " << std::endl
|
||||
<< " x = " << x << std::endl
|
||||
<< " λ = " << lambda << std::endl
|
||||
<< " f(x) = " << f(x) << std::endl
|
||||
<< " grad f(x) = " << gradfx << std::endl
|
||||
<< " ||grad f(x)|| = " << gradfx.length() << std::endl << std::endl
|
||||
<< " x_neu = " << x_neu << std::endl
|
||||
<< " f(x_neu) = " << f(x_neu) << std::endl << std::endl;
|
||||
|
||||
// Halbierung
|
||||
if (f(x_neu) <= f(x)) {
|
||||
double lamda_test = lambda * 0.5;
|
||||
CMyVektor x_test = x + lamda_test * gradfx;
|
||||
|
||||
std::cout
|
||||
<< " ↯ f(x) = " << f(x) << " ≥ f(x_neu) = " << f(x_neu) << std::endl << std::endl
|
||||
<< " ? Test mit halbierter Schrittweite (λ = " << lamda_test << "): " << std::endl
|
||||
<< " x_test = " << x_test << std::endl
|
||||
<< " f(x_test) = " << f(x_test) << std::endl << std::endl;
|
||||
|
||||
if (f(x) < f(x_test))
|
||||
std::cout
|
||||
<< " ✓ f(x) = " << f(x) << " < f(x_test) = " << f(x_test) << std::endl
|
||||
<< " ! Übernehme Schrittweite." << std::endl << std::endl;
|
||||
|
||||
// weiter Halbieren wenn f(x_test) <= f(x)
|
||||
while (f(x_test) <= f(x)) {
|
||||
std::cout
|
||||
<< " ↯ f(x) = " << f(x) << " ≥ f(x_test) = " << f(x_test) << std::endl << std::endl;
|
||||
|
||||
lamda_test *= 0.5;
|
||||
x_test = x + lamda_test * gradfx;
|
||||
|
||||
std::cout
|
||||
<< " ? Test mit halbierter Schrittweite (λ = " << lamda_test << "): " << std::endl
|
||||
<< " x_test = " << x_test << std::endl
|
||||
<< " f(x_test) = " << f(x_test) << std::endl << std::endl;
|
||||
|
||||
// Ausgabe beim letzten Durchlauf der Schleife
|
||||
if (!(f(x_test) <= f(x)))
|
||||
std::cout
|
||||
<< " ✓ f(x) = " << f(x) << " < f(x_test) = " << f(x_test) << std::endl << std::endl
|
||||
<< " ! Übernehme Schrittweite λ = " << lamda_test << std::endl << std::endl;
|
||||
}
|
||||
|
||||
lambda = lamda_test;
|
||||
x_neu = x_test;
|
||||
}
|
||||
|
||||
// Verdopplung
|
||||
else {
|
||||
double lamda_test = lambda * 2;
|
||||
CMyVektor x_test = x + lamda_test * gradfx;
|
||||
|
||||
std::cout
|
||||
<< " ? Test mit doppelter Schrittweite (λ = " << lamda_test << "): " << std::endl
|
||||
<< " x_test = " << x_test << std::endl
|
||||
<< " f(x_test) = " << f(x_test) << std::endl << std::endl;
|
||||
|
||||
if (f(x_test) > f(x_neu)) {
|
||||
x_neu = x_test;
|
||||
lambda = lamda_test;
|
||||
std::cout
|
||||
<< " ! Übernehme verdoppelte Schrittweite λ = " << lamda_test << std::endl
|
||||
<< " ✓ f(x_neu) = " << f(x_neu) << " < f(x_test) = " << f(x_test) << std::endl << std::endl;
|
||||
}
|
||||
else {
|
||||
std::cout
|
||||
<< " ↯ f(x_neu) = " << f(x_neu) << " ≥ f(x_test) = " << f(x_test) << std::endl
|
||||
<< " ! behalte aktuelle Schrittweite λ = " << lambda << std::endl << std::endl;
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
x = x_neu;
|
||||
gradfx = gradient(f, x);
|
||||
schritt_zaehler++;
|
||||
}
|
||||
|
||||
// Zusammenfassung des Endes
|
||||
if (gradfx.length() < 1e-5)
|
||||
std::cout
|
||||
<< "Ende wegen ||grad f(x)|| < 10^-5 bei" << std::endl;
|
||||
|
||||
else
|
||||
std::cout
|
||||
<< "Ende wegen 25. Schritt" << std::endl;
|
||||
|
||||
std::cout
|
||||
<< " x = " << x << std::endl
|
||||
<< " λ = " << lambda << std::endl
|
||||
<< " f(x) = " << f(x) << std::endl
|
||||
<< " grad f(x) = " << gradfx << std::endl
|
||||
<< " ||grad f(x)|| = " << gradfx.length() << std::endl
|
||||
<< "-----------------------------------------------------" << std::endl << std::endl;
|
||||
|
||||
return x_neu;
|
||||
}
|
||||
38
P3/CMyVektor.h
Executable file
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
class CMyVektor {
|
||||
private:
|
||||
int dimension;
|
||||
std::vector<double> werte;
|
||||
public:
|
||||
// Vektor mit Dimension anlegen
|
||||
CMyVektor(int n) : dimension{ n } {
|
||||
werte.resize(n);
|
||||
}
|
||||
|
||||
CMyVektor(std::vector<double> x) : dimension{ (int)x.size() } {
|
||||
werte.resize(x.size());
|
||||
for (int i = 0; i < x.size(); i++)
|
||||
werte[i] = x[i];
|
||||
}
|
||||
|
||||
double getElement(int i);
|
||||
void setElement(int i, double j);
|
||||
void setElements(std::vector<double> x);
|
||||
|
||||
int getDimension();
|
||||
double length();
|
||||
|
||||
// Komponente von Vektor übergeben
|
||||
double& operator[](int index);
|
||||
};
|
||||
|
||||
CMyVektor operator+(CMyVektor a, CMyVektor b);
|
||||
CMyVektor operator*(double lambda, CMyVektor a);
|
||||
|
||||
std::ostream& operator<< (std::ostream& os, CMyVektor& vektor);
|
||||
|
||||
CMyVektor gradient(double f(CMyVektor x), CMyVektor x);
|
||||
CMyVektor gradientenverfahren(double f(CMyVektor x), CMyVektor x, double lambda = 1.0);
|
||||
110
P3/C_DGLSolver.cpp
Executable file
@@ -0,0 +1,110 @@
|
||||
#include "C_DGLSolver.h"
|
||||
using namespace std;
|
||||
|
||||
C_DGLSolver::C_DGLSolver() {
|
||||
}
|
||||
|
||||
// Konstruktor für DGL 1. Ordnung
|
||||
C_DGLSolver::C_DGLSolver(CMyVektor(*f_DGL_System)(CMyVektor y, double x)) {
|
||||
isDGLSystem = true;
|
||||
fDglSystemZeiger = f_DGL_System;
|
||||
}
|
||||
|
||||
// Konstruktor für DGL n-ter Ordnung
|
||||
C_DGLSolver::C_DGLSolver(double(*f_DGL_nterOrdnung)(CMyVektor y, double x)) {
|
||||
isDGLSystem = false;
|
||||
fDglNterOrdnungZeiger = f_DGL_nterOrdnung;
|
||||
}
|
||||
|
||||
C_DGLSolver::~C_DGLSolver() {
|
||||
}
|
||||
|
||||
CMyVektor C_DGLSolver::euler(CMyVektor y, double xStart, double XEnd, double schritte) {
|
||||
double schrittweite = (XEnd - xStart) / schritte;
|
||||
CMyVektor yCopy(y.getDimension());
|
||||
CMyVektor yAbl(y.getDimension());
|
||||
yCopy = y;
|
||||
|
||||
double x = xStart;
|
||||
int s = 0;
|
||||
cout << "h = " << schrittweite << endl;
|
||||
|
||||
for (; s < schritte; s++, x += schrittweite) {
|
||||
yAbl = ableitungen(yCopy, x);
|
||||
|
||||
cout << "Schritt " << s << ": " << endl
|
||||
<< "\t" << " 𝑥 = " << x << endl
|
||||
<< "\t" << " 𝑦 = " << yCopy << endl
|
||||
<< "\t" << "𝑦' = " << yAbl << endl << endl;
|
||||
|
||||
for (int i = 1; i <= yCopy.getDimension(); i++)
|
||||
yCopy.setElement(i, yCopy.getElement(i) + schrittweite * yAbl.getElement(i));
|
||||
}
|
||||
|
||||
cout << "Ende bei " << endl;
|
||||
cout << "\t" << " 𝑥 = " << x << endl;
|
||||
cout << "\t" << " 𝑦 = " << yCopy << endl;
|
||||
return yCopy;
|
||||
}
|
||||
|
||||
CMyVektor C_DGLSolver::heun(CMyVektor y, double xStart, double XEnd, double schritte) {
|
||||
double schrittweite = (XEnd - xStart) / schritte;
|
||||
CMyVektor yCopy(y.getDimension());
|
||||
CMyVektor yCopyTest(y.getDimension());
|
||||
yCopy = y;
|
||||
|
||||
CMyVektor yAbl(y.getDimension());
|
||||
CMyVektor yAblTest(y.getDimension());
|
||||
CMyVektor fx_mStg(y.getDimension());
|
||||
|
||||
double x = xStart;
|
||||
int s = 0;
|
||||
cout << "h = " << schrittweite << endl;
|
||||
|
||||
for (; s < schritte; x += schrittweite, s++) {
|
||||
yAbl = ableitungen(yCopy, x);
|
||||
|
||||
cout << "Schritt " << s << ": " << endl;
|
||||
cout << "\t" << " 𝑥 = " << x << endl;
|
||||
cout << "\t" << " 𝑦 = " << yCopy << endl;
|
||||
|
||||
cout << "\t" << "𝑦ₒ' = " << yAbl << endl << endl;
|
||||
|
||||
|
||||
for (int i = 1; i <= yCopy.getDimension(); i++)
|
||||
yCopyTest.setElement(i, yCopy.getElement(i) + schrittweite * yAbl.getElement(i));
|
||||
|
||||
yAblTest = ableitungen(yCopyTest, x + schrittweite);
|
||||
|
||||
for (int i = 1; i <= fx_mStg.getDimension(); i++)
|
||||
fx_mStg.setElement(i, 0.5 * (yAbl.getElement(i) + yAblTest.getElement(i)));
|
||||
|
||||
for (int i = 1; i <= yCopy.getDimension(); i++)
|
||||
yCopy.setElement(i, yCopy.getElement(i) + schrittweite * fx_mStg.getElement(i));
|
||||
|
||||
cout << "\t" << " 𝑦ₜ = " << yCopyTest << endl;
|
||||
cout << "\t" << "𝑦ₜ' = " << yAblTest << endl << endl;
|
||||
cout << "\t" << "𝑦ₘ' = " << fx_mStg << endl << endl;
|
||||
}
|
||||
|
||||
cout << "Ende bei " << endl
|
||||
<< "\t" << " 𝑥 = " << x << endl
|
||||
<< "\t" << " 𝑦 = " << yCopy << endl;
|
||||
|
||||
return yCopy;
|
||||
}
|
||||
|
||||
CMyVektor C_DGLSolver::ableitungen(CMyVektor y, double x) {
|
||||
CMyVektor result(y.getDimension());
|
||||
|
||||
if (isDGLSystem) {
|
||||
result = fDglSystemZeiger(y, x);
|
||||
}
|
||||
else {
|
||||
for (int i = 1; i < y.getDimension(); i++)
|
||||
result.setElement(i, y.getElement(i + 1));
|
||||
|
||||
result.setElement(y.getDimension(), fDglNterOrdnungZeiger(y, x));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
26
P3/C_DGLSolver.h
Executable file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#ifndef C_DGLSolver_h
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include "CMyVektor.h"
|
||||
|
||||
class C_DGLSolver
|
||||
{
|
||||
public:
|
||||
C_DGLSolver();
|
||||
C_DGLSolver(CMyVektor(*f_DGL_System)(CMyVektor y, double x));
|
||||
C_DGLSolver(double(*f_DGL_nterOrdnung)(CMyVektor y, double x));
|
||||
~C_DGLSolver();
|
||||
CMyVektor euler(CMyVektor y, double xStart, double XEnd, double h);
|
||||
CMyVektor heun(CMyVektor y, double xStart, double XEnd, double h);
|
||||
|
||||
|
||||
private:
|
||||
CMyVektor(*fDglSystemZeiger)(CMyVektor y, double x);
|
||||
double(*fDglNterOrdnungZeiger)(CMyVektor y, double x);
|
||||
bool isDGLSystem;
|
||||
CMyVektor ableitungen(CMyVektor y, double x);
|
||||
};
|
||||
|
||||
#endif // !C_DGLSolver_h
|
||||
BIN
P3/Heun Verfahren.ods
Executable file
BIN
P3/Praktikum3.pdf
Executable file
99
P3/main.cpp
Executable file
@@ -0,0 +1,99 @@
|
||||
#include <math.h>
|
||||
#include "CMyVektor.h"
|
||||
#include "CMyMatrix.h"
|
||||
#include "C_DGLSolver.h"
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
CMyVektor DGLSystem(CMyVektor y, double x) {
|
||||
CMyVektor result(2);
|
||||
result.setElement(1, 2 * y.getElement(2) - x * y.getElement(1));
|
||||
result.setElement(2, y.getElement(1) * y.getElement(2) - 2 * pow(x, 3));
|
||||
return result;
|
||||
}
|
||||
|
||||
double DGL_dritter_Ordnung(CMyVektor y, double x) {
|
||||
return 2 * x * y.getElement(2) * y.getElement(3) + 2 * pow(y.getElement(1), 2) * y.getElement(2);
|
||||
}
|
||||
|
||||
int main() {
|
||||
int option;
|
||||
|
||||
cout << "Was soll berechnet werden? \n" <<
|
||||
"1 Euler-Verfahren DGL\n" <<
|
||||
"2 Heun-Verfahren DGL\n" <<
|
||||
"3 Abweichungen DGL 3.O\n" <<
|
||||
"0 Beenden\n"
|
||||
"> ";
|
||||
cin >> option;
|
||||
|
||||
while (0 < option && option < 4) {
|
||||
switch (option) {
|
||||
case 1: {
|
||||
CMyVektor startwerte(vector<double>{0, 1});
|
||||
double xStart = 0; // x0 = 0
|
||||
double xEnd = 2;
|
||||
C_DGLSolver dglSystemTest(DGLSystem);
|
||||
dglSystemTest.euler(startwerte, xStart, xEnd, 100);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
CMyVektor startwerte(vector<double>{0, 1});
|
||||
double xStart = 0; // x0 = 0
|
||||
double xEnd = 2;
|
||||
C_DGLSolver dglSystemTest(DGLSystem);
|
||||
dglSystemTest.heun(startwerte, xStart, xEnd, 100);
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
CMyVektor startwerte(3);
|
||||
CMyVektor eulerResult(3);
|
||||
CMyVektor heunResult(3);
|
||||
CMyVektor allResults(8);
|
||||
C_DGLSolver dglSystemTest(DGL_dritter_Ordnung);
|
||||
|
||||
|
||||
double schritte;
|
||||
double xStart;
|
||||
double xEnd;
|
||||
int j = 1;
|
||||
for (int i = 1; i < 5; i++) {
|
||||
schritte = pow(10, i);
|
||||
xStart = 1;
|
||||
xEnd = 2;
|
||||
startwerte.setElements(vector<double>{1, -1, 2});
|
||||
eulerResult = dglSystemTest.euler(startwerte, xStart, xEnd, schritte);
|
||||
allResults.setElement(j, eulerResult.getElement(1) - 0.5);
|
||||
|
||||
startwerte.setElements(vector<double>{1, -1, 2});
|
||||
heunResult = dglSystemTest.heun(startwerte, xStart, xEnd, schritte);
|
||||
allResults.setElement(++j, heunResult.getElement(1) - 0.5);
|
||||
j++;
|
||||
}
|
||||
cout << endl;
|
||||
int k = 1;
|
||||
cout << setw(10) << "Verfahren" << setw(10) << "Schritte" << setw(10) << "Δ\n";
|
||||
for (int j = 1; j <= 4; j++) {
|
||||
double schritte = pow(10, j);
|
||||
// E = s+1 , H = E*2
|
||||
cout << setw(10) << "Euler" << setw(10) << setprecision(0) << schritte << setw(10) << scientific << setprecision(1) << allResults.getElement(k) << endl;
|
||||
cout << setw(10) << "Heun" << setw(10) << setprecision(0) << schritte << setw(10) << scientific << setprecision(1) << allResults.getElement(++k) << endl << endl;
|
||||
|
||||
k++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cout << "\nHauptmenü: \n" <<
|
||||
"1 Euler-Verfahren DGL\n" <<
|
||||
"2 Heun-Verfahren DGL\n" <<
|
||||
"3 Euler/Heun Vergleich DGL 3.O\n" <<
|
||||
"0 Beenden\n"
|
||||
"> ";
|
||||
cin >> option;
|
||||
|
||||
};
|
||||
cout << endl << endl;
|
||||
system("PAUSE");
|
||||
}
|
||||
1001
P4/Bilder/1/Daten_original1.txt
Executable file
BIN
P4/Bilder/1/Daten_original1_.png
Executable file
|
After Width: | Height: | Size: 249 B |
1001
P4/Bilder/1/ZDaten_transformiert_0_001.txt
Executable file
1001
P4/Bilder/1/ZDaten_transformiert_0_01.txt
Executable file
BIN
P4/Bilder/1/ZDaten_transformiert_0_01_.png
Executable file
|
After Width: | Height: | Size: 249 B |
1001
P4/Bilder/1/ZDaten_transformiert_0_1.txt
Executable file
BIN
P4/Bilder/1/ZDaten_transformiert_0_1_.png
Executable file
|
After Width: | Height: | Size: 254 B |
1001
P4/Bilder/1/ZDaten_transformiert_1_0.txt
Executable file
1001
P4/Bilder/1/ZDaten_transformiert_default.txt
Executable file
BIN
P4/Bilder/1/ZDaten_transformiert_default_.png
Executable file
|
After Width: | Height: | Size: 249 B |
1001
P4/Bilder/2/Daten_original2.txt
Executable file
BIN
P4/Bilder/2/Daten_original2_.png
Executable file
|
After Width: | Height: | Size: 249 B |
3606
P4/Bilder/FH Logo/ZDaten_transformiert_10.txt
Executable file
3565
P4/Bilder/FH Logo/ZDaten_transformiert_100.txt
Executable file
BIN
P4/Bilder/FH Logo/ZDaten_transformiert_100_.png
Executable file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
P4/Bilder/FH Logo/ZDaten_transformiert_10_.png
Executable file
|
After Width: | Height: | Size: 2.6 KiB |
3603
P4/Bilder/FH Logo/ZDaten_transformiert_30.txt
Executable file
11
P4/Bilder/FH Logo/ZDaten_transformiert_300.txt
Executable file
@@ -0,0 +1,11 @@
|
||||
4096
|
||||
1868 303.113 -5.16085e-11
|
||||
1932 305.132 -3.8197e-11
|
||||
1996 306.455 7.16582e-12
|
||||
2060 307.681 1.10596e-11
|
||||
2124 308.876 -8.74891e-11
|
||||
2188 309.485 -3.58149e-11
|
||||
2252 308.38 -1.0786e-11
|
||||
2316 304.067 -6.60449e-12
|
||||
2461 302.54 -3.15374e-11
|
||||
2525 302.324 -2.92957e-11
|
||||
BIN
P4/Bilder/FH Logo/ZDaten_transformiert_300_.png
Executable file
|
After Width: | Height: | Size: 72 B |
BIN
P4/Bilder/FH Logo/ZDaten_transformiert_30_.png
Executable file
|
After Width: | Height: | Size: 2.8 KiB |
4097
P4/Bilder/FH Logo/ZDaten_transformiert_d.txt
Executable file
BIN
P4/Bilder/FH Logo/ZDaten_transformiert_d_.png
Executable file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
P4/Bilder/FH Logo/download.jpg
Executable file
|
After Width: | Height: | Size: 24 KiB |
4097
P4/Bilder/FH Logo/download.txt
Executable file
BIN
P4/Bilder/Landschaft/Eingabe.png
Executable file
|
After Width: | Height: | Size: 3.1 KiB |
4097
P4/Bilder/Landschaft/ZDaten_transformiert_10.txt
Executable file
1659
P4/Bilder/Landschaft/ZDaten_transformiert_100.txt
Executable file
BIN
P4/Bilder/Landschaft/ZDaten_transformiert_100_.png
Executable file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
P4/Bilder/Landschaft/ZDaten_transformiert_10_.png
Executable file
|
After Width: | Height: | Size: 3.2 KiB |
4074
P4/Bilder/Landschaft/ZDaten_transformiert_30.txt
Executable file
1
P4/Bilder/Landschaft/ZDaten_transformiert_300.txt
Executable file
@@ -0,0 +1 @@
|
||||
4096
|
||||
BIN
P4/Bilder/Landschaft/ZDaten_transformiert_30_.png
Executable file
|
After Width: | Height: | Size: 3.0 KiB |
4097
P4/Bilder/Landschaft/ZDaten_transformiert_d.txt
Executable file
BIN
P4/Bilder/Landschaft/ZDaten_transformiert_d_.png
Executable file
|
After Width: | Height: | Size: 3.1 KiB |
4097
P4/Bilder/Landschaft/bild_d_r.txt
Executable file
BIN
P4/Bilder/Landschaft/bild_d_r_.png
Executable file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
P4/Bilder/Landschaft/proxy-image.jpg
Executable file
|
After Width: | Height: | Size: 61 KiB |
4097
P4/Bilder/Landschaft/proxy-image.txt
Executable file
56
P4/CKomplex.cpp
Executable file
@@ -0,0 +1,56 @@
|
||||
#include "CKomplex.h"
|
||||
#include <cmath>
|
||||
|
||||
// Konstruktor mit zwei Argumenten f<>r a + b*j
|
||||
CKomplex::CKomplex() : real(0), imag(0) {
|
||||
}
|
||||
|
||||
// Konstruktor mit zwei Argumenten f<>r a + b*j
|
||||
CKomplex::CKomplex(double a, double b) : real(a), imag(b) {
|
||||
}
|
||||
|
||||
// Konstruktor mit einem Argument f<>r e^(j*phi)
|
||||
CKomplex::CKomplex(double phi) : real(cos(phi)), imag(sin(phi)) {
|
||||
}
|
||||
|
||||
// Methode zur R<>ckgabe des Realteils
|
||||
double CKomplex::re() const {
|
||||
return real;
|
||||
}
|
||||
|
||||
// Methode zur R<>ckgabe des Imagin<69>rteils
|
||||
double CKomplex::im() const {
|
||||
return imag;
|
||||
}
|
||||
|
||||
// <20>berladene Methode f<>r die Addition von zwei komplexen Zahlen
|
||||
CKomplex CKomplex::operator+(const CKomplex &other) const {
|
||||
double a = real + other.real;
|
||||
double b = imag + other.imag;
|
||||
return CKomplex(a, b);
|
||||
}
|
||||
|
||||
// <20>berladene Methode f<>r die Subtraktion von zwei komplexen Zahlen
|
||||
CKomplex CKomplex::operator-(const CKomplex &other) const {
|
||||
double a = real - other.real;
|
||||
double b = imag - other.imag;
|
||||
return CKomplex(a, b);}
|
||||
|
||||
// <20>berladene Methode f<>r die Multiplikation von zwei komplexen Zahlen
|
||||
CKomplex CKomplex::operator*(const CKomplex &other) const {
|
||||
double a = real * other.real - imag * other.imag;
|
||||
double b = real * other.imag + imag * other.real;
|
||||
return CKomplex(a, b);
|
||||
}
|
||||
|
||||
// <20>berladene Methode f<>r die Multiplikation einer double-Zahl mit einer komplexen Zahl
|
||||
CKomplex CKomplex::operator*(double scalar) const {
|
||||
double a = real * scalar;
|
||||
double b = imag * scalar;
|
||||
return CKomplex(a, b);
|
||||
}
|
||||
|
||||
// Methode zur Berechnung des Betrags der komplexen Zahl
|
||||
double CKomplex::abs() const {
|
||||
return sqrt(real * real + imag * imag);
|
||||
}
|
||||
24
P4/CKomplex.h
Executable file
@@ -0,0 +1,24 @@
|
||||
class CKomplex {
|
||||
private:
|
||||
double real;
|
||||
double imag;
|
||||
|
||||
public:
|
||||
// Konstruktoren
|
||||
CKomplex();
|
||||
CKomplex(double a, double b);
|
||||
CKomplex(double phi);
|
||||
|
||||
// Methoden zur R<>ckgabe des Real- und Imagin<69>rteils
|
||||
double re() const;
|
||||
double im() const;
|
||||
|
||||
// <20>berladene Operatoren f<>r Addition und Multiplikation
|
||||
CKomplex operator+(const CKomplex& other) const;
|
||||
CKomplex operator-(const CKomplex& other) const;
|
||||
CKomplex operator*(const CKomplex& other) const;
|
||||
CKomplex operator*(double scalar) const;
|
||||
|
||||
// Methode zur Berechnung des Betrags
|
||||
double abs() const;
|
||||
};
|
||||
12
P4/CMakeLists.txt
Executable file
@@ -0,0 +1,12 @@
|
||||
# Set the minimum required version of CMake
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
|
||||
# Set the project name and specify the C++ as the project language
|
||||
project(HM_P4)
|
||||
|
||||
# Specify the C++ standard
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# Add an executable with the above sources
|
||||
add_executable(HM_P4 main.cpp CKomplex.cpp Fourier.cpp)
|
||||
1001
P4/Daten_original1.txt
Executable file
1001
P4/Daten_original2.txt
Executable file
30
P4/Fourier.cpp
Executable file
@@ -0,0 +1,30 @@
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
#include "Fourier.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
vector<CKomplex> fourier(vector<CKomplex> werte, int vz) {
|
||||
int N = werte.size();
|
||||
vector<CKomplex> ret;
|
||||
|
||||
for (int n = 0; n < N; n++) {
|
||||
CKomplex v(0,0);
|
||||
for (int k = 0; k < N; k++) {
|
||||
double phi = (vz * -2.0 * M_PI * k * n) / (double) N;
|
||||
CKomplex e = werte[k] * CKomplex(phi);
|
||||
v = v + e;
|
||||
}
|
||||
v = v * (1 / sqrt(N));
|
||||
ret.push_back(v);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
vector<CKomplex> Fourier::hin(vector<CKomplex> werte) {
|
||||
return fourier(werte, -1);
|
||||
}
|
||||
|
||||
vector<CKomplex> Fourier::zurueck(vector<CKomplex> werte) {
|
||||
return fourier(werte, 1);
|
||||
}
|
||||
12
P4/Fourier.h
Executable file
@@ -0,0 +1,12 @@
|
||||
#ifndef __FOURIER_H__
|
||||
# define __FOURIER_H__
|
||||
#include <vector>
|
||||
#include "CKomplex.h"
|
||||
|
||||
namespace Fourier
|
||||
{
|
||||
extern std::vector<CKomplex> hin(std::vector<CKomplex> werte);
|
||||
extern std::vector<CKomplex> zurueck(std::vector<CKomplex> werte);
|
||||
}
|
||||
|
||||
#endif
|
||||
106
P4/main.cpp
Executable file
@@ -0,0 +1,106 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include "Fourier.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
vector<CKomplex> werte_einlesen(string dateiname) {
|
||||
int i, N, idx;
|
||||
double re, im;
|
||||
vector<CKomplex> werte;
|
||||
ifstream fp;
|
||||
fp.open(dateiname);
|
||||
if (fp.is_open()) {
|
||||
fp >> N;
|
||||
werte.resize(N);
|
||||
CKomplex null(0, 0);
|
||||
for (i = 0; i < N; i++)
|
||||
werte[i] = null;
|
||||
while (!fp.eof()) {
|
||||
fp >> idx >> re >> im;
|
||||
CKomplex a(re, im);
|
||||
werte[idx] = a;
|
||||
}
|
||||
fp.close();
|
||||
}
|
||||
return werte;
|
||||
}
|
||||
|
||||
void werte_ausgeben(string dateiname, vector<CKomplex> &werte, double epsilon = -1.0) {
|
||||
|
||||
int i;
|
||||
int N = werte.size();
|
||||
ofstream fp;
|
||||
fp.open(dateiname);
|
||||
if (fp.is_open()) {
|
||||
fp << N << endl;
|
||||
for (i = 0; i < N; i++)
|
||||
if (werte[i].abs() > epsilon)
|
||||
fp << i << "\t" << setprecision(10) << werte[i].re() << "\t" << werte[i].im() << endl;
|
||||
fp.close();
|
||||
}
|
||||
}
|
||||
|
||||
double abweichung(vector<CKomplex> &a, vector<CKomplex> &b) {
|
||||
double r;
|
||||
if (a.size() == b.size()) {
|
||||
for (size_t i(0U), sz(a.size()); i != sz; i++) {
|
||||
CKomplex a1(a[i]);
|
||||
CKomplex b1(b[i]);
|
||||
CKomplex difC = b1 - a1;
|
||||
double difAbs = difC.abs();
|
||||
if (r < difAbs)
|
||||
r = difAbs;
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
void abweichungBestimmen(string dateinameTransformiert, vector<CKomplex> transformierteWerte, double epsilon,
|
||||
string dateinameOriginal) {
|
||||
vector<CKomplex> originaleWerte(werte_einlesen(dateinameOriginal));
|
||||
werte_ausgeben(dateinameTransformiert, transformierteWerte, epsilon);
|
||||
|
||||
vector<CKomplex> transformierteWerteEpsilon = werte_einlesen(dateinameTransformiert);
|
||||
vector<CKomplex> zurueckTransformiertWerte = Fourier::zurueck(transformierteWerteEpsilon);
|
||||
|
||||
string nameZ = "Z" + dateinameTransformiert;
|
||||
werte_ausgeben(nameZ, zurueckTransformiertWerte, -1);
|
||||
|
||||
cout << "Maximale Abweichung bei epsilon " << epsilon << " = " << abweichung(
|
||||
originaleWerte, zurueckTransformiertWerte) << endl;
|
||||
}
|
||||
|
||||
int main() {
|
||||
string dateinameOriginal = "Daten_original2.txt";
|
||||
|
||||
vector<CKomplex> originalWerte = werte_einlesen(dateinameOriginal);
|
||||
|
||||
vector<CKomplex> transformierteWerte = Fourier::hin(originalWerte);
|
||||
|
||||
/*
|
||||
werte_ausgeben("Daten_original_TEST.txt", originalWerte);
|
||||
|
||||
|
||||
werte_ausgeben("Daten_original1_trafo.txt", transformierteWerte, -1);
|
||||
|
||||
vector<CKomplex> transformierteWerteA = werte_einlesen("Daten_original1_trafo.txt");
|
||||
vector<CKomplex> zurueckTransformiertWerte = Fourier::zurueck(transformierteWerteA);
|
||||
werte_ausgeben("Daten_original1_Rtrafo.txt", zurueckTransformiertWerte);
|
||||
|
||||
cout << "Maximale Abweichung bei epsilon " << -1 << " = " << abweichung(
|
||||
zurueckTransformiertWerte, originalWerte) << endl;
|
||||
|
||||
*/
|
||||
|
||||
abweichungBestimmen("Daten_transformiert_default.txt", transformierteWerte, -1, dateinameOriginal);
|
||||
abweichungBestimmen("Daten_transformiert_0_001.txt", transformierteWerte, 0.001, dateinameOriginal);
|
||||
abweichungBestimmen("Daten_transformiert_0_01.txt", transformierteWerte, 0.01, dateinameOriginal);
|
||||
abweichungBestimmen("Daten_transformiert_0_1.txt", transformierteWerte, 0.1, dateinameOriginal);
|
||||
abweichungBestimmen("Daten_transformiert_1_0.txt", transformierteWerte, 1.0, dateinameOriginal);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
12
P5/CMakeLists.txt
Executable file
@@ -0,0 +1,12 @@
|
||||
# Set the minimum required version of CMake
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
|
||||
# Set the project name and specify the C++ as the project language
|
||||
project(HM_P5)
|
||||
|
||||
# Specify the C++ standard
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# Add an executable with the above sources
|
||||
add_executable(HM_P5 main.cpp)
|
||||
117
P5/main.cpp
Executable file
@@ -0,0 +1,117 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <ctime>
|
||||
#include <cstdlib>
|
||||
#include <set>
|
||||
|
||||
class CZufall {
|
||||
public:
|
||||
void initialisiere(int s) {
|
||||
srand(s);
|
||||
}
|
||||
|
||||
int wert(int a, int b) {
|
||||
return a + rand() % (b - a + 1);
|
||||
}
|
||||
|
||||
void test(int a, int b, int N) {
|
||||
std::vector<int> haeufigkeiten(b - a + 1, 0);
|
||||
for (int i = 0; i < N; ++i) {
|
||||
int zahl = wert(a, b);
|
||||
haeufigkeiten[zahl - a]++;
|
||||
}
|
||||
for (int i = 0; i < haeufigkeiten.size(); ++i) {
|
||||
std::cout << a + i << ": " << haeufigkeiten[i] << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void test_falsch(int a, int b, int N) {
|
||||
std::vector<int> haeufigkeiten(b - a + 1, 0);
|
||||
for (int i = 0; i < N; ++i) {
|
||||
initialisiere(time(NULL));
|
||||
int zahl = wert(a, b);
|
||||
haeufigkeiten[zahl - a]++;
|
||||
}
|
||||
for (int i = 0; i < haeufigkeiten.size(); ++i) {
|
||||
std::cout << a + i << ": " << haeufigkeiten[i] << std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class CLotto {
|
||||
private:
|
||||
int k, n;
|
||||
std::vector<int> tippzettel;
|
||||
CZufall zufall;
|
||||
|
||||
public:
|
||||
CLotto(int k, int n, int s) : k(k), n(n) {
|
||||
if (s < 0) {
|
||||
zufall.initialisiere(time(NULL));
|
||||
} else {
|
||||
zufall.initialisiere(s);
|
||||
}
|
||||
}
|
||||
|
||||
void setzeTippzettel(const std::vector<int>& tipp) {
|
||||
tippzettel = tipp;
|
||||
}
|
||||
|
||||
std::vector<int> ziehung() {
|
||||
std::set<int> unique_numbers;
|
||||
while (unique_numbers.size() < k) {
|
||||
int zahl = zufall.wert(1, n);
|
||||
unique_numbers.insert(zahl);
|
||||
}
|
||||
return std::vector<int>(unique_numbers.begin(), unique_numbers.end());
|
||||
}
|
||||
|
||||
int anzahlRichtige(const std::vector<int>& ziehung) {
|
||||
int richtige = 0;
|
||||
for (int zahl : ziehung) {
|
||||
if (std::find(tippzettel.begin(), tippzettel.end(), zahl) != tippzettel.end()) {
|
||||
richtige++;
|
||||
}
|
||||
}
|
||||
return richtige;
|
||||
}
|
||||
|
||||
double monteCarloSimulation(int r, int N, bool gleicherTippzettel) {
|
||||
int treffer = 0;
|
||||
for (int i = 0; i < N; ++i) {
|
||||
if (!gleicherTippzettel) {
|
||||
setzeTippzettel(ziehung());
|
||||
}
|
||||
std::vector<int> aktuelleZiehung = ziehung();
|
||||
if (anzahlRichtige(aktuelleZiehung) == r) {
|
||||
treffer++;
|
||||
}
|
||||
}
|
||||
return static_cast<double>(treffer) / N;
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
// Aufgabe 1: Testen der Klasse CZufall
|
||||
CZufall zufall;
|
||||
zufall.initialisiere(42);
|
||||
zufall.test(3, 7, 10000);
|
||||
zufall.test_falsch(3, 7, 10000);
|
||||
|
||||
// Aufgabe 2: Testen der Klasse CLotto
|
||||
CLotto lotto(8, 38, -1);
|
||||
std::vector<int> tippzettel = {1, 2, 3, 4, 5, 6, 7, 8};
|
||||
lotto.setzeTippzettel(tippzettel);
|
||||
std::vector<int> ziehung = lotto.ziehung();
|
||||
std::cout << "Anzahl Richtige: " << lotto.anzahlRichtige(ziehung) << std::endl;
|
||||
|
||||
// Monte-Carlo-Simulation
|
||||
double wahrscheinlichkeit = lotto.monteCarloSimulation(2, 10000, true);
|
||||
double wahrscheinlichkeit2 = lotto.monteCarloSimulation(2, 10000, false);
|
||||
std::cout << "Wahrscheinlichkeit f<>r genau 3 Richtige: " << wahrscheinlichkeit << std::endl;
|
||||
std::cout << "Wahrscheinlichkeit f<>r genau 3 Richtige: " << wahrscheinlichkeit2 << std::endl;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||