x034.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <gsl/gsl_errno.h>
4 #include <gsl/gsl_math.h>
5 #include <gsl/gsl_roots.h>
6 
7 #include "xoutput.h"
8 #include "xroot.h"
9 
10 namespace nmx::apps::x034 {
11 
16  double a, b, c;
17 };
18 
25 double quadratic_fn(double x, void *params) {
26  //Konvertierung des void-Zeigers, die Koeffizienten des Polynoms
27  //werden über diesen Parameter festgelegt
28  struct quadratic_params *p = static_cast<quadratic_params *>(params);
29  //Koeffizienten a x^2 + b x + c
30  double a = p->a;
31  double b = p->b;
32  double c = p->c;
33  return (a * x + b) * x + c;
34 }
35 
42 double quadratic_deriv(double x, void *params) {
43  //Konvertierung des void-Zeigers, die Koeffizienten des Polynoms
44  //werden über diesen Parameter festgelegt
45  struct quadratic_params *p = static_cast<quadratic_params *>(params);
46  //Koeffizienten a x^2 + b x + c
47  double a = p->a;
48  double b = p->b;
49  return 2.0 * a * x + b;
50 }
51 
60 void quadratic_fdf(double x, void *params, double *y, double *dy) {
61  //Konvertierung des void-Zeigers, die Koeffizienten des Polynoms
62  //werden über diesen Parameter festgelegt
63  struct quadratic_params *p = static_cast<quadratic_params *>(params);
64  //Koeffizienten a x^2 + b x + c
65  double a = p->a;
66  double b = p->b;
67  double c = p->c;
68  *y = (a * x + b) * x + c;
69  *dy = 2.0 * a * x + b;
70 }
71 
75 inline void ex1() {
76  // Definition der Funktion, für welche die Nullstelle gesucht wird
77  //Polynomkoeffizienten
78  quadratic_params params = { 1.0, 0.0, -5.0 };
79  //gsl-Funktion
80  gsl_function F;
81  F.function = &quadratic_fn;
82  F.params = &params;
83 
84  //**Teil 2
85  // Initialisierung der gsl_Routinen
86  // Anfangsintervall
87  double x_lo = 0.0, x_hi = 5.0;
88  //Bisektionsalgorithmus
89  const gsl_root_fsolver_type *T = gsl_root_fsolver_bisection;
90  //Routine zur Nullstellensuche
91  gsl_root_fsolver *s;
92  s = gsl_root_fsolver_alloc(T);
93  //registriere Funktion
94  gsl_root_fsolver_set(s, &F, x_lo, x_hi);
95 
96  //**Teil 3
97  //Iteration
98  printf("using %s method\n", gsl_root_fsolver_name(s));
99  printf("%5s [%9s, %9s] %9s %10s %9s\n", "iter", "lower", "upper", "root", "err", "err(est)");
100 
101  double r = 0, r_expected = sqrt(5.0);
102  int status;
103  int iter = 0, max_iter = 100;
104  do {
105  //Zähler damit keine Endlosschleife entsteht
106  iter++;
107  //Iterationschritt
108  status = gsl_root_fsolver_iterate(s);
109  r = gsl_root_fsolver_root(s);
110  //neue Grenzen für das Intervall
111  x_lo = gsl_root_fsolver_x_lower(s);
112  x_hi = gsl_root_fsolver_x_upper(s);
113  //ist das Intervall klein genug?
114  status = gsl_root_test_interval(x_lo, x_hi, 0, 0.001);
115 
116  if (status == GSL_SUCCESS) {
117  printf("Converged:\n");
118  }
119 
120  printf("%5d [%.7f, %.7f] %.7f %+.7f %.7f\n",
121  iter,
122  x_lo,
123  x_hi,
124  r,
125  r - r_expected,
126  x_hi - x_lo);
127  } while (status == GSL_CONTINUE && iter < max_iter);
128 
129  //**Teil 4
130  //Speicherfreigabe
131  gsl_root_fsolver_free(s);
132 }
133 
137 inline void ex2() {
138  //Definition der Funktion, für welche die Nullstelle gesucht
139  //wird,Ableitung der Funktion,kombinierter Aufruf Funktion
140  // und Ableitung
141  quadratic_params params = { 1.0, 0.0, -5.0 };
142  gsl_function_fdf FDF;
143  FDF.f = &quadratic_fn;
144  FDF.df = &quadratic_deriv;
145  FDF.fdf = &quadratic_fdf;
146  FDF.params = &params;
147 
148  //**Teil 2
149  //Initialisierung der gsl_Routinen Anfangsintervall
150  double x0, x = 5.0, r_expected = sqrt(5.0);
151  //Newton-Algorithmus
152  const gsl_root_fdfsolver_type *T = gsl_root_fdfsolver_newton;
153  //Routine zur Nullstellensuche
154  gsl_root_fdfsolver *s;
155  s = gsl_root_fdfsolver_alloc(T);
156  //registriere Funktion und ihre Ableitung
157  gsl_root_fdfsolver_set(s, &FDF, x);
158 
159  //**Teil 3
160  //Iteration
161  int status;
162  int iter = 0, max_iter = 100;
163  printf("using %s method\n", gsl_root_fdfsolver_name(s));
164  printf("%-5s %10s %10s %10s\n", "iter", "root", "err", "err(est)");
165  do {
166  //Zähler damit keine Endlosschleife entsteht
167  iter++;
168  //Iterationschritt
169  status = gsl_root_fdfsolver_iterate(s);
170  x0 = x;
171  x = gsl_root_fdfsolver_root(s);
172  //ist Nullstelle gefunden?
173  status = gsl_root_test_delta(x, x0, 0, 1e-3);
174 
175  if (status == GSL_SUCCESS)
176  printf("Converged:\n");
177 
178  printf("%5d %10.7f %+10.7f %10.7f\n", iter, x, x - r_expected, x - x0);
179  } while (status == GSL_CONTINUE && iter < max_iter);
180 
181  //**Teil 4
182  //Speicherfreigabe
183  gsl_root_fdfsolver_free(s);
184 }
185 
191 inline auto get_output_stream(const char *name, Format fmt = Output::terminal) {
192  auto ofs = Output::get_stream("x034", fmt, name);
193  fmt.set_defaults(ofs);
194  return ofs;
195 }
196 
203 template<class T>
204 inline void show_results(std::ofstream &ofs, const T &obj, double expected) {
205  ofs << "method used :" << obj.method_used() << std::endl;
206  if (obj.converged()) {
207  ofs << "success\n";
208  ofs << "t:" << obj.result() << std::endl;
209  ofs << "t (exact):" << expected << std::endl;
210  ofs << "error:" << abs(obj.result() - expected) << std::endl;
211  } else {
212  ofs << "failed" << std::endl;
213  }
214 }
215 
219 inline void root1() {
220  //Suche Nullstelle dieser Funktion
221  auto function = [](double x) { return pow(x, 2) - 5; };
222 
223  // öffne Ausgabestrom
224  std::ofstream ofs = get_output_stream(__func__);
225  ofs << std::fixed << std::setprecision(7);
226 
227  //Zeichne Iterationsschritte auf
228  auto monitor = [&ofs](size_t i,
229  double xmin, //
230  double xmax,
231  double result) {
232  ofs << i << "\t" << xmin << "\t" //
233  << xmax << "\t" << result << std::endl;
234  };
235 
236  //gsl-Klasse zur Nullstellenberechnung
237  gsl::RootBracketing rootFinder{ function };
238  ofs << "iter\txmin\txmax\terror\n";
239  rootFinder.apply(0, 5, monitor, 0, 0.001);
240 
241  //Ausgabe
242  show_results(ofs, rootFinder, std::sqrt(5));
243 }
244 
248 inline void root2() {
249  auto function = [](double x) { return pow(x, 2) - 5; };
250  std::ofstream ofs = get_output_stream(__func__);
251  ofs << std::fixed << std::setprecision(7);
252  auto monitor = [&ofs](size_t i, double xmin, double xmax, double result) {
253  ofs << i << "\t" << xmin << "\t" << xmax << "\t" << result << std::endl;
254  };
255 
256  gsl::RootBracketing rootFinder{ function, gsl_root_fsolver_brent };
257  ofs << "iter\txmin\txmax\terror\n";
258  rootFinder.apply(0, 5, monitor, 0, 0.001);
259  ofs << "method used :" << rootFinder.method_used() << std::endl;
260  show_results(ofs, rootFinder, std::sqrt(5));
261 }
262 
266 inline void root3() {
267  //Bewegungsparameter
268  const double d = 100;
269  const double m1 = 1, m2 = 2;
270  const double f1 = 10, f2 = 15;
271  const double a1 = f1 / m1;
272  const double a2 = f2 / m2;
273 
274  //Suche Nullstelle dieser Funktion
275  auto fn = [d, a1, a2](double t) {
276  const auto x1 = 0.5 * a1 * pow(t, 2);
277  const auto x2 = d - 0.5 * a2 * pow(t, 2);
278  return (x1 - x2);
279  };
280 
281  //Ausgabestrom
282  std::ofstream ofs = get_output_stream(__func__);
283  ofs << std::fixed << std::setprecision(7);
284 
285  //gsl-Klasse
286  gsl::RootBracketing rootFinder{ fn, gsl_root_fsolver_brent };
287  rootFinder.apply(0, 100, 0, 1e-6);
288 
289  //Ergebnisse
290  const auto expected = sqrt(2 * d / (a1 + a2));
291  show_results(ofs, rootFinder, expected);
292 }
293 
297 inline void root4() {
298  //Funktion und ihre Ableitung
299  struct MyFN {
300  inline double f(double x) const { return pow(x, 2) - 5; }
301  inline double df(double x) const { return 2 * x; }
302  } myFN;
303 
304  //Ausgabestrom
305  std::ofstream ofs = get_output_stream(__func__);
306  ofs << std::setprecision(6) << std::fixed;
307 
308  //zeichne Schritte auf
309  auto monitor = [&ofs](size_t itr, double x0, double x) {
310  ofs << itr << "\t" << x << "\t" << x - x0 //
311  << "\t" << x - sqrt(5) << std::endl;
312  };
313 
314  //löse die Gleichung
315  gsl::FDFSolver rootFinder{ myFN };
316  rootFinder.apply(5, monitor);
317 
318  //zeige Iterationsschritte und Ergebnis
319  show_results(ofs, rootFinder, std::sqrt(5));
320 }
321 
322 } // namespace nmx::apps::x034
The quadratic_params struct.
Definition: x034.h:15
void ex2()
ex2 Nullstellensuche mit dem Newton-Verfahren und gsl-Routinen
Definition: x034.h:137
void show_results(std::ofstream &ofs, const T &obj, double expected)
show_results Präsentation der Ergebnisse
Definition: x034.h:204
void quadratic_fdf(double x, void *params, double *y, double *dy)
quadratic_fdf quadratisches Polynom und Ableitung
Definition: x034.h:60
void root4()
root4 Berechnung von sqrt(5) mit dem Newton-Verfahren
Definition: x034.h:297
void root2()
root2 Berechnung von sqrt{5} mit dem Bisektionsverfahren
Definition: x034.h:248
void ex1()
ex1 Bisektionsverfahren mit gsl-Routinen
Definition: x034.h:75
auto apply(double xmin, double xmax, FN fn, double epsabs, double epsrel)
apply startet Nullstellensuche
Definition: xroot.h:124
double quadratic_fn(double x, void *params)
quadratic quadratisches Polynom
Definition: x034.h:25
void root1()
root1 Berechnung von sqrt{5} mit dem Bisektionsverfahren
Definition: x034.h:219
auto get_output_stream(const char *name, Format fmt=Output::terminal)
get_output_stream
Definition: x034.h:191
static const Format terminal
Definition: xoutput.h:19
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
The RootBracketing class gsl-Klasse für das Bisektionsverfahren.
Definition: xroot.h:14
void root3()
root3 zwei Teilchen bewegen sich aufeinader zu
Definition: x034.h:266
The Format class Formatierte Ausgabe von Arrays.
Definition: xfmt.h:10
double quadratic_deriv(double x, void *params)
quadratic_deriv Ableitung des quadratischen Polynoms
Definition: x034.h:42
double f(double x, void *params)
f
Definition: x035.h:15
auto apply(double startval, double epsabs=0, double epsrel=1e-3)
apply Nullstellensuche
Definition: xroot.h:285
The FDFSolver class Nullstellensuche Funktion und ihre Ableitung werden benötigt. ...
Definition: xroot.h:175