Advertisement
Guest User

Untitled

a guest
Jun 2nd, 2015
253
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.43 KB | None | 0 0
  1. #include <iostream>
  2. #include <cmath>
  3. #include <iomanip>
  4. #include <fstream>
  5. using namespace std;
  6. int Romberg_neu(double(*f)(double), double a, double b, double tol, int L_in, int &L_out, int &fcnt, double &Q){
  7.     /* Näherungsweise Berechnung des Integrals über f von a bis b: I(f;a,b)
  8.     % mit dem Romberg-Schema mit max. L_in Stufen.
  9.     %
  10.     % Eingabe:
  11.     % f    : Funktion der Form f(x); Integrand
  12.     % a    : reelle Zahl; untere Integrationsgrenze
  13.     % b    : reelle Zahl; obere Integrationsgrenze
  14.     % tol  : reelle Zahl; Genauigkeitstoleranz: |I(f;a,b)-Q|<=tol*(1+|Q|)
  15.     % L_in : Integer; max. Anzahl Stufen im Romberg-Schema
  16.     % Ausgabe:
  17.     % rc    : Integer; rc=0; Q wurde in gewünschter Genauigkeit berechnet.
  18.     %                  rc=1; Q ist nicht genau genug. Es würden evtl. mehr Stufen (als L_in) benötigt.
  19.     %                  rc=2; Eingabefehler: tol <=0
  20.     %
  21.     % L_out : Integer; Anzahl genutzter Stufen
  22.     % fcnt    : Integer; Anzahl Funktionsauswertungen des Integranden
  23.     % Q       : relle Zahl; Näherungswert für das Integral I(f;a,b)
  24.     %
  25.     %------- R. Reuter ----- 24.03.2013 --------------------------------------*/
  26.     double Q1 = 0., E = 0., h = 0., ah = 0.;
  27.     int n = 10; // Anzahl initialer Teilintervalle für ST-Formel
  28.     int rc = 1; // Return Code
  29.     double Fak = 1.0;
  30.     int Lmax = L_in; // max. Anzahl Stufen
  31.     int L = 0;
  32.     double *QQ = new double[Lmax + 1]; // Array zum Speichern der jeweils aktuellen Zeile
  33.     // des Romberg-Schemas
  34.     fcnt = 0;
  35.     if (tol <= 0.){
  36.         rc = 2;
  37.         return rc;
  38.     }
  39.  
  40.     h = (b - a) / n;
  41.     Q1 = 0.5 * (f(a) + f(b));
  42.     fcnt = fcnt + 2;
  43.     for (int k = 1; k<n; k++)
  44.         Q1 = Q1 + f(a + k*h);
  45.     fcnt = fcnt + n - 1;
  46.     Q1 = h*Q1; // ST-Formel zu h
  47.     QQ[1] = Q1;
  48.  
  49.     for (L = 2; L <= Lmax; L++){
  50.         Q = 0.0;
  51.         ah = a + 0.5*h;
  52.  
  53.         for (int k = 0; k<n; k++)
  54.             Q = Q + f(ah + k*h);
  55.         fcnt = fcnt + n;
  56.         Q = 0.5*(QQ[1] + h*Q); // ST-Formel zu h/2
  57.         Fak = 1.0;
  58.  
  59.         for (int LL = 1; LL<L; LL++){
  60.             Fak = Fak*4.;
  61.             Q1 = QQ[LL];
  62.             QQ[LL] = Q;
  63.             E = (Q - Q1) / (Fak - 1.0);
  64.  
  65.             Q = Q + E;
  66.         }
  67.  
  68.         QQ[L] = Q;
  69.  
  70.         if (fabs(E) <= tol*(1 + fabs(Q))){
  71.             rc = 0;
  72.             break;
  73.         }
  74.  
  75.         h = 0.5*h;
  76.         n = 2 * n;
  77.     }
  78.     L_out = L;
  79.     return rc;
  80. }
  81.  
  82. struct funktionContainer
  83. {
  84.     double(*funktion)(double);
  85.     double(*ableitung)(double);
  86.     double(*bogenlaenge)(double);
  87. };
  88.  
  89. struct coordinate
  90. {
  91.     double x;
  92.     double y;
  93. };
  94.  
  95. struct pointContainer
  96. {
  97.     coordinate coord;
  98.     double x_s1;
  99.     double x_s2;
  100.     int fcnt;
  101.     int its;
  102.     double angle;
  103.     double radius;
  104. };
  105.  
  106. double funktion1(double x)
  107. {
  108.     return log(x);
  109. }
  110.  
  111. double funktion1_ableitung(double x)
  112. {
  113.     return 1. / x;
  114. }
  115.  
  116. double funktion1_b(double x)
  117. {
  118.     return sqrt(1. + (funktion1_ableitung(x) * funktion1_ableitung(x)));
  119. }
  120.  
  121. double funktion2(double x)
  122. {
  123.     return (x - 2.) * (x - 2.);
  124. }
  125.  
  126. double funktion2_ableitung(double x)
  127. {
  128.     return 2. * (x - 2.);
  129. }
  130.  
  131. double funktion2_b(double x)
  132. {
  133.     return sqrt(1. + (funktion2_ableitung(x) * funktion2_ableitung(x)));
  134. }
  135.  
  136. double funktion3(double x)
  137. {
  138.     return cosh(x);
  139. }
  140.  
  141. double funktion3_ableitung(double x)
  142. {
  143.     return sinh(x);
  144. }
  145.  
  146. double funktion3_b(double x)
  147. {
  148.     return sqrt(1. + (funktion3_ableitung(x) * funktion3_ableitung(x)));
  149. }
  150.  
  151. double funktion4(double x)
  152. {
  153.     return sqrt(x);
  154. }
  155.  
  156. double funktion4_ableitung(double x)
  157. {
  158.     return 1. / (2. * sqrt(x));
  159. }
  160.  
  161. double funktion4_b(double x)
  162. {
  163.     return sqrt(1. + (funktion4_ableitung(x) * funktion4_ableitung(x)));
  164. }
  165.  
  166.  
  167. double doEuklid(funktionContainer fkt, double x_s0, double d, int & iteration) //aufgabe B: bestimme euklidischen abstand
  168. {
  169.     double differenz = 0.;
  170.     double x_s1 = x_s0 + d;
  171.     do
  172.     {
  173.         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)
  174.             / (2 * (x_s1 - x_s0) + 2 * (fkt.funktion(x_s1) - fkt.funktion(x_s0)) * fkt.ableitung(x_s1));
  175.         x_s1 -= differenz;
  176.         iteration++;
  177.  
  178.     } while (abs(differenz) > 1e-10);
  179.  
  180.     return x_s1;
  181. }
  182.  
  183. const double doTangente(const funktionContainer &fkt, const double &x_s0, const double &d) // Aufgabe C: gebraucht für bogenlänge
  184. {
  185.     const double abl = fkt.ableitung(x_s0);
  186.     return x_s0 + d / sqrt(abl * abl + 1.);
  187. }
  188.  
  189. const double doSekante(const funktionContainer &fkt, const double &x_s0, const double &x_s1, const double &d)// Aufgabe C: gebraucht für bogenlänge
  190. {
  191.     const double m = (fkt.funktion(x_s1) - fkt.funktion(x_s0)) / (x_s1 - x_s0);
  192.     return x_s0 + d / (sqrt(m*m + 1.));
  193. }
  194.  
  195. const double radToDeg(const double &rad) //feste formel
  196. {
  197.     return rad * 180. / (4. * atan(1.));
  198. }
  199.  
  200. const coordinate getDiffvector(const coordinate &a, const coordinate &b) //winkelfunktion
  201. {
  202.     return coordinate{ b.x - a.x, b.y - a.y };
  203. }
  204.  
  205. const double getRadius(const coordinate &vector) // winkelfunktion
  206. {
  207.     return sqrt(vector.x * vector.x + vector.y * vector.y);
  208. }
  209.  
  210. const double getRadius(const coordinate &a, const coordinate &b) // aufgabe F
  211. {
  212.     return getRadius(getDiffvector(a, b));
  213. }
  214.  
  215. const double getScalarproduct(const coordinate &a, const coordinate &b)
  216. {
  217.     return a.x * b.x + a.y * b.y;
  218. }
  219.  
  220. const double getAngle(const coordinate &center, const coordinate &currentPoint, const coordinate &referencePoint)
  221. {
  222.     const coordinate a = getDiffvector(center, currentPoint);
  223.     const coordinate b = getDiffvector(center, referencePoint);
  224.  
  225.     return radToDeg(acos(getScalarproduct(a, b) / (getRadius(a) * getRadius(b))));
  226. }
  227.  
  228. void save(const pointContainer* pointData, const int &size, const string &filename,double xEnd)
  229. {
  230.     ofstream file;
  231.     file.open(filename);
  232.  
  233.     file << '#' << "\t\t" << "Kartesische Koordinaten" << "\t\t\t\t\t\t\t\t\t\t\t\t" << "Polarkoordinaten" << endl;
  234.     file << "#Nr." << '\t' << "x-Koord." << "\t\t" << "y-Koord." << "\t\t" << "x-Start_1" << "\t\t" << "x-Start_2" << "\t\t" <<
  235.         "fcnt" << '\t' << "Its" << "\t" << "Winkel" << "\t\t\t" << "Radius" << endl;
  236.     file << setprecision(14) << fixed;
  237.  
  238.     for (int i = 0; i < size; i++)
  239.     {
  240.         file << i << '\t' <<
  241.             pointData[i].coord.x << '\t' <<
  242.             pointData[i].coord.y << '\t' <<
  243.             pointData[i].x_s1 << '\t' <<
  244.             pointData[i].x_s2 << '\t' <<
  245.             pointData[i].fcnt << '\t' <<
  246.             pointData[i].its << '\t' <<
  247.             pointData[i].angle << '\t' <<
  248.             pointData[i].radius << '\t' << endl;
  249.     }
  250.     file << endl << endl;
  251.     file << "Test: [xn,x(N),xn-x(N)] = " << endl;
  252.     file << "... = " << pointData[size - 1].coord.x << "\t" << xEnd << "\t" << (pointData[size - 1].coord.x - xEnd) << endl;
  253.  
  254.     file.close();
  255. }
  256. void saveKomplett(const coordinate &center, const pointContainer* pointData, const int &size, const string &filename, int l, int n, int d, double x0, int its, double startwert, double xEnd)
  257. {
  258.     ofstream file;
  259.     file.open(filename);
  260.  
  261.     file << "---------------------------------------------------------" << endl;
  262.     file << " Beispiel Nr." << l << endl;
  263.     file << "---------------------------------------------------------" << endl;
  264.     file << endl << endl;
  265.     file << "Tabelle der Punkte gleichen Bogenabstands" << endl;
  266.     switch (l)
  267.     {
  268.     case 1:
  269.         file << " f(x) = ln(x); N = " << n << " ; x0 = " << x0 << " ; d = " << d << endl;
  270.         file << " Integrand fuer Bogenlaenge: " << endl;
  271.         file << "b(x) = sqrt(1+(f’(x))^2)" << endl;
  272.         file << "     = (1/x^2 + 1)^(1/2)" << endl;
  273.         file << "Endpunkt = (xn,yn) = (" << pointData[size - 1].coord.x << "," << pointData[size - 1].coord.y << 2.0667 << ") ; Startwert = " << startwert << "; Its = " << its << endl;
  274.         file << endl;
  275.         file << "Mittelpunkt = (px,py) = (" << center.x << "," << center.y << ")" << endl;
  276.         break;
  277.     case 2:
  278.         file << " f(x) = (x-2)^2; N = " << n << " ; x0 = " << x0 << " ; d = " << d << endl;
  279.         file << " Integrand fuer Bogenlaenge: " << endl;
  280.         file << "b(x) = sqrt(1+(f’(x))^2)" << endl;
  281.         file << "     = (((x - 2.) * (x - 2.))^2 + 1)^(1/2)" << endl;
  282.         file << "Endpunkt = (xn,yn) = (" << pointData[size - 1].coord.x << "," << pointData[size - 1].coord.y << 2.0667 << ") ; Startwert = " << startwert << "; Its = " << its << endl;
  283.         file << endl;
  284.         file << "Mittelpunkt = (px,py) = (" << center.x << "," << center.y << ")" << endl;
  285.         break;
  286.     case 3:
  287.         file << " f(x) = cosh(x); N = " << n << " ; x0 = " << x0 << " ; d = " << d << endl;
  288.         file << " Integrand fuer Bogenlaenge: " << endl;
  289.         file << "b(x) = sqrt(1+(f’(x))^2)" << endl;
  290.         file << "     = ((sinh(x))^2 + 1)^(1/2)" << endl;
  291.         file << "Endpunkt = (xn,yn) = (" << pointData[size - 1].coord.x << "," << pointData[size - 1].coord.y << 2.0667 << ") ; Startwert = " << startwert << "; Its = " << its << endl;
  292.         file << endl;
  293.         file << "Mittelpunkt = (px,py) = (" << center.x << "," << center.y << ")" << endl;
  294.         break;
  295.     case 4:
  296.         file << " f(x) = sqrt(x); N = " << n << " ; x0 = " << x0 << " ; d = " << d << endl;
  297.         file << " Integrand fuer Bogenlaenge: " << endl;
  298.         file << "b(x) = sqrt(1+(f’(x))^2)" << endl;
  299.         file << "     = ((1. / (2. * sqrt(x)))^2 + 1)^(1/2)" << endl;
  300.         file << "Endpunkt = (xn,yn) = (" << pointData[size - 1].coord.x << "," << pointData[size - 1].coord.y << 2.0667 << ") ; Startwert = " << startwert << "; Its = " << its << endl;
  301.         file << endl;
  302.         file << "Mittelpunkt = (px,py) = (" << center.x << "," << center.y << ")" << endl;
  303.         break;
  304.     }
  305.  
  306.     file << '#' << "\t\t" << "Kartesische Koordinaten" << "\t\t\t\t\t\t\t\t\t\t\t\t" << "Polarkoordinaten" << endl;
  307.     file << "#Nr." << '\t' << "x-Koord." << "\t\t" << "y-Koord." << "\t\t" << "x-Start_1" << "\t\t" << "x-Start_2" << "\t\t" <<
  308.         "fcnt" << '\t' << "Its" << "\t" << "Winkel" << "\t\t\t" << "Radius" << endl;
  309.     file << setprecision(14) << fixed;
  310.  
  311.     for (int i = 0; i < size; i++)
  312.     {
  313.         file << i << '\t' <<
  314.             pointData[i].coord.x << '\t' <<
  315.             pointData[i].coord.y << '\t' <<
  316.             pointData[i].x_s1 << '\t' <<
  317.             pointData[i].x_s2 << '\t' <<
  318.             pointData[i].fcnt << '\t' <<
  319.             pointData[i].its << '\t' <<
  320.             pointData[i].angle << '\t' <<
  321.             pointData[i].radius << '\t' << endl;
  322.     }
  323.  
  324.     file << endl << endl;
  325.     file << "Test: [xn,x(N),xn-x(N)] = " << endl;
  326.     file << "... = " << pointData[size - 1].coord.x << "\t" << xEnd << "\t" << scientific <<  (pointData[size - 1].coord.x - xEnd) << endl;
  327.  
  328.     file.close();
  329. }
  330.  
  331. void plotFile(const coordinate &center, const pointContainer* pointData, const int &n, const string &functionFile, const string &datafile, const string &filename)
  332. {
  333.     ofstream file, data;
  334.     file.open(filename);
  335.     data.open(datafile);
  336.  
  337.     data << setprecision(14) << fixed;
  338.     for (int i = 0; i < n; i++)
  339.     {
  340.         data <<
  341.             pointData[i].coord.x << '\t' <<
  342.             pointData[i].coord.y << endl <<
  343.             center.x << '\t' << center.y << endl;
  344.     }
  345.  
  346.     data.close();
  347.  
  348.     file << "reset" << endl << "set grid" << endl << "set samples 40000" << endl;
  349.     file << "plot \"" << functionFile.c_str() << "\" using 2:3 smooth unique with linespoints notitle, \"" << datafile.c_str() << "\" using 1:2 with lines notitle";
  350.  
  351.     file.close();
  352. }
  353.  
  354. int main()
  355. {
  356.    
  357.     funktionContainer fkt[4] = { { funktion1, funktion1_ableitung, funktion1_b }, { funktion2, funktion2_ableitung, funktion2_b }, { funktion3, funktion3_ableitung, funktion3_b }, { funktion4, funktion4_ableitung, funktion4_b } };
  358.     int iteration = 0;
  359.     int iterationNeu = 0;
  360.     int l = 0, n = 0, d = 0, h;
  361.     double x0 = 0.;
  362.     string gnuFunkt = " ";
  363.  
  364.  
  365.     cout << "Geben Sie die Nummer der Funktion ein(1-4): ";
  366.     cin >> l;
  367.     h = l;
  368.     cout << "Geben Sie die Anzahl N ein: ";
  369.     cin >> n;
  370.     cout << "Geben Sie den Abstand d ein: ";
  371.     cin >> d;
  372.     cout << "Geben Sie den Punkt x0 ein: ";
  373.     cin >> x0;
  374.  
  375.     l--; // array mit natürlichen zahlen gleichsetzen
  376.     double xEnd = doEuklid(fkt[l], x0, d, iteration);
  377.  
  378.     int temp = 0;
  379.     double Q = 0.;
  380.  
  381.     switch (Romberg_neu(fkt[l].bogenlaenge, x0, xEnd, 1e-14, 20, temp, temp, Q))
  382.     {
  383.     case 0:
  384.         break;
  385.     case 1:
  386.         break;
  387.     case 2:
  388.         break;
  389.     }
  390.  
  391.     coordinate center = { (x0 + xEnd) / 2, (fkt[l].funktion(x0) + fkt[l].funktion(xEnd)) / 2 }; //mittelpunkt berechnen feste funktion
  392.     pointContainer* pointData = new pointContainer[n + 1];
  393.  
  394.     pointData[0].coord.x = x0;
  395.     pointData[0].coord.y = fkt[l].funktion(pointData[0].coord.x);
  396.     pointData[0].x_s1 = x0;
  397.     pointData[0].x_s2 = x0;
  398.     pointData[0].fcnt = 0;
  399.     pointData[0].its = 0;
  400.     pointData[0].angle = 0.;
  401.     pointData[0].radius = d / 2.;
  402.  
  403.     double xn = x0;
  404.     double xk1 = xn;
  405.     double dn = Q / n;
  406.     double delta = 0.;
  407.     double startwert = x0 + d;
  408.  
  409.     for (int k = 1; k <= n; k++)
  410.     {
  411.         int L_out = 0, fcnt = 0;
  412.         xk1 = xn;
  413.         const double x_s1 = doTangente(fkt[l], xn, dn);
  414.         const double x_s2 = doSekante(fkt[l], xn, x_s1, dn);
  415.         xn = x_s2;
  416.         delta = 0.;
  417.         pointData[k].fcnt = 0;
  418.         int its = 0;
  419.         do
  420.         {
  421.             L_out = 0;
  422.             switch (Romberg_neu(fkt[l].bogenlaenge, xk1, xn, 1e-14, 20, L_out, fcnt, Q))
  423.             {
  424.             case 0:
  425.                 delta = (Q - dn) / (fkt[l].bogenlaenge(xn));
  426.                 xn = xn - delta;
  427.                 break;
  428.             case 1:
  429.                 cout << "Romberg Error: 1" << endl;
  430.                 break;
  431.             case 2:
  432.                 cout << "Romberg Error: 2" << endl;
  433.                 break;
  434.             }
  435.             pointData[k].fcnt += fcnt;
  436.             its++;
  437.  
  438.         } while (abs(Q - dn) > 1e-10);
  439.  
  440.         pointData[k].coord.x = xn;
  441.         pointData[k].coord.y = fkt[l].funktion(pointData[k].coord.x);
  442.         pointData[k].x_s1 = x_s1;
  443.         pointData[k].x_s2 = x_s2;
  444.  
  445.         pointData[k].its = its;
  446.         pointData[k].angle = getAngle(center, pointData[k].coord, pointData[0].coord);
  447.         pointData[k].radius = getRadius(center, pointData[k].coord);
  448.     }
  449.  
  450.     save(pointData, n + 1, "Funktion.txt",xEnd);
  451.     saveKomplett(center, pointData, n + 1, "Muster.txt", h, n, d, x0, iteration, startwert, xEnd);
  452.     saveKomplett(center, pointData, n + 1, "Funktionen.txt", h, n, d, x0, iteration, startwert, xEnd);
  453.     plotFile(center, pointData, n + 1, "Funktion.txt", "data.txt", "plot.txt");
  454.    
  455.    
  456.  
  457.     cout << endl;
  458.  
  459.  
  460.  
  461.     double Euklidd[20];
  462.  
  463.     fstream dataNeu;
  464.     dataNeu.open("dataNeu2.txt", ios::out);
  465.  
  466.     for (int i = 0; i < n; i++)
  467.     {
  468.         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));
  469.         dataNeu << i << "\t" << setprecision(15) << scientific << Euklidd[i] << endl;
  470.     }
  471.     system("PAUSE");
  472.     return 0;
  473.  
  474. }
  475.  
  476.  
  477.  
  478.  
  479.  
  480.  
  481.  
  482.  
  483.  
  484.  
  485.  
  486.  
  487.  
  488.  
  489.  
  490.  
  491.  
  492. /*// test
  493. fstream gnuPlot;
  494. gnuPlot.open("Gnuplot.plt", ios::out);
  495.  
  496. switch (l + 1)
  497. {
  498. case 1:
  499. gnuPlot << "plot log(x),";
  500. break;
  501. case 2:
  502. gnuPlot << "plot (x-2)*(x-2),";
  503. break;
  504. case 3:
  505. gnuPlot << "plot cosh(x),";
  506. break;
  507. case 4:
  508. gnuPlot << "plot sqrt(x),";
  509. break;
  510. }
  511.  
  512. gnuPlot << "\"data.txt\" using 1:2 with lines " << endl;
  513. gnuPlot << "pause -1" << endl;
  514.  
  515. fstream dataNeu;
  516. dataNeu.open("dataNeu.txt", ios::out);
  517. double *EuklidAbstand = new double[n];
  518. double gesamtlaenge = 0;
  519. double eMax_x = 0;
  520. double eMax_x1 = 0;
  521. double eMin_x = 0;
  522. double eMin_x1 = 0;
  523.  
  524. for (int i = 0; i < n; i++)
  525. {
  526. 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));
  527. gesamtlaenge += EuklidAbstand[i];
  528. dataNeu << i << "\t" << EuklidAbstand[i] << endl;
  529. }
  530. double eMax = EuklidAbstand[0];
  531. double eMin = EuklidAbstand[0];
  532.  
  533. for (int i = 1; i < n; i++)
  534. {
  535. if (eMax < EuklidAbstand[i])
  536. {
  537. eMax = EuklidAbstand[i];
  538. eMax_x = i;
  539. eMax_x1 = i + 1;
  540. }
  541.  
  542. if (eMin > EuklidAbstand[i])
  543. {
  544. eMin = EuklidAbstand[i];
  545. eMin_x = i;
  546. eMin_x1 = i + 1;
  547. }
  548.  
  549. }
  550. cout << endl << "Gesamtlaenge: " << gesamtlaenge << endl << "eMax[ " << eMax_x << ", " << eMax_x1 << " ] : " << eMax << endl << "eMin[ " << eMin_x << ", " << eMin_x1 << " ] : " << eMin << endl;
  551.  
  552. fstream gnuPlotNeu;
  553. gnuPlotNeu.open("GnuplotNeu.plt", ios::out);
  554. gnuPlotNeu << "\"dataNeu.txt\" using 1:2 with lines " << endl;
  555. gnuPlotNeu << "pause -1" << endl;
  556.  
  557.  
  558. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement