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

Fehler im Code zur berechnung eines Cosinuswertes

 

Dippuff

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 03.06.2014, 12:34     Titel: Fehler im Code zur berechnung eines Cosinuswertes
  Antworten mit Zitat      
Hallo ihr Matlab-Profis,

ich schreibe grade eine Funktion zur Berechnung eines Cosinuswertes, mit Hilfe der Taylorreihe:




Die Eingabeparameter der Funktion sind "eps" und "x".
"x" ist dabei der X-Wert, von dem der Y-Wert berechnet werden soll.
"eps" ist eine Zahl zwischen Null und Eins, die angibt, bis zu welcher Genauigkeit der Y-Wert berechnet werden soll.

Der Ausgabeparameter "Summe" soll den berechneten Y-Wert enthalten.

Mein Problem ist nun, dass der berechnete Y-Wert nicht richtig ist, und ich habe keine Ahnung warum. Ich hoffe ihr könnt mir weiterhelfen.



Code:
function [Summe] = cosine(x,eps)

if eps<=0
    error('Die Genauigkeit muss größer als Null sein.')
elseif eps>=1
    error('Die Genauigkeit muss kleiner als Eins sein.')
end

k=0;
Summe=0;
Zaehler=1;
Nenner=1;
Quotient=Zaehler/Nenner;

while abs(Quotient)>=eps
   
    Zaehler=((-1)^k)*(x^(2*k));
   
    a=(2*k);                          % Fakultät berechnen
    while a>=1                      %     ''       ''
        Nenner=Nenner*(a);     %     ''       ''
        a=a-1;                         %     ''       ''
    end
   
    Quotient=Zaehler/Nenner;
    Summe=Summe+Quotient;
    k=k+1;

end

disp(Summe)


Dippuff

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 03.06.2014, 17:14     Titel:
  Antworten mit Zitat      
Aha ich konnte das Problem lösen.

Wenn die äußere Schleife mehr als ein Mal durchlaufen wurde, hat die Variable "Nenner" immernoch der Wert vom letzten durchlauf.

Ich habe nun eine Zeile [18] eingefügt, in der der Wert zurückgesetzt wird.

Code:
function [Summe] = cosine(x,eps)

if eps<=0
    error('Die Genauigkeit muss größer als Null sein.')
elseif eps>=1
    error('Die Genauigkeit muss kleiner als Eins sein.')
end

k=0;
Summe=0;
Zaehler=1;
Nenner=1;
Quotient=Zaehler/Nenner;

while abs(Quotient)>=eps
   
    Zaehler=((-1)^k)*(x^(2*k));
    Nenner=1;
   
    a=(2*k);
    while a>=1
        Nenner=Nenner*(a);
        a=a-1;
    end
   
    Quotient=Zaehler/Nenner;
    Summe=Summe+Quotient;
    k=k+1;

end

disp(Summe)
 
Dippuff

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 03.06.2014, 17:23     Titel:
  Antworten mit Zitat      
Bei der Überprüfung der Funktion habe ich nun einen Fehler festgestellt:

Die Funktionswerte stimmen nur bis zu einem X-Wert von etwa 30. Danach werden die Funktionswerte extrem groß.

Ich habe keine Ahnung woran das liegen könnte. Hat jemand eine Idee?


Code:
>> cosine(5 , 0.001);

    0.2836

>> cos(5)

    0.2837

>> cosine(20 , 0.001);

    0.4081

>> cos(20)

    0.4081

>> cosine(30 , 0.001);

    0.1545

>> cos(30)

    0.1543

>> cosine(35 , 0.001);

   -0.9648

>> cos(35)

   -0.9037

>> cosine(40 , 0.001);

  -10.5901

>> cos(40)

   -0.6669

>> cosine(60 , 0.001);

   3.4246e+09

>> cos(60)

   -0.9524

>> cosine(70 , 0.001);
   NaN
 
Dippuff

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 04.06.2014, 13:54     Titel:
  Antworten mit Zitat      
Kann mir hier niemand weiterhelfen ?!
 
Thomas84
Forum-Meister

Forum-Meister


Beiträge: 546
Anmeldedatum: 10.02.10
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 05.06.2014, 06:45     Titel:
  Antworten mit Zitat      
Code:
function [Summe] = cosine(x,eps)

if eps<=0
    error('Die Genauigkeit muss größer als Null sein.')
elseif eps>=1
    error('Die Genauigkeit muss kleiner als Eins sein.')
end

k=0;
Summe=0;
Zaehler=1;
Nenner=1;
Quotient=Zaehler/Nenner;

while abs(Quotient)>=eps
   
    Zaehler=((-1)^k)*(x^(2*k));
    Nenner=1;
   
    a=(2*k);
    while a>=1
        Nenner=Nenner*(a);
        a=a-1;
    end
   
    Quotient(k+1)=Zaehler/Nenner;
   
   
    Summe=Summe+Quotient(k+1);
    k=k+1;

end

plot(Quotient)


disp(Summe - cos(x))


Schau dir doch mal die einzelnen Summanden der Taylor-Reihe an. Mit steigendem x werden die sehr groß. Durch das (-1)^n haben sie zudem ein alternierendes Vorzeichen. Wenn man große Zahlen voneinander abzieht kommt es zu numerischen Ungenauigkeiten.

Beispiel:
Code:
3^34 - (3^34 + 0.01)


viele Grüße
Thomas
Private Nachricht senden Benutzer-Profile anzeigen
 
Dippuff

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 05.06.2014, 16:17     Titel:
  Antworten mit Zitat      
Vielen Dank für die Antwort Thomas.

Bedeutet das, dass die Taylorreihe einfach nicht für große X-Werte geeignet ist?
 
Thomas84
Forum-Meister

Forum-Meister


Beiträge: 546
Anmeldedatum: 10.02.10
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 06.06.2014, 06:20     Titel:
  Antworten mit Zitat      
Ja. Aber du kannst ja die Periodizität ausnutzen und vor die restlichen Berechnungen

Code:


schreiben. Dann tritt das Problem nicht mehr auf.

viele Grüße
Thomas
Private Nachricht senden Benutzer-Profile anzeigen
 
Dippuff

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 08.06.2014, 10:56     Titel:
  Antworten mit Zitat      
Ich versteh nicht so genau wie du das meinst Thomas.
Kannst du das vielleicht kurz erklären, bin noch Anfänger Very Happy
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 09.06.2014, 20:52     Titel:
  Antworten mit Zitat      
Hallo Dippuff,

Die Taylor-Entwicklung ergibt eine Näherungs-Formel um einen bestimmten Punkt herum. Eine Taylorreihe für den X-Wert 0 ist nicht akkurat für die Berechnung beim X-Wert 30.

Nun kannst Du die Periodizität des Cosinus ausnutzen: Statt cos(30) auszurechnen, ist cos(rem(30,2*pi)) besser geeignet, wenn Du eine Taylor-Entwicklung um 0 verwendest.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Dippuffer

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 10.06.2014, 17:24     Titel:
  Antworten mit Zitat      
Ah okay. Oh man, ich habs gecheckt Very Happy
Danke Jungs

 
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.