Für Vorlesungen, bitte die Webseite verwenden. https://flavigny.de/lecture
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

92 lines
2.4KB

  1. #include <iostream>
  2. #include <vector>
  3. #include "hdnum.hh"
  4. template<class N>
  5. class PolynomialProblem
  6. {
  7. public:
  8. // Exportiere Größentyp
  9. typedef std::size_t size_type;
  10. // Exportiere Zahlentyp
  11. typedef N number_type;
  12. // Dimension der untenstehenden Funktion
  13. std::size_t size () const
  14. {
  15. return 1;
  16. }
  17. // Funktionsauswertung
  18. void F (const hdnum::Vector<N>& x, hdnum::Vector<N>& result) const
  19. {
  20. result[0] = pow(x[0], 4) - 3.0*pow(x[0], 3) + 5.0*x[0] + 3.0;
  21. }
  22. // Jacobimatrix
  23. void F_x (const hdnum::Vector<N>& x, hdnum::DenseMatrix<N>& result) const
  24. {
  25. result[0][0] = 4.0*pow(x[0], 3) - 9.0*pow(x[0], 2) + 5.0;
  26. }
  27. };
  28. int main ()
  29. {
  30. typedef std::complex<double> Number; // Der Zahlentyp soll hier komplex sein
  31. typedef PolynomialProblem<Number> Problem;
  32. Problem problem;
  33. // Wir schauen Startpunkte auf einem Raster an, das später in ein Bild umgesetzt werden soll
  34. for (double start_value_i = -5.0; start_value_i <= 5.0; start_value_i += 1e-2) {
  35. for (double start_value = -5.0; start_value <= 5.0; start_value += 1e-2) {
  36. hdnum::Vector<Number> u(problem.size()); // Vektor für Startpunkt bzw Lösung
  37. u[0] = Number(start_value, start_value_i); // Startpunkt
  38. hdnum::Newton newton;
  39. newton.set_maxit(20);
  40. newton.set_verbosity(0);
  41. newton.set_reduction(1e-10);
  42. newton.set_abslimit(1e-20);
  43. newton.set_linesearchsteps(3);
  44. newton.solve(problem,u); // Lösen
  45. double id = 0;
  46. if(newton.has_converged()) {
  47. // Falls unser Newton-Löser konvergiert ist, stellen wir fest welche Nullstelle
  48. // Nullstelle wir getroffen haben und legen einen Index für jede Nullstelle fest.
  49. if (u[0].real() < 0 && u[0].imag() < 0)
  50. id = 1;
  51. else if (u[0].real() < 0 && u[0].imag() > 0)
  52. id = 2;
  53. else if (u[0].real() > 0 && u[0].imag() < 0)
  54. id = 3;
  55. else if (u[0].real() > 0 && u[0].imag() > 0)
  56. id = 4;
  57. else
  58. std::cout << "Unbekannte Nullstelle!" << std::endl;
  59. // Damit auch der "Abstand" zur Nullstelle (im Sinne von benötigten Iterationen
  60. // um sie zu erreichen) sichtbar wird, addieren wir noch die Iterationszahl
  61. // um einen Faktor abgeschwächt
  62. id += .1 * (double)newton.iterations();
  63. }
  64. std::cout << id << ",";
  65. }
  66. std::cout << std::endl;
  67. }
  68. return 0;
  69. }