Hier eine Tabelle der Nullstellen von J0, J1 und J2 im Intervall [0,1000] auf 20 Stellen genau: BESJZERO.TXT (berechnet mit besselj(n,x) von Pari/GP, Version 2.3.4). Nullstellensuche mit GNU-Octave: findzeros.m (Beschreibung siehe unten).
Nullstellen der Besselfunktionen J0, J1 und J2.
Tabellen mit Funktionswerten sind in diesem Jahrhundert ja etwas aus der Mode gekommen ... Auf der Suche nach einer Liste von Nullstellen der Besselschen Funktionen erster Art Jn(x), möglichst mit Angaben zur Genauigkeit, konnte ich daher auf die schnelle nur eine ... hmm ... ältere Publikation ausfindig machen:
Davis, H. T. and W. J. Kirkham. A NEW TABLE OF THE ZEROS OF THE BESSEL FUNCTIONS J0(x) AND J1(x) WITH CORRESPONDING VALUES OF J1(x) AND J0(x). Bull. Amer. Math. Soc. 33.6 (1927): 760–772.
Dort findet man die ersten 150 Nullstellen von J0 und J1 auf 10 Nachkommastellen berechnet. Wer längere oder genauere Tabellen haben möchte, muss dagegen selbst rechnen. Als ich versucht habe, die Nullstellen mal eben mit Hilfe von "fzero" von GNU-Octave zu bestimmen, verhielten sich die Besselfunktionen allerdings unerwartet widerspenstig (siehe das Beispiel unten).
Die Nullstellen wurden schließlich mit Hilfe des Skripts findzeros.m durch Bisektion bestimmt. Anschließend wurde mit der "solve"-Funktion von Pari/GP (in der Standardeinstellung mit 28 signifikanten Stellen) nachiteriert und die Ergebnisse auf 20 Stellen gerundet ausgegeben.
Octave-Skript zur Nullstellensuche
Das Skript findzeros.m ist ein m-File für GNU-Octave (für MATLAB-Kompatiblität sind evtl. kleinere Änderungen nötig). Es findet Nullstellen von reellwertigen Funktionen f : R → R im Intervall [a,b], sofern Bisektion anwendbar ist, d. h. wenn Vorzeichenwechsel an den Nullstellen stattfinden. Die Intervallschachtelung wird bis zum Erreichen des Maschinen-Epsilons durchgeführt. Zur Kontrolle können auch die Funktionswerte ausgegeben werden (falls man z.B. eine Polstelle statt einer Nullstelle erwischt haben sollte). Details mit "help findzeros".
Anwendung auf die Besselfunktionen: Die von findzeros.m ausgegebenen Nullstellen von J0, J1 und J2 für |x| < 1000 waren auf mindestens 1e-13 genau, und die Funktionswerte wichen um maximal 4e-15 von Null ab. Die mit Pari/GP nachbehandelten Werte in BESJZERO.TXT sollten korrekt auf 20 Stellen gerundet sein (die Korrektheit der besselj(n,x)-Funktion von Pari/GP vorausgesetzt).
Probleme mit "fzero" von GNU-Octave
Mit der Funktion "fzero" von Octave lassen sich allgemein Nullstellen von nichtlinearen Funktionen finden. Das klappt in vielen Fällen sehr gut, jedoch hat fzero auch Schwächen:
Beispielsweise kann man lediglich einen Startwert x0 vorgeben, aber kein Intervall [a,b]. Manchmal fühlt sich fzero dann zu weit entfernten Nullstellen hingezogen (siehe Beispiel). Ärgerlich wird's, wenn man bereits weiß, dass eine Nullstelle x mit a < x < b existiert ... (Die Funktion "solve" von Pari/GP arbeitet ähnlich, hat aber den Vorteil, dass sich hier ein Anfangsintervall [a,b] vorgeben lässt.)
Auch mit dem Parameter "TolX" ließ sich fzero nicht dazu überreden, dieselbe Genauigkeit zu erreichen, wie sie eine einfache selbstgebastelte Bisektion liefert.
Die Besselfunktionen scheinen ein Beispiel zu sein, das fzero gar nicht mag (gestestet mit Octave, Version 3.2.4). Die ersten Nullstellen von J2(x) sind x = 0, 5.1, 8.4, 11.6, 14.8, und 18 (symmetrisch dazu gibt es negative Nullstellen).
Pari/GPs "solve" hatte mit J2(x) an der Nullstelle x = 0 ebenfalls Probleme (Version 2.3.4). Genauso scheitert "findzeros.m" mit seiner Bisektion, da an dieser Stelle kein Nulldurchgang stattfindet. (Von der Ausnahme x = 0 abgesehen haben die Jn aber stets nur einfache Nullstellen.)
Beispiel zum "fzero"-Problem:
> % Hilfsfunktion BesselJ2(x) = besselj(2,x) > function y = BesselJ2(x); y=besselj(2,x); end > fzero(@BesselJ2,-1) % Scheitert komplett (weil es hier > fzero(@BesselJ2,0) % vergeblich eine Bisektion versucht). > fzero(@BesselJ2,1) error: fzero: zero point is not bracketed [...] > fzero(@BesselJ2,2) % Findet weit entfernte Nullstelle ... ans = -11.620 > fzero(@BesselJ2,3) % Ok. > fzero(@BesselJ2,4) % Ok. > fzero(@BesselJ2,5) % Ok. > fzero(@BesselJ2,6) % Ok. ans = 5.1356 > fzero(@BesselJ2,7) % x = 8.4 liegt bereits näher. ans = 5.1356 > fzero(@BesselJ2,8) % Ok. > fzero(@BesselJ2,9) % Ok. ans = 8.4172 > fzero(@BesselJ2,10) % x = 11.6 und x = 14.8 übersprungen. ans = 17.960 > fzero(@BesselJ2,11) % Ok. > fzero(@BesselJ2,12) % Ok. ans = 11.620 > fzero(@BesselJ2,13) % Ach du lieber Himmel! ans = -96.585 > fzero(@BesselJ2,14) % Ok. ans = 14.796 > fzero(@BesselJ2,-3) % Für negativen Funktionswert x = -3: Ok. ans = -5.1356 > fzero(@BesselJ2,-2) % Ein bisschen zu komplex... ans = 5.1356e+000 + 3.1564e-024i
Version: 2010-04-18, Stefan Reiser, (s.reiser@tu-braunschweig.de)