Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cmath>
- #include <iomanip>
- #include <fstream>
- using namespace std;
- int Romberg_neu(double(*f)(double), double a, double b, double tol, int L_in, int &L_out, int &fcnt, double &Q){
- /* Näherungsweise Berechnung des Integrals über f von a bis b: I(f;a,b)
- % mit dem Romberg-Schema mit max. L_in Stufen.
- %
- % Eingabe:
- % f : Funktion der Form f(x); Integrand
- % a : reelle Zahl; untere Integrationsgrenze
- % b : reelle Zahl; obere Integrationsgrenze
- % tol : reelle Zahl; Genauigkeitstoleranz: |I(f;a,b)-Q|<=tol*(1+|Q|)
- % L_in : Integer; max. Anzahl Stufen im Romberg-Schema
- % Ausgabe:
- % rc : Integer; rc=0; Q wurde in gewünschter Genauigkeit berechnet.
- % rc=1; Q ist nicht genau genug. Es würden evtl. mehr Stufen (als L_in) benötigt.
- % rc=2; Eingabefehler: tol <=0
- %
- % L_out : Integer; Anzahl genutzter Stufen
- % fcnt : Integer; Anzahl Funktionsauswertungen des Integranden
- % Q : relle Zahl; Näherungswert für das Integral I(f;a,b)
- %
- %------- R. Reuter ----- 24.03.2013 --------------------------------------*/
- double Q1 = 0., E = 0., h = 0., ah = 0.;
- int n = 10; // Anzahl initialer Teilintervalle für ST-Formel
- int rc = 1; // Return Code
- double Fak = 1.0;
- int Lmax = L_in; // max. Anzahl Stufen
- int L = 0;
- double *QQ = new double[Lmax + 1]; // Array zum Speichern der jeweils aktuellen Zeile
- // des Romberg-Schemas
- fcnt = 0;
- if (tol <= 0.){
- rc = 2;
- return rc;
- }
- h = (b - a) / n;
- Q1 = 0.5 * (f(a) + f(b));
- fcnt = fcnt + 2;
- for (int k = 1; k<n; k++)
- Q1 = Q1 + f(a + k*h);
- fcnt = fcnt + n - 1;
- Q1 = h*Q1; // ST-Formel zu h
- QQ[1] = Q1;
- for (L = 2; L <= Lmax; L++){
- Q = 0.0;
- ah = a + 0.5*h;
- for (int k = 0; k<n; k++)
- Q = Q + f(ah + k*h);
- fcnt = fcnt + n;
- Q = 0.5*(QQ[1] + h*Q); // ST-Formel zu h/2
- Fak = 1.0;
- for (int LL = 1; LL<L; LL++){
- Fak = Fak*4.;
- Q1 = QQ[LL];
- QQ[LL] = Q;
- E = (Q - Q1) / (Fak - 1.0);
- Q = Q + E;
- }
- QQ[L] = Q;
- if (fabs(E) <= tol*(1 + fabs(Q))){
- rc = 0;
- break;
- }
- h = 0.5*h;
- n = 2 * n;
- }
- L_out = L;
- return rc;
- }
- struct funktionContainer
- {
- double(*funktion)(double);
- double(*ableitung)(double);
- double(*bogenlaenge)(double);
- };
- struct coordinate
- {
- double x;
- double y;
- };
- struct pointContainer
- {
- coordinate coord;
- double x_s1;
- double x_s2;
- int fcnt;
- int its;
- double angle;
- double radius;
- };
- double funktion1(double x)
- {
- return log(x);
- }
- double funktion1_ableitung(double x)
- {
- return 1. / x;
- }
- double funktion1_b(double x)
- {
- return sqrt(1. + (funktion1_ableitung(x) * funktion1_ableitung(x)));
- }
- double funktion2(double x)
- {
- return (x - 2.) * (x - 2.);
- }
- double funktion2_ableitung(double x)
- {
- return 2. * (x - 2.);
- }
- double funktion2_b(double x)
- {
- return sqrt(1. + (funktion2_ableitung(x) * funktion2_ableitung(x)));
- }
- double funktion3(double x)
- {
- return cosh(x);
- }
- double funktion3_ableitung(double x)
- {
- return sinh(x);
- }
- double funktion3_b(double x)
- {
- return sqrt(1. + (funktion3_ableitung(x) * funktion3_ableitung(x)));
- }
- double funktion4(double x)
- {
- return sqrt(x);
- }
- double funktion4_ableitung(double x)
- {
- return 1. / (2. * sqrt(x));
- }
- double funktion4_b(double x)
- {
- return sqrt(1. + (funktion4_ableitung(x) * funktion4_ableitung(x)));
- }
- double doEuklid(funktionContainer fkt, double x_s0, double d, int & iteration) //aufgabe B: bestimme euklidischen abstand
- {
- double differenz = 0.;
- double x_s1 = x_s0 + d;
- do
- {
- differenz = ((x_s1 - x_s0)*(x_s1 - x_s0) + (fkt.funktion(x_s1) - fkt.funktion(x_s0))*(fkt.funktion(x_s1) - fkt.funktion(x_s0)) - d*d)
- / (2 * (x_s1 - x_s0) + 2 * (fkt.funktion(x_s1) - fkt.funktion(x_s0)) * fkt.ableitung(x_s1));
- x_s1 -= differenz;
- iteration++;
- } while (abs(differenz) > 1e-10);
- return x_s1;
- }
- const double doTangente(const funktionContainer &fkt, const double &x_s0, const double &d) // Aufgabe C: gebraucht für bogenlänge
- {
- const double abl = fkt.ableitung(x_s0);
- return x_s0 + d / sqrt(abl * abl + 1.);
- }
- const double doSekante(const funktionContainer &fkt, const double &x_s0, const double &x_s1, const double &d)// Aufgabe C: gebraucht für bogenlänge
- {
- const double m = (fkt.funktion(x_s1) - fkt.funktion(x_s0)) / (x_s1 - x_s0);
- return x_s0 + d / (sqrt(m*m + 1.));
- }
- const double radToDeg(const double &rad) //feste formel
- {
- return rad * 180. / (4. * atan(1.));
- }
- const coordinate getDiffvector(const coordinate &a, const coordinate &b) //winkelfunktion
- {
- return coordinate{ b.x - a.x, b.y - a.y };
- }
- const double getRadius(const coordinate &vector) // winkelfunktion
- {
- return sqrt(vector.x * vector.x + vector.y * vector.y);
- }
- const double getRadius(const coordinate &a, const coordinate &b) // aufgabe F
- {
- return getRadius(getDiffvector(a, b));
- }
- const double getScalarproduct(const coordinate &a, const coordinate &b)
- {
- return a.x * b.x + a.y * b.y;
- }
- const double getAngle(const coordinate ¢er, const coordinate ¤tPoint, const coordinate &referencePoint)
- {
- const coordinate a = getDiffvector(center, currentPoint);
- const coordinate b = getDiffvector(center, referencePoint);
- return radToDeg(acos(getScalarproduct(a, b) / (getRadius(a) * getRadius(b))));
- }
- void save(const pointContainer* pointData, const int &size, const string &filename,double xEnd)
- {
- ofstream file;
- file.open(filename);
- file << '#' << "\t\t" << "Kartesische Koordinaten" << "\t\t\t\t\t\t\t\t\t\t\t\t" << "Polarkoordinaten" << endl;
- file << "#Nr." << '\t' << "x-Koord." << "\t\t" << "y-Koord." << "\t\t" << "x-Start_1" << "\t\t" << "x-Start_2" << "\t\t" <<
- "fcnt" << '\t' << "Its" << "\t" << "Winkel" << "\t\t\t" << "Radius" << endl;
- file << setprecision(14) << fixed;
- for (int i = 0; i < size; i++)
- {
- file << i << '\t' <<
- pointData[i].coord.x << '\t' <<
- pointData[i].coord.y << '\t' <<
- pointData[i].x_s1 << '\t' <<
- pointData[i].x_s2 << '\t' <<
- pointData[i].fcnt << '\t' <<
- pointData[i].its << '\t' <<
- pointData[i].angle << '\t' <<
- pointData[i].radius << '\t' << endl;
- }
- file << endl << endl;
- file << "Test: [xn,x(N),xn-x(N)] = " << endl;
- file << "... = " << pointData[size - 1].coord.x << "\t" << xEnd << "\t" << (pointData[size - 1].coord.x - xEnd) << endl;
- file.close();
- }
- void saveKomplett(const coordinate ¢er, const pointContainer* pointData, const int &size, const string &filename, int l, int n, int d, double x0, int its, double startwert, double xEnd)
- {
- ofstream file;
- file.open(filename);
- file << "---------------------------------------------------------" << endl;
- file << " Beispiel Nr." << l << endl;
- file << "---------------------------------------------------------" << endl;
- file << endl << endl;
- file << "Tabelle der Punkte gleichen Bogenabstands" << endl;
- switch (l)
- {
- case 1:
- file << " f(x) = ln(x); N = " << n << " ; x0 = " << x0 << " ; d = " << d << endl;
- file << " Integrand fuer Bogenlaenge: " << endl;
- file << "b(x) = sqrt(1+(f’(x))^2)" << endl;
- file << " = (1/x^2 + 1)^(1/2)" << endl;
- file << "Endpunkt = (xn,yn) = (" << pointData[size - 1].coord.x << "," << pointData[size - 1].coord.y << 2.0667 << ") ; Startwert = " << startwert << "; Its = " << its << endl;
- file << endl;
- file << "Mittelpunkt = (px,py) = (" << center.x << "," << center.y << ")" << endl;
- break;
- case 2:
- file << " f(x) = (x-2)^2; N = " << n << " ; x0 = " << x0 << " ; d = " << d << endl;
- file << " Integrand fuer Bogenlaenge: " << endl;
- file << "b(x) = sqrt(1+(f’(x))^2)" << endl;
- file << " = (((x - 2.) * (x - 2.))^2 + 1)^(1/2)" << endl;
- file << "Endpunkt = (xn,yn) = (" << pointData[size - 1].coord.x << "," << pointData[size - 1].coord.y << 2.0667 << ") ; Startwert = " << startwert << "; Its = " << its << endl;
- file << endl;
- file << "Mittelpunkt = (px,py) = (" << center.x << "," << center.y << ")" << endl;
- break;
- case 3:
- file << " f(x) = cosh(x); N = " << n << " ; x0 = " << x0 << " ; d = " << d << endl;
- file << " Integrand fuer Bogenlaenge: " << endl;
- file << "b(x) = sqrt(1+(f’(x))^2)" << endl;
- file << " = ((sinh(x))^2 + 1)^(1/2)" << endl;
- file << "Endpunkt = (xn,yn) = (" << pointData[size - 1].coord.x << "," << pointData[size - 1].coord.y << 2.0667 << ") ; Startwert = " << startwert << "; Its = " << its << endl;
- file << endl;
- file << "Mittelpunkt = (px,py) = (" << center.x << "," << center.y << ")" << endl;
- break;
- case 4:
- file << " f(x) = sqrt(x); N = " << n << " ; x0 = " << x0 << " ; d = " << d << endl;
- file << " Integrand fuer Bogenlaenge: " << endl;
- file << "b(x) = sqrt(1+(f’(x))^2)" << endl;
- file << " = ((1. / (2. * sqrt(x)))^2 + 1)^(1/2)" << endl;
- file << "Endpunkt = (xn,yn) = (" << pointData[size - 1].coord.x << "," << pointData[size - 1].coord.y << 2.0667 << ") ; Startwert = " << startwert << "; Its = " << its << endl;
- file << endl;
- file << "Mittelpunkt = (px,py) = (" << center.x << "," << center.y << ")" << endl;
- break;
- }
- file << '#' << "\t\t" << "Kartesische Koordinaten" << "\t\t\t\t\t\t\t\t\t\t\t\t" << "Polarkoordinaten" << endl;
- file << "#Nr." << '\t' << "x-Koord." << "\t\t" << "y-Koord." << "\t\t" << "x-Start_1" << "\t\t" << "x-Start_2" << "\t\t" <<
- "fcnt" << '\t' << "Its" << "\t" << "Winkel" << "\t\t\t" << "Radius" << endl;
- file << setprecision(14) << fixed;
- for (int i = 0; i < size; i++)
- {
- file << i << '\t' <<
- pointData[i].coord.x << '\t' <<
- pointData[i].coord.y << '\t' <<
- pointData[i].x_s1 << '\t' <<
- pointData[i].x_s2 << '\t' <<
- pointData[i].fcnt << '\t' <<
- pointData[i].its << '\t' <<
- pointData[i].angle << '\t' <<
- pointData[i].radius << '\t' << endl;
- }
- file << endl << endl;
- file << "Test: [xn,x(N),xn-x(N)] = " << endl;
- file << "... = " << pointData[size - 1].coord.x << "\t" << xEnd << "\t" << scientific << (pointData[size - 1].coord.x - xEnd) << endl;
- file.close();
- }
- void plotFile(const coordinate ¢er, const pointContainer* pointData, const int &n, const string &functionFile, const string &datafile, const string &filename)
- {
- ofstream file, data;
- file.open(filename);
- data.open(datafile);
- data << setprecision(14) << fixed;
- for (int i = 0; i < n; i++)
- {
- data <<
- pointData[i].coord.x << '\t' <<
- pointData[i].coord.y << endl <<
- center.x << '\t' << center.y << endl;
- }
- data.close();
- file << "reset" << endl << "set grid" << endl << "set samples 40000" << endl;
- file << "plot \"" << functionFile.c_str() << "\" using 2:3 smooth unique with linespoints notitle, \"" << datafile.c_str() << "\" using 1:2 with lines notitle";
- file.close();
- }
- int main()
- {
- funktionContainer fkt[4] = { { funktion1, funktion1_ableitung, funktion1_b }, { funktion2, funktion2_ableitung, funktion2_b }, { funktion3, funktion3_ableitung, funktion3_b }, { funktion4, funktion4_ableitung, funktion4_b } };
- int iteration = 0;
- int iterationNeu = 0;
- int l = 0, n = 0, d = 0, h;
- double x0 = 0.;
- string gnuFunkt = " ";
- cout << "Geben Sie die Nummer der Funktion ein(1-4): ";
- cin >> l;
- h = l;
- cout << "Geben Sie die Anzahl N ein: ";
- cin >> n;
- cout << "Geben Sie den Abstand d ein: ";
- cin >> d;
- cout << "Geben Sie den Punkt x0 ein: ";
- cin >> x0;
- l--; // array mit natürlichen zahlen gleichsetzen
- double xEnd = doEuklid(fkt[l], x0, d, iteration);
- int temp = 0;
- double Q = 0.;
- switch (Romberg_neu(fkt[l].bogenlaenge, x0, xEnd, 1e-14, 20, temp, temp, Q))
- {
- case 0:
- break;
- case 1:
- break;
- case 2:
- break;
- }
- coordinate center = { (x0 + xEnd) / 2, (fkt[l].funktion(x0) + fkt[l].funktion(xEnd)) / 2 }; //mittelpunkt berechnen feste funktion
- pointContainer* pointData = new pointContainer[n + 1];
- pointData[0].coord.x = x0;
- pointData[0].coord.y = fkt[l].funktion(pointData[0].coord.x);
- pointData[0].x_s1 = x0;
- pointData[0].x_s2 = x0;
- pointData[0].fcnt = 0;
- pointData[0].its = 0;
- pointData[0].angle = 0.;
- pointData[0].radius = d / 2.;
- double xn = x0;
- double xk1 = xn;
- double dn = Q / n;
- double delta = 0.;
- double startwert = x0 + d;
- for (int k = 1; k <= n; k++)
- {
- int L_out = 0, fcnt = 0;
- xk1 = xn;
- const double x_s1 = doTangente(fkt[l], xn, dn);
- const double x_s2 = doSekante(fkt[l], xn, x_s1, dn);
- xn = x_s2;
- delta = 0.;
- pointData[k].fcnt = 0;
- int its = 0;
- do
- {
- L_out = 0;
- switch (Romberg_neu(fkt[l].bogenlaenge, xk1, xn, 1e-14, 20, L_out, fcnt, Q))
- {
- case 0:
- delta = (Q - dn) / (fkt[l].bogenlaenge(xn));
- xn = xn - delta;
- break;
- case 1:
- cout << "Romberg Error: 1" << endl;
- break;
- case 2:
- cout << "Romberg Error: 2" << endl;
- break;
- }
- pointData[k].fcnt += fcnt;
- its++;
- } while (abs(Q - dn) > 1e-10);
- pointData[k].coord.x = xn;
- pointData[k].coord.y = fkt[l].funktion(pointData[k].coord.x);
- pointData[k].x_s1 = x_s1;
- pointData[k].x_s2 = x_s2;
- pointData[k].its = its;
- pointData[k].angle = getAngle(center, pointData[k].coord, pointData[0].coord);
- pointData[k].radius = getRadius(center, pointData[k].coord);
- }
- save(pointData, n + 1, "Funktion.txt",xEnd);
- saveKomplett(center, pointData, n + 1, "Muster.txt", h, n, d, x0, iteration, startwert, xEnd);
- saveKomplett(center, pointData, n + 1, "Funktionen.txt", h, n, d, x0, iteration, startwert, xEnd);
- plotFile(center, pointData, n + 1, "Funktion.txt", "data.txt", "plot.txt");
- cout << endl;
- double Euklidd[20];
- fstream dataNeu;
- dataNeu.open("dataNeu2.txt", ios::out);
- for (int i = 0; i < n; i++)
- {
- Euklidd[i] = sqrt((pointData[i + 1].coord.x - pointData[i].coord.x)*(pointData[i + 1].coord.x - pointData[i].coord.x) + (pointData[i + 1].coord.y - pointData[i].coord.y)*(pointData[i + 1].coord.y - pointData[i].coord.y));
- dataNeu << i << "\t" << setprecision(15) << scientific << Euklidd[i] << endl;
- }
- system("PAUSE");
- return 0;
- }
- /*// test
- fstream gnuPlot;
- gnuPlot.open("Gnuplot.plt", ios::out);
- switch (l + 1)
- {
- case 1:
- gnuPlot << "plot log(x),";
- break;
- case 2:
- gnuPlot << "plot (x-2)*(x-2),";
- break;
- case 3:
- gnuPlot << "plot cosh(x),";
- break;
- case 4:
- gnuPlot << "plot sqrt(x),";
- break;
- }
- gnuPlot << "\"data.txt\" using 1:2 with lines " << endl;
- gnuPlot << "pause -1" << endl;
- fstream dataNeu;
- dataNeu.open("dataNeu.txt", ios::out);
- double *EuklidAbstand = new double[n];
- double gesamtlaenge = 0;
- double eMax_x = 0;
- double eMax_x1 = 0;
- double eMin_x = 0;
- double eMin_x1 = 0;
- for (int i = 0; i < n; i++)
- {
- EuklidAbstand[i] = sqrt((pointData[i + 1].coord.x - pointData[i].coord.x)*(pointData[i + 1].coord.x - pointData[i].coord.x) + (pointData[i + 1].coord.y - pointData[i].coord.y)*(pointData[i + 1].coord.y - pointData[i].coord.y));
- gesamtlaenge += EuklidAbstand[i];
- dataNeu << i << "\t" << EuklidAbstand[i] << endl;
- }
- double eMax = EuklidAbstand[0];
- double eMin = EuklidAbstand[0];
- for (int i = 1; i < n; i++)
- {
- if (eMax < EuklidAbstand[i])
- {
- eMax = EuklidAbstand[i];
- eMax_x = i;
- eMax_x1 = i + 1;
- }
- if (eMin > EuklidAbstand[i])
- {
- eMin = EuklidAbstand[i];
- eMin_x = i;
- eMin_x1 = i + 1;
- }
- }
- cout << endl << "Gesamtlaenge: " << gesamtlaenge << endl << "eMax[ " << eMax_x << ", " << eMax_x1 << " ] : " << eMax << endl << "eMin[ " << eMin_x << ", " << eMin_x1 << " ] : " << eMin << endl;
- fstream gnuPlotNeu;
- gnuPlotNeu.open("GnuplotNeu.plt", ios::out);
- gnuPlotNeu << "\"dataNeu.txt\" using 1:2 with lines " << endl;
- gnuPlotNeu << "pause -1" << endl;
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement