x039.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "xquad.h"
4 #include "xdata.h"
5 #include "xmath.h"
6 #include "xoutput.h"
7 #include "xphysics.h"
8 #include "xtools.h"
9 #include <gsl/gsl_integration.h>
10 #include <iostream>
11 #include <math.h>
12 #include <stdio.h>
13 
14 namespace nmx::apps::x039 {
15 
22 double f(double x, void *params) {
23  double alpha = *(double *) params;
24  double f = log(alpha * x) / sqrt(x);
25  return f;
26 }
27 
32 void gslex() {
33  //gsl Struktur: Verwaltung von Daten
34  gsl_integration_workspace *w = gsl_integration_workspace_alloc(1000);
35 
36  //exaktes Ergebnis
37  double expected = -4.0;
38  //Parameter des Integranden
39  double alpha = 1.0;
40  //Ausgabewerte der Integrationsroutine
41  double result, error;
42  //gsl-Funktion(übergibt Integranden an die Integrationsroutine)
43  gsl_function F;
44  F.function = &f;
45  F.params = &alpha;
46  //numerische Integration, Integrand hat Singularität
47  gsl_integration_qags(&F, 0, 1, 0, 1e-7, 1000, w, &result, &error);
48  //Ausgabe der Daten
49  printf("result = % .18f\n", result);
50  printf("exact result = % .18f\n", expected);
51  printf("estimated error = % .18f\n", error);
52  printf("actual error = % .18f\n", result - expected);
53  printf("intervals = %zu\n", w->size);
54 
55  //Freigabe des workspaces
56  gsl_integration_workspace_free(w);
57 }
58 
64 static inline auto get_output_stream(const char *name, Format fmt) {
65  auto ofs = Output::get_stream("x039", fmt, name);
66  return ofs;
67 }
68 
72 inline void ex0() {
73  //Integrand
74  auto fn = [](double x) { return 4.0 / (1 + pow(x, 2)); };
75  //gsl-Klasse
76  gsl::Integral integral(fn);
77  //nicht adaptive Integration von fn im Intervall [0,1]
78  integral.qng(0, 1);
79  //Ausgabe von Ergebnissen
80  const double expected = Math::PI;
81  std::ofstream sout = get_output_stream(__func__, Output::terminal);
82  integral.show_results(sout, expected);
83 }
84 
88 inline void ex1() {
89  //Integrand
90  auto fn = [](double x) { return log(x) / sqrt(x); };
91  //gsl-Klasse
92  gsl::Integral integral(fn);
93  //adaptive Integration von fn (mit Singularitäten)
94  //im Intervall [0,1]
95  integral.qags(0, 1);
96  //Ausgabe
97  const double expected = -4;
98  std::ofstream sout = get_output_stream(__func__, Output::terminal);
99  integral.show_results(sout, expected);
100 }
101 
105 inline void ex2() {
106  //Integrand
107  auto fn = [](double x) { return exp(-.5 * pow(x, 2)); };
108  //gsl-Klasse
109  gsl::Integral integral(fn);
110  //adaptive Integration von fn von -Unendlich bis +Unendlich
111  integral.qagi();
112  //Ausgabe
113  const double expected = 2.5066282746310002;
114  std::ofstream sout = get_output_stream(__func__, Output::terminal);
115  integral.show_results(sout, expected);
116 }
117 
121 inline void ex3() {
122  //Integrand
123  auto fn = [](double x) { return exp(-.5 * pow(x, 2)); };
124  //gsl-Klasse
125  gsl::Integral integral(fn);
126  //adaptive Integration von fn von 0 bis +Unendlich
127  integral.qagiu(0);
128  //Ausgabe
129  const double expected = 1.2533141373155001;
130  std::ofstream sout = get_output_stream(__func__, Output::terminal);
131  integral.show_results(sout, expected);
132 }
133 
137 inline void ex4() {
138  //Integrand
139  auto fn = [](double x) { return exp(-.5 * pow(x, 2)); };
140  //gsl-Klasse
141  gsl::Integral integral(fn);
142  //adaptive Integration von fn von -Unendlich bis 0
143  integral.qagil(0);
144  //Ausgabe
145  const double expected = 1.2533141373155001;
146  std::ofstream sout = get_output_stream(__func__, Output::terminal);
147  integral.show_results(sout, expected);
148 }
149 
153 inline void ex5() {
154  //Integrand
155  auto fn = [](double x) { return exp(-.5 * pow(x, 2)); };
156 
157  //gsl-Klasse
158  gsl::CQUADIntegral integral(fn);
159  integral.apply(2, 5);
160 
161  //Ausgabe
162  const double expected = 5.7025405463957006e-2;
163  std::ofstream sout = get_output_stream(__func__, Output::terminal);
164  integral.show_results(sout, expected);
165 }
166 
170 inline void ex6() {
171  using Data = Data<5>;
172  //Masse
173  const auto mass = 10.0;
174  //...kommt nach einer Strecke zum Stillstand
175  const auto s = 50.0;
176  const auto g = gravitation::Earth::g;
177  //Datenobjekt zur Speicherung der berechneten Daten
178  Data data;
179  //Schleife über Werte des Reibungskoeffizienten
180  for (auto mu : { 0.1, 0.4, 0.8 }) {
181  auto fn = [mu, mass](double x) {
182  (void) x;
183  return -mu * mass * gravitation::Earth::g;
184  };
185  // berechne das Integral
186  gsl::Integral integral(fn);
187  integral.qng(0.0, s);
188  const auto v0Exact = sqrt(2 * mu * g * s);
189  const auto v0Approx = sqrt(-2.0 / mass * integral.result());
190  data += { mass, s, mu, v0Approx, v0Exact };
191  }
192  //Ausgabe der Daten
193  std::ofstream ofs = get_output_stream(__func__, Output::latex);
194  data.save(ofs, Output::latex);
195 }
196 
201 inline void ex7() {
202  std::ofstream sout = get_output_stream(__func__, Output::terminal);
203  const double l = 1.0;
204  const double density = 7.7 / 1e-3;
205 
206  //Zähler und Nenner
207  auto fnnum = [density](double x) { return x * density; };
208  auto fnden = [density](double x) {
209  (void) x; //avoid warning
210  return density;
211  };
212 
213  //integriere Zähler und Nenner von 0 bis l
214  gsl::Integral integralnum(fnnum), integralden(fnden);
215  integralnum.qng(0, l);
216  integralden.qng(0, l);
217 
218  //berechne Ortsvektor und Masse
219  const double xcm = integralnum.result() / integralden.result();
220  const double m = density * l;
221 
222  //Ausgabe
223  sout << "mass =" << m << std::endl;
224  sout << "xcm=" << xcm << std::endl;
225  sout << "xcm=" << 0.5 * l << " (exact)" << std::endl;
226 }
227 
231 inline void ex8() {
232  std::ofstream sout = get_output_stream(__func__, Output::terminal);
233 
234  //Daten des Halbkreisrings
235  const double l = 1;
236  const double density = 7.7 / pow(0.1, 3);
237  const double radius = l / Math::PI;
238 
239  //Zähler der x-Koordinate
240  auto fnnumx = [density, radius](double phi) {
241  return cos(phi) * density * pow(radius, 2); //
242  };
243 
244  //Zähler der y-Koordinate
245  auto fnnumy = [density, radius](double phi) {
246  return sin(phi) * density * pow(radius, 2); //
247  };
248 
249  // der Nenner
250  auto fnden = [density, radius](double x) {
251  (void) x; //avoid warning
252  return density * radius;
253  };
254 
255  //Berechne die Integrale
256  gsl::Integral integralnumx(fnnumx), integralden(fnden), integralnumy(fnnumy);
257  //benötigt epsabs um einen Wert auszugeben.
258  integralnumx.qag(0.0, Math::PI, 6, 1e-9);
259  integralnumy.qag(0, Math::PI, 6);
260  integralden.qag(0, Math::PI, 6);
261 
262  //x- und y-Koordinate des Schwerpunktes und Masse
263  const double xcm = integralnumx.result() / integralden.result();
264  const double ycm = integralnumy.result() / integralden.result();
265  const double w = density * l;
266 
267  //Ausgabe in Datei
268  sout << "w =" << w << std::endl;
269  sout << "xcm=" << xcm << std::endl;
270  sout << "ycm=" << ycm << std::endl;
271  sout << "xcm=" << 0 << " (exact)" << std::endl;
272  sout << "ycm=" << 2 * radius / Math::PI << " (exact)" << std::endl;
273 }
274 
279 inline void ex9() {
280  using Data = nmx::Data<4>;
281  const double mass = 1e3;
282 
283  //Funktion über die integriert werden soll
284  auto workFn = [](double u) { return 1 / pow(u, 2); };
285 
286  //Berechnung des exakten Wertes für das Potential
287  auto exactFn = [](double z) { return 1 / z; };
288 
289  //Datenobjekt und Ausgabestrom
290  Data data;
291  std::ofstream ofs = get_output_stream(__func__, Output::latex);
292 
293  //Berechne exakten Wert für die potenzielle Energie
294  // und das Arbeitsintegral in Einheiten von GM/R
295  for (auto u : { 1e1, 1e2, 1e3, 1e4 }) {
296  gsl::Integral integral(workFn);
297  integral.qagiu(u, 1e-8);
298  const auto approxValue = -mass * integral.result();
299  const auto exactValue = -mass * exactFn(u);
300  const auto error = abs(exactValue - approxValue);
301  data += { u, approxValue, exactValue, error };
302  }
303 
304  //Ausgabe in Datei
305  data.save(ofs, Output::latex);
306 }
307 
312 inline void ex10() {
313  nmx::Data<7> data;
314  //Anfangsbedingungen
315  const double x0 = 0, v0 = 0;
316  const double c1 = 10;
317  for (auto c2 : { 1., -3. }) {
318  //Beschleunigung
319  auto afn = [c1, c2](double t) { //
320  return c1 * t + c2 * sqrt(t);
321  };
322  //Funktionen zur exakten Berechnung von
323  // Geschwindigkeit...
324  auto vex = [c1, c2, v0](double t) {
325  const auto static f1 = 2. / 3.;
326  const auto static f2 = 3. / 2.;
327  return 0.5 * c1 * pow(t, 2) + f1 * c2 * pow(t, f2) + v0;
328  };
329  // ... und Ort
330  auto xex = [c1, c2, v0, x0](double t) {
331  const auto static f1 = 1. / 6.;
332  const auto static f2 = 4. / 15.;
333  const auto static f3 = 5. / 2.;
334  return f1 * c1 * pow(t, 3) //
335  + f2 * c2 * pow(t, f3) + v0 * t + x0;
336  };
337 
338  // Integrand zur numerischen Berechnung des Ortes
339  // berechnet für jedes t intern über numerische Integration
340  // die Geschwindigkeit und wird dann zur numerischen
341  // Berechnung des Ortes eingesetzt.
342  auto vfn = [&afn](double t) {
343  gsl::CQUADIntegral integral(afn);
344  integral.apply(0, t);
345  return integral.result();
346  };
347  //berechne Daten für t
348  for (double tmax : { 10, 20, 30 }) {
349  gsl::Integral integral1(afn);
350  integral1.qng(v0, tmax, 0, 1e-6);
351  gsl::Integral integral2(vfn);
352  integral2.qng(x0, tmax, 0, 1e-6);
353  data += { c1,
354  c2,
355  tmax,
356  integral1.result(), //
357  integral2.result(),
358  vex(tmax),
359  xex(tmax) };
360  }
361  }
362 
363  //speichere Daten im LaTeX-Format
364  std::ofstream ofs = get_output_stream(__func__, Output::latex);
365  data.save(ofs, Output::latex);
366 }
367 
372 inline void ex11() {
373  nmx::Data<5> data;
374 
375  for (double c1 : { 10, 20 }) {
376  for (double c2 : { 0.1, 0.2 }) {
377  //Formel zur Berechnung des exakten Werts
378  auto fnex = [c1, c2](double v) { //
379  return 1 / c2 * log(c1 / (c1 - c2 * v));
380  };
381 
382  // Integrand des numerischen Integrals
383  auto fn = [c1, c2](double v) { //
384  return 1 / (c1 - c2 * v);
385  };
386 
387  //Iteration über die Geschwindigkeiten
388  for (double v : { 10, 30 }) {
389  gsl::Integral integral(fn);
390  integral.qag(0, v, 6, 0, 1e-5);
391  data += { c1, c2, v, integral.result(), fnex(v) };
392  }
393  }
394  }
395 
396  //Ausgabe in Datei
397  std::ofstream ofs = get_output_stream(__func__, Output::latex);
398  data.save(ofs, Output::latex);
399 }
400 
404 inline void ex12() {
405  nmx::Data<5> data;
406  const double v0 = -6;
407  const double m = 2;
408  const double F0 = 25, omega = Math::PI / 10;
409 
410  auto force = [F0, omega](double t) { //zeitabhängige Kraft
411  return F0 * cos(omega * t);
412  };
413 
414  //exakte Formel für die Geschwindigkeit
415  auto vex = [v0, F0, m, omega](double t) { //
416  return v0 + F0 / (m * omega) * sin(omega * t);
417  };
418 
419  for (double t : { 2., 10., 15. }) {
420  gsl::Integral integral(force); //numerische Berechnung
421  integral.qag(0, t, 6);
422  const double vnum = v0 + 1 / m * integral.result();
423  data += { t, v0, force(t), vnum, vex(t) };
424  }
425 
426  //Ausgabe in Datei
427  std::ofstream ofs = get_output_stream(__func__, Output::latex);
428  data.save(ofs, Output::latex);
429 }
430 
435 inline void ex13() {
436  nmx::Data<5> data;
437  const double m = 2;
438  const double l0 = 1, v0 = 15;
439  const double k = 4;
440 
441  auto force = [l0](double x) { //
442  return x - l0 * x / sqrt(pow(l0, 2) + pow(x, 2));
443  };
444 
445  auto vex = [l0, v0, k, m](double x) {
446  const static double trm1 = pow(v0, 2);
447  const static double trm2 = 2 * k / m;
448  const double trm3 = sqrt(pow(l0, 2) + pow(x, 2));
449  return sqrt(trm1 - trm2 * (0.5 * pow(x, 2) - l0 * trm3 + pow(l0, 2)));
450  };
451 
452  auto vnum = [v0, k, m](const auto &intresult) { //
453  return sqrt(pow(v0, 2) - 2 * k / m * intresult);
454  };
455 
456  for (double x : { 1., 2.5, 4. }) {
457  gsl::Integral integral(force);
458  integral.qng(0, x, 0, 1e-6);
459  data += { v0,
460  x,
461  force(x), //
462  vnum(integral.result()),
463  vex(x) };
464  }
465 
466  //Ausgabe in Datei
467  std::ofstream ofs = get_output_stream(__func__, Output::latex);
468  ofs << std::setprecision(4);
469  data.save(ofs, Output::latex);
470 }
471 
475 inline void ex14() {
476  //Federkonstante
477  const double k = 100;
478  //Massen der Blöcke
479  const double m1 = 10, m2 = 5;
480  //Feder wird um diese Länge gestaucht
481  const double l = 20._cm;
482  //exakte Formel für die Geschwindigkeit
483  auto vex = [k, m1, m2](double x) { //
484  return sqrt(k / (m1 + m2)) * x;
485  };
486  //Integrand
487  auto fn = [k, m1, m2](double x) { //
488  return k / (m1 + m2) * x;
489  };
490  //numerische Berechnung des Integrals ohne den Faktor 2
491  gsl::Integral integral(fn);
492  integral.qng(0, l);
493  //Ausgabe in Datei
494  std::ofstream ofs = get_output_stream(__func__, Output::terminal);
495  ofs << "exact :" << vex(l) << std::endl;
496  ofs << "numerical :" << sqrt(2 * integral.result()) << std::endl;
497 }
498 
502 inline void ex15() {
503  //Integrand
504  auto fn = [](double x) { return 1 / sqrt(sin(x)); };
505  //gsl-Klasse
506  gsl::Integral integral(fn);
507  //adaptive integration (mit Singularitäten) im Intervall [0,1]
508  integral.qags(0, 1);
509  //Ausgabe
510  const double expected = 2.0348053;
511  std::ofstream sout = get_output_stream(__func__, Output::terminal);
512  integral.show_results(sout, expected);
513 }
514 
521 template<class T>
522 inline void show_results(std::ofstream &sout, const T &gslint, double expected) {
523  sout << "result = " << gslint.result() << "\n";
524  sout << "exact result = " << expected << "\n";
525  sout << "estimated error= " << gslint.error() << "\n";
526  sout << "actual error = " << abs(gslint.result() - expected) << "\n";
527  sout << "intervals = " << gslint.intervals() << "\n";
528 }
529 
534 void gslex_cquad() {
535  //gsl Struktur: Verwaltung von Daten
536  gsl_integration_cquad_workspace *w = gsl_integration_cquad_workspace_alloc(100);
537  //analytisch berechnetes Ergebnis
538  double expected = -4;
539  //Parameter des Integranden
540  double alpha = 1.0;
541  //Ausgabewerte der Integrationsroutine
542  double result, error;
543  //Anzahl der Funktionsauswertungen
544  size_t nevals;
545  //gsl-Funktion(übergibt Integranden an die Integrationsroutine)
546  gsl_function F;
547  F.function = &f;
548  F.params = &alpha;
549  //numerische Integration, Integrand hat Singularität
550  gsl_integration_cquad(&F, 0, 1, 0, 1e-7, w, &result, &error, &nevals);
551  //Ausgabe der Daten
552  printf("result = % .18f\n", result);
553  printf("exact result = % .18f\n", expected);
554  printf("estimated error = % .18f\n", error);
555  printf("actual error = % .18f\n", result - expected);
556  printf("intervals = %zu\n", w->size);
557 
558  //Freigabe des workspace
559  gsl_integration_cquad_workspace_free(w);
560 }
561 
562 } // namespace nmx::apps::x039
int qagiu(double xmin, double epsabs=0, double epsrel=1e-9)
qagiu numerische Integration mit automatischer Schrittweitenanpassung von xmin bis + Unendlich ...
Definition: xquad.h:204
int qagil(double xmax, double epsabs=1e-9, double epsrel=1e-9)
qagil numerische Integration mit automatischer Schrittweitenanpassung von - Unendlich bis xmax ...
Definition: xquad.h:222
void ex11()
ex11 Teilchen bewegt sich geradlinig mit einer geschwindigkeitsabhängigen Beschleunigung ...
Definition: x039.h:372
The CQUADIntegral class adaptive numerische Integration geeignet für Integranden mit Singularitäten o...
Definition: xquad.h:238
void ex2()
ex2
Definition: x039.h:105
void ex15()
ex1
Definition: x039.h:502
void save(std::ostream &ofs, Format fmt) const
save Schreibe Tabelle in Datei
Definition: xdata.h:160
void ex8()
ex8 Massenmittelpunkt eines homogenen Halbkreisrings
Definition: x039.h:231
The Data class Eine Klasse für Zahlentabellen mit fester Anzahl von Spalten. Die Anzahl der Reihen wä...
Definition: xdata.h:22
auto qng(double xmin, double xmax, double epsabs=1e-9, double epsrel=1e-9)
qng Integration von stetigen Funktionen keine automatische Schrittweitenanpassung ...
Definition: xquad.h:132
void ex9()
ex9 Potenzielle Energie einer Masse im Gravitationsfeld der Erde
Definition: x039.h:279
void gslex()
gslex numerische Integration Beispiel mit Kommentaren https://www.gnu.org/software/gsl/doc/html/integ...
Definition: x039.h:32
static const Format terminal
Definition: xoutput.h:19
void ex12()
ex12 Geschwindigkeitsänderung durch Kraftstoß
Definition: x039.h:404
static std::ofstream get_stream(const std::string &fname)
get_output_stream Öffnen einer Ausgabedatei falls die Datei nicht geöffnet werden kann wird ein Fehle...
Definition: xoutput.h:29
void show_results(std::ofstream &sout, const T &gslint, double expected)
show_results
Definition: x039.h:522
void ex7()
ex7 Massenmittelpunkt eines homogenen dünnen zylindrischen Stabs
Definition: x039.h:201
void ex10()
ex10 Teilchen bewegt sich geradlinig mit zeitabhängiger Beschleunigung
Definition: x039.h:312
int qags(double xmin, double xmax, double epsabs=1e-9, double epsrel=1e-9)
qags numerische Integration mit automatischer Schrittweitenanpassung von singulären Funktionen ...
Definition: xquad.h:171
void show_results(std::ofstream &sout, double expected)
show_results einfache Ausgabe des Ergebnisses mit Zusatzinformationen
Definition: xquad.h:54
void ex4()
ex4
Definition: x039.h:137
void gslex_cquad()
gslex_cquad numerische Integration mit CQUAD (gsl-Beispiel mit Kommentaren)
Definition: x039.h:534
void ex0()
ex0 nicht adaptive Gauß-Kronrod Integration
Definition: x039.h:72
void ex3()
ex3
Definition: x039.h:121
void ex14()
ex14 Zwei Blöcke und eine Feder
Definition: x039.h:475
void ex1()
ex1
Definition: x039.h:88
double f(double x, void *params)
f Integrand (gsl-Funktion)
Definition: x039.h:22
The Integral class erste Varianten der gsl-Klasse zur numerischen Integration. Der Template-Parameter...
Definition: xquad.h:86
The Format class Formatierte Ausgabe von Arrays.
Definition: xfmt.h:10
static constexpr double PI
Definition: xmath.h:11
void ex6()
ex6 Teilchen bremst auf geradliniger Strecke
Definition: x039.h:170
static const Format latex
Definition: xoutput.h:17
static constexpr double g
Definition: xphysics.h:20
int apply(double xmin, double xmax, double epsabs=1e-9, double epsrel=1e-9)
apply Ausführung der numerischen Integration
Definition: xquad.h:274
void ex5()
ex5
Definition: x039.h:153
int qagi(double epsabs=1e-9, double epsrel=1e-9)
qagi numerische Integration mit automatischer Schrittweitenanpassung von - Unendlich bis + Unendlich ...
Definition: xquad.h:187
int qag(double xmin, double xmax, int key, double epsabs=1e-9, double epsrel=1e-9)
qag numerische Integration mit automatischer Schrittweitenanpassung (Gauß-Kronrod) ...
Definition: xquad.h:152
double result() const
result
Definition: xquad.h:66
void ex13()
ex13 Perle bewegt sich reibungsfrei entlang einer Schiene unter dem Einfluss einer Feder ...
Definition: x039.h:435