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

Wie berechnet man Cumulative Standard Deviation ohne 'for'?

 

clustering_n00b
Forum-Century

Forum-Century


Beiträge: 129
Anmeldedatum: 05.09.11
Wohnort: ---
Version: R2011a, R2012b
     Beitrag Verfasst am: 23.09.2011, 16:51     Titel: Wie berechnet man Cumulative Standard Deviation ohne 'for'?
  Antworten mit Zitat      
Hallo zusammen!

Habe ein ganz banales Problem für euch.
Ich die kumulative/progressive Standardabweichung, i.e. cumulative/progressive standard deviation berechnen, und zwar ohne die lästigen for-loops.

Mit for-loops habe ich es so gemacht:
Code:

function [cummean variationa variationb] = cumvalues(x)

    N = length(x);
    cummean = cumsum(x)./[1:N];

    var = NaN(N, 1);
    std = NaN(N, 1);
   
    for i=1:N
       
       var(i) = 0;
       for k = 1:i
            var(k) = (x(k)-cummean(k))^2 + var(k);
       end
       var(i) = var(k)/i;
       std(i) = sqrt(var(i));
       
    end
   
    cummean = cummean';
    variationa = cummean + std;
    variationb = cummean - std;
   
end
 



Wie geht's denn ohne for-loops? Kann man es so ähnlich machen mit einer direkten Formel wie ich es für cummean gemacht habe?


Freue mich auf Ansätze Very Happy
Private Nachricht senden Benutzer-Profile anzeigen


Harald
Forum-Meister

Forum-Meister


Beiträge: 24.492
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 23.09.2011, 21:19     Titel:
  Antworten mit Zitat      
Hallo,

Google hilft:
http://www.mathworks.com/matlabcent.....sreader/view_thread/97185

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
clustering_n00b
Themenstarter

Forum-Century

Forum-Century


Beiträge: 129
Anmeldedatum: 05.09.11
Wohnort: ---
Version: R2011a, R2012b
     Beitrag Verfasst am: 24.09.2011, 07:45     Titel:
  Antworten mit Zitat      
Hallo Harald!

Danke für deine Antwort! Very Happy

Diesen Beitrag hatte ich schon gesehen, allerdings ist der Code nicht richtig

Code:

n=10;
x = 1:n;
cummean = cumsum(x)./(1:n);
cumstd = sqrt((cumsum(x.^2) - (1:n).*cummean.^2)./(0:(n-1)));
cumstd(1) = 0;
 


Beispiel:
x = [1 2 3 4 .... 10]
cummean = [1 1.5 2 2.5 ... 5.5]

Soweit ist alles richtig.
Für cumstd sollte jetzt (von Hand verifiziert):
[ 0.5000
0.8165
1.1180
1.4142
1.7078
2.0000
2.2913
2.5820
2.8723 ]
rauskommen.

Das tut es aber nicht Confused

Sieht jemand den Fehler? Question



PS: Die for-Loop Lösung oben ist falsch. Richtig lautet es:
Code:

    N = length(x);
    cummean = cumsum(x)./(1:N);

    var = NaN(N, 1);
    std = NaN(N, 1);
   
    for i=1:N
       
       sum = 0;
       for k = 1:i            
            sum = (x(k)-cummean(i))^2 + sum;
       end
       var(i) = sum/i;
       std(i) = sqrt(var(i));
       
    end
 
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.492
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 24.09.2011, 09:13     Titel:
  Antworten mit Zitat      
Hallo,

in dem Link wird nur anders skaliert. John macht:

Code:
sqrt((cumsum(x.^2) - (1:n).*xbar.^2)./(0:(n-1)))


Das deckt sich auch mit dem letzten Absatz von
http://de.wikipedia.org/wiki/Standardabweichung

Du willst stattdessen anscheinend:
Code:
sqrt((cumsum(x.^2) - (1:n).*xbar.^2)./(1:n))


Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
clustering_n00b
Themenstarter

Forum-Century

Forum-Century


Beiträge: 129
Anmeldedatum: 05.09.11
Wohnort: ---
Version: R2011a, R2012b
     Beitrag Verfasst am: 24.09.2011, 11:03     Titel:
  Antworten mit Zitat      
Hat funktioniert!!!

Vielen Dank!! Laughing


Aber wieso hat er anders skaliert? Mit einer anderen Skalierung (= falsche Formel) bekommt man ja einen falschen Wert?!
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.492
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 24.09.2011, 18:17     Titel:
  Antworten mit Zitat      
Hallo,

ich würde sagen, man bekommt unterschiedliche Werte. Beide Werte sind ein Maß für die Streuung der Daten.

Die Skalierung ist dieselbe wie in der Formel in Wikipedia.
Kann es sein, dass du eventuell "falsch" skaliert hast?

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
clustering_n00b
Themenstarter

Forum-Century

Forum-Century


Beiträge: 129
Anmeldedatum: 05.09.11
Wohnort: ---
Version: R2011a, R2012b
     Beitrag Verfasst am: 25.09.2011, 21:00     Titel:
  Antworten mit Zitat      
Ok, ich hab's jetzt glaube ich begriffen Smile

Nochmals vielen Dank! Very Happy
Private Nachricht senden Benutzer-Profile anzeigen
 
clustering_n00b
Themenstarter

Forum-Century

Forum-Century


Beiträge: 129
Anmeldedatum: 05.09.11
Wohnort: ---
Version: R2011a, R2012b
     Beitrag Verfasst am: 29.09.2011, 12:39     Titel:
  Antworten mit Zitat      
Ok, jetzt im Nachhinein habe ich was bemerkt...

Und zwar bekomme ich mit dem angegebenen Code auch negative Varianzen und dementsprechend komplexe Standardabweichungen Question

Da stimmt doch was nicht mit der Formel..
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.492
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 29.09.2011, 12:52     Titel:
  Antworten mit Zitat      
Code-Beispiel dafür?

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
clustering_n00b
Themenstarter

Forum-Century

Forum-Century


Beiträge: 129
Anmeldedatum: 05.09.11
Wohnort: ---
Version: R2011a, R2012b
     Beitrag Verfasst am: 29.09.2011, 15:00     Titel:
  Antworten mit Zitat      
Also die Funktion cumvalues sieht folgendermassen aus:

Code:

function [cummean variationa variationb] = cumvalues(x)


N = length(x);


cummean = cumsum(x)./(1:N)
cumvar = (cumsum(x.^2) - (1:N). * cummean. ^ 2)./(1:N)
cumstd sqrt(cumvar)
cumstd(1) = 0;

variationa = cummean + cumstd:
variationb = cummean - cumstd:

 



Beim folgenden Beispiel hat's gehappert:

Code:
x = 0.4294 * ones(8)
-->
cummean = 0.4294 * ones(8)
cumvar = 1.0e-15 * [0 0 0 0 -0.044 -0.0740 -0.0952 -0.1110 -0.1234 -0.1332]
cumstd = 1.0e-07 * [0 0 0 0 0+0.0666i 0+0.086i 0+0.0976i ... etc.]



Sieht jemand was falsch gelaufen ist?
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.492
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 29.09.2011, 19:53     Titel:
  Antworten mit Zitat      
Hallo,

wenn die Werte alle gleich sind, wären Varianz bzw. Standardabweichung beide 0. Bei numerischen Berechnungen die 0 genau zu treffen, ist nahezu unmöglich (und das ist im übrigen von der Programmiersprache unabhängig so). Beispiele:
Code:
0.1 + 0.1 + 0.1 - 0.3
sin(pi)


In dem Link, den wir uns angeschaut haben, ist übrigens erwähnt, dass die Lösung aus numerischer Sicht nicht empfehlenswert ist.

Meine Empfehlung wäre eine kleine Anpassung des Codes:
Code:
cumstd = sqrt(max(cumvar,0))


Man muss sich allerdings darüber im klaren sein, dass es bei der Berechnung von im Vergleich zur Größe sehr kleine Varianzen (und 0 ist nunmal im Verhältnis zu allem *sehr* klein) zu Ungenauigkeiten kommen kann.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
clustering_n00b
Themenstarter

Forum-Century

Forum-Century


Beiträge: 129
Anmeldedatum: 05.09.11
Wohnort: ---
Version: R2011a, R2012b
     Beitrag Verfasst am: 30.09.2011, 07:22     Titel:
  Antworten mit Zitat      
Hm.. das erstaunt mich jetzt, dass MATLAB numerisch so ungenau ist.
Liegt der Fehler nicht immer um 0 herum? Also -0.14, -0.2, usw.
Aber nicht irgendwie -40 oder so?

Dänn wäre die Aufrundung auf 0 noch akzeptabel.

Sonst...
Macht es da nicht doch mehr Sinn die for-Schleifen zu benutzen?
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 30.09.2011, 09:00     Titel:
  Antworten mit Zitat      
Hallo clustering_n00b,

MATLAB is so genau wie alle Programme, die die standardisierte IEEE754 Floating-Point-Arithmetik verwenden, also z.B. Fortran, C, C++, C#, Java, Basic, ... Siehe http://de.wikipedia.org/wiki/IEEE_754.
Die Benutzung von Schleifen ändert daran nichts.

CUMSUM verwendet genauso wie SUM einen 64-bit Akkumulator, der eine eingeschränkte Genauigkeit hat:
Code:
x = [1e16, 1e0, -1e16];
sum(x)       % >> 0, instead of the correct 1
cumsum(x)  % >> [1e16, 1e16, 0]

Zwar können moderne Prozessoren die Zwischenwerte auch in 80-Bit registern speichern, das wird aber z.B. nicht von den Microsoft MSVC compilern unterstützt. In der FEX gibt es eine funktion, um die Summe mit 64, ~72, 128 und 196 bit Genauigkeit zu berechnen: http://www.mathworks.com/matlabcentral/fileexchange/26800-xsum. Das ist für numerische Analysen wichtig, für den alltäglichen Gebrauch aber nicht. Die Nutzung von Floating Point Zahlen hat einfach nur eine begrenzte "Precision", und dadurch wird die "Accuracy" eines Algorithmus' beschränkt. Dies muss in jeder numerischen Software berücksichtigt werden.

Nebenbei sei bemerkt, dass dies sogar für die physikalische Realität gilt: Die Quantenmechanik stellt ebenfalls eine Begrenzung der "Precision" dar: Man kann z.B. keine Teilchen durch unendlich kleine Löcher schießen oder sie unbewegt an einem exakt bestimmten Ort festhalten. Die eingeschränkte "Precision" ist also nicht irgendwie besonders künstlich, sondern entspricht im gewissen Grad der physikalischen Natur.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.492
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 30.09.2011, 09:29     Titel:
  Antworten mit Zitat      
Hallo,

ich möchte noch einmal betonen, dass dies unabhängig von der Programmiersprache so ist. Der Fehler wird relativ zum Quadrat der Größen, mit denen du rechnest, wahrscheinlich sehr klein sein - in der Größenordnung von 1e-14, was die Varianzen angeht.
Bei den Standardabweichungen dürfte der Fehler in der Größenordnung von 1e-7 relativ zu den Größen, mit denen du rechnest, sein.
Wenn du mit sehr großen Zahlen rechnest, werden also auch die Fehler sehr groß sein. Probiers mal mit:
Code:
x = 0.4294e50 * ones(1,8)
Vorhersage: Fehler in Varianz bei 1e(2*50 - 14) = 1e86
Fehler in Standardabweichung bei 1e(50-7) = 1e43

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
clustering_n00b
Themenstarter

Forum-Century

Forum-Century


Beiträge: 129
Anmeldedatum: 05.09.11
Wohnort: ---
Version: R2011a, R2012b
     Beitrag Verfasst am: 01.10.2011, 16:13     Titel:
  Antworten mit Zitat      
Ok... die technischen Details waren mir gar nicht bewusst.
Macht jetzt Sinn.
Ich habe deine max-Variante benutzt und es hat wunderbar geklappt Smile

Etlichen Dank Very Happy
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.