WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Nullstellen der Besselfunktion mit Newton-Näherung

 

taiyou92
Forum-Anfänger

Forum-Anfänger


Beiträge: 12
Anmeldedatum: 16.10.19
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 16.10.2019, 23:23     Titel: Nullstellen der Besselfunktion mit Newton-Näherung
  Antworten mit Zitat      
Liebes Forum Smile
Ich sitze schon seit Tagen an einem Problem an dem ich einfach nicht weiter komme, und mir auch kein anderer Helfen kann.
Und zwar ich soll die die ersten 3 Nullstellen der Besselfunktion mit J = 0,1,2 bestimmen, und zwar mit der Newton-Näherung.

Hierbei habe ich ich die Besselfunktion nach Vorzeichenänderungen abgetastet um geeignete Startwerte zu finden, und wollte darauf hin die Näherung mit einer while Schleife realisieren mit gegebener Schranke 1e-13. Doch es funktioniert einfach nicht. Bin schon wirklich am verzweifeln. Daher meine Bitte, könnt ihr mir bitte Sagen was ich falsch mache?
Vielen Dank im Voraus für eure Hilfe!

Mein Code:

Code:
%
x = linspace(0,15,50);
J0= besselj(0,x);
J1 = besselj(1,x);
J2 = besselj(2,x);




%Vorzeichenwechsel detektieren
vorzeichen0 = sign(J0);
vorzeichen1 = sign(J1);
vorzeichen2 = sign(J2);
nullstelle0=find(diff(vorzeichen0)>0 | diff(vorzeichen0)<0);
nullstelle1=find(diff(vorzeichen1)>0 | diff(vorzeichen1)<0);
nullstelle2=find(diff(vorzeichen2)>0 | diff(vorzeichen2)<0);

% Startwerte auf X-Achse;

x0 = x(nullstelle0);
x1 = x(nullstelle1);
x2 = x(nullstelle2);

% Auswertung Besselfunktion an den "Nullstellen";
j0 = J0(nullstelle0);
j1 = J1(nullstelle1);
j2 = J2(nullstelle1);

jd0 = gradient(j0);
jd1 = gradient(j1);
jd2 = gradient(j2);

xnull0 = x0;
while abs(j0)>1e-12;
    if abs(j0)< 1e-12 |
       break
    end
    xnull0 = xnull0- j0./jd0;
end
Private Nachricht senden Benutzer-Profile anzeigen


T16
Forum-Century

Forum-Century


Beiträge: 145
Anmeldedatum: 31.01.18
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 17.10.2019, 10:30     Titel:
  Antworten mit Zitat      
Dein Gradient haut meiner Meinung nach nicht hin. Du legst in klein j0 nacheinander deine Nullstellenkandidaten ab und bildest dann davon den Gradienten.
Private Nachricht senden Benutzer-Profile anzeigen
 
taiyou92
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 12
Anmeldedatum: 16.10.19
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 17.10.2019, 11:11     Titel:
  Antworten mit Zitat      
Danke für die Antwort Smile
Wie kann ich in Matlab die erste Ableitung der Besselfunktion sonst berechnen?
Leider kenne ich nur die Befehle gradient und diff, und mit beiden scheint es leider nicht hinzuhauen.

lg
taiyou92
Private Nachricht senden Benutzer-Profile anzeigen
 
T16
Forum-Century

Forum-Century


Beiträge: 145
Anmeldedatum: 31.01.18
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 17.10.2019, 11:49     Titel:
  Antworten mit Zitat      
Gradient ist schon die korrekte Funktion, nur das Argument passt noch nicht. Ich würde dir zunächst empfehlen, erstmal nur die erste Nullstelle zu suchen, die restlichen kann man dann später sehr einfach hinzufügen.

Zu Beginn kannst du dir den Gradienten zunächst für den gesamten betrachteten Bereich zurechtbasteln: JD0 = gradient(J0)

Die Ableitung an deiner ersten Nullstelle nullstelle0 kannst du dir dann einfach über jd0=JD0(nullstelle0) aus diesem Vektor herausziehen. Damit solltest du dir erste Iteration deiner Lösung hinbekommen. Jetzt wirst du natürlich nicht drumherum kommen, an der so errechneten neuen Nullstele die Besselfunktion und deren Ableitung erneut auszuwerten. Smile

Code:
x   = linspace(0,15,50);
J0  = besselj(0,x);
JD0 = gradient(J0);

vorzeichen0 = sign(J0);
nullstelle0=find(diff(vorzeichen0)>0 | diff(vorzeichen0)<0);
nullstelle0=nullstelle0(1);


x0 = x(nullstelle0);

j0 = J0(nullstelle0);
jd0= JD0(nullstelle0);
Private Nachricht senden Benutzer-Profile anzeigen
 
taiyou92
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 12
Anmeldedatum: 16.10.19
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 17.10.2019, 13:26     Titel:
  Antworten mit Zitat      
Ok, Danke für die schnelle Hilfe ! Smile
Ich habe das ganze soeben ausprobiert aber leider, bekomme ich für die 1 Nullstelle nur 2.272 heraus, eigentlich sollte ja pi rauskommen für die 1 Nullstelle der Besselfunktion J = 0, oder? Aber zumindest läuft jetzt die Schleife Smile
An was könnte das liegen? Für mich sieht der Code eigentlich so weit richtig aus.


lg taiyou92

Code:
%
x = linspace(0,15,100);
J0= besselj(0,x);
J1 = besselj(1,x);
J2 = besselj(2,x);
J0d = gradient(J0);
J1d = gradient(J1);
J2d = gradient(J2);

%Vorzeichenwechsel detektieren;
vorzeichen0 = sign(J0);
vorzeichen1 = sign(J1);
vorzeichen2 = sign(J2);
nullstelle0=find(diff(vorzeichen0)>0 | diff(vorzeichen0)<0);
nullstelle1=find(diff(vorzeichen1)>0 | diff(vorzeichen1)<0);
nullstelle2=find(diff(vorzeichen2)>0 | diff(vorzeichen2)<0);

% 1 Nullstellen;
nullstelle0 = nullstelle0(1);
nullstelle1 = nullstelle1(1);
nullstelle2 = nullstelle2(1);

% Startwerte 1 Nullstelle auf X-Achse;

x0 = x(nullstelle0);
x1 = x(nullstelle1);
x2 = x(nullstelle2);

% Auswertung Besselfunktion an 1 Nullstelle;
j0 = besselj(0,x0);
j1 = besselj(1,x1);
j2 = besselj(2,x2);
jd0 = gradient(j0);
jd1 = gradient(j1);
jd2 = gradient(j2);


xn = x0;
while abs(j0)<1e-12
    j0 = besselj(0,xn);
    jd0 = gradient(j0);
    xn = xn- j0./jd0;
end

k = xn % Schmeißt mir Nan als Ergebnis raus.

 


Zuletzt bearbeitet von taiyou92 am 17.10.2019, 14:08, insgesamt 2-mal bearbeitet
Private Nachricht senden Benutzer-Profile anzeigen
 
T16
Forum-Century

Forum-Century


Beiträge: 145
Anmeldedatum: 31.01.18
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 17.10.2019, 14:03     Titel:
  Antworten mit Zitat      
Da ist noch einiges im Argen, angehängt ist ein funktionierender kommentierter Code für eine Nullstelle. Dein Abbruchkriterium ist im neuen Code falsch herum, er soll doch bitte rechnen bis der Fehler kleiner ist als dein Abbruchkriterium, nicht umgekehrt Wink
Außerdem haut dein Gradient nach wie vor noch nicht hin. Du übergibts aktuell ein Skalar an gradient(), demenstprechend gibt dir gradient() nur eine Null zurück. Die gradient()-funktion braucht immer Vektoren und spuckt dir dann die Differenzen zwischen den Vektoreinträgen aus. Das kann man nutzen, um die Ableitung zu berechnen in dem man das Ergebnis durch die (x)-Schrittweite teilt.
Die Nullstelle kannst du einfach überprüfen, indem du die Funktion fix plottest
plot(x, J0), da siehst du auch, dass deine "berechnete" Nullstelle gar nicht so weit von der tatsächlichen Nullstelle entfernt liegt. Allerdings ist die ausgegebene Nullstelle bisher nur deine erste Schätzung, das Newtonverfahren kam nicht zur Anwendung da, wie bereits erwähnt, dein Abbruchkriterium noch nicht hinhaut.


Code:
x   = linspace(0,15,10000);   % x-Vektor für die erste Nullstellensuche aufbauen, je mehr Punkte desto genauer ist die Abschätzung!
sw  = x(2)-x(1);       % Schrittweite des x-Vektors, wichtig um die Ableitung korrekt zu bestimmen
J0  = besselj(0,x);    % Besselfunktion
JD0 = gradient(J0)/sw; % Und deren Ableitung


%% Erste Nullstllensuche, war so korrekt
vorzeichen0 = sign(J0);
nullstelle0=find(diff(vorzeichen0)>0 | diff(vorzeichen0)<0);
nullstelle0=nullstelle0(1);

%% x0, j0, dj0 festlegen
x0 = x(nullstelle0);
j0 = J0(nullstelle0);
jd0= JD0(nullstelle0);

sw=1e-8; %Schrittweite für genauere Suche
xnull0 = x0;
while j0>1e-12
    xnull0 = xnull0- j0./jd0; %% Newtonverfahren
    j0=besselj(0,xnull0);     % An neuer vermuteter Nullstelle Besselfunktion auswerten
    jtemp=besselj(0,xnull0-sw:sw:xnull0+sw); % Besselfunktion um Nullstelle herum bilden
    jd0=gradient(jtemp);  
    jd0=jd0(2)./sw;           % Und ableiten
end
Private Nachricht senden Benutzer-Profile anzeigen
 
taiyou92
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 12
Anmeldedatum: 16.10.19
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 17.10.2019, 14:25     Titel:
  Antworten mit Zitat      
VIELEN DANK!!! Endlich funktioniert es.
Very Happy
Buh,bei diesen Problem bin ich doch wirklich seit Tagen auf dem Schlauch gestanden!
Auf jeden Fall Danke für die Hilfe, jetzt hab ich es endlich verstanden Smile

lg
Taiyou
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum posten
Du kannst Dateien in diesem Forum herunterladen
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2024 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.