Standardabweichung, Varianz <=Rundungsfehler



  • das ist ja gar nicht so schwer wie ich dachte aber, wenn ich mit Excel die Angaben ausrechne bekomm ich ganz schöne ungenauigkeiten, die sich durch quadrieren halt ganz schön aufsummieren!!
    z.B. Hab ich für die Varianz

    in Excel 877823607,1
    und in meinem Prog 877818418.34157133
    Wo kommt die ungenauigkeit her?
    Hier mal meine FKTen:

    double CWavealyzeDoc::Standardabweichung(fstream Wavefile)
    {
    	unsigned long n = getAnzahlSamples(Wavefile);
    	long double SummeX = SummeSamples(Wavefile,0,n);
    	long double SummeXquadrat = SummeSamplesQuadrat(Wavefile,0,n);
    	double StdAbw = sqrt((n*SummeXquadrat-(SummeX*SummeX))/(n*(n-1)));
    
    	return StdAbw;
    }
    
    double CWavealyzeDoc::Varianz(fstream Wavefile)
    {
    	unsigned long n = getAnzahlSamples(Wavefile);
    	long double SummeX = SummeSamples(Wavefile,0,n);
    	long double SummeXquadrat = SummeSamplesQuadrat(Wavefile,0,n);
    	double Varianz = (n*SummeXquadrat-(SummeX*SummeX))/(n*(n-1));
    
    	return Varianz;
    }
    
    long double CWavealyzeDoc::SummeSamples(fstream Wavefile, unsigned long StartSample, unsigned long EndSample)
    {
    	unsigned long * pData=0;
    	long double  Summe = 0;
    	if(Samples_to_intArray(Wavefile, pData,StartSample,EndSample,"links"))
    	{
    		for (unsigned long i = 0; i<=getAnzahlSamples(Wavefile);i++)
    		{
    			Summe += pData[i];
    		}
    	}
    return Summe;
    }
    long double CWavealyzeDoc::SummeSamplesQuadrat(fstream Wavefile, unsigned long StartSample, unsigned long EndSample)
    {
    	unsigned long* pData=0;
    	long double Summe = 0;
    	if(Samples_to_intArray(Wavefile, pData,StartSample,EndSample,"links"))
    	{
    		for (unsigned long i = 0; i<=getAnzahlSamples(Wavefile);i++)
    		{
    			Summe += pData[i]*pData[i];
    		}
    	}
    return Summe;
    }
    


  • Kann mir keiner sagen ob ich ungenau bin oder ob das ungenaue von Excel kommt. Ich würde es ja gern mal von Hand nachrechnen, aber die große ungenauigkeit tritt halt erst auf wenn ich mal ne gute Anzahl Werte hab die ich aufsummieren muss. Und in genanntem Besipiel wären das knapp ü+ber 34000
    Wo passiert diese ungenauigkeit??



  • Was anderes als selber nachrechnen wüßte ich jetzt nicht.

    Ich habe schon nach dem beliebtesten Ungenauigkeitsfehler geguckt, habe ihn aber nirgends gefunden:
    Man muss immer erst große Zahlen erzeugen bevor man sie dividiert. Sonst gibt das schnell fette Rundungsfehler.

    Ich bin leider in Mathe nicht so fit.
    Vielleicht solltest du den Threadtitel mal so ändern, dass Leute reingucken, die sich mit Rundungsfehlern auskennen.
    Und ein Matheforum gibt es hier für alle Fälle auch noch.



  • Sag uns erstmal was das mit MFC/Visual C++ zu tun hat. 🤡 🤡 🤡 🤡



  • lol? schrieb:

    Sag uns erstmal was das mit MFC/Visual C++ zu tun hat. 🤡 🤡 🤡 🤡

    Stimmt irgendwie...

    Polofreak: Wenn du in ein anderes Forum geschoben werden möchtest, dann sag es. 🙂
    So auf Anhieb weiß ich aber leider nicht, wo hier die Matheasse sitzen.



  • lol? schrieb:

    Sag uns erstmal was das mit MFC/Visual C++ zu tun hat. 🤡 🤡 🤡 🤡

    Naja angefangen hat es ja mit: "Ich hab keine Ahnung wie das geht, vielleicht gibt es ja in der MFC fertige bzw nutzbare Funktionen."
    Drum hier im MFC Forum.

    Aber mittlerweile ist es wirklich eher das Rundungsproblem. Drum wäre es mittlerweile besser im Mathe-Forum aufgehoben. Estartu, wärst du so lieb und blinzelst mich rüber? So per Astral-Projektion? 😉



  • Dieser Thread wurde von Moderator/in estartu_de aus dem Forum MFC (Visual C++) in das Forum Mathematik verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Klaro. 🙂
    Viel Erfolg hier.



  • Danke schön ich hoffe hier kann mir einer helfen.
    Es wird sich raus stellen.



  • wenn du maple oder octave zur hand hast: rechne doch dort mal nach. ansonsten der gute alte taschenrechner kanns auch 🙂 auf das ergenis von excel würd ich nicht so viel geben...



  • Ich würde eher Excel vertrauen als einem Ergebnis, das beim Rechnen mit Fließkommavariablen entstanden ist. Wie groß sind denn die Werte, die dabei als Zwischenergebnis rauskommen? Würde ein 64Bit-Integer ausreichen?



  • klar kann es der gute alte TR doch hab ich ehrlich gesagt nicht die lust 34782 Werte in den TR zu tippen! Maple oder ähnliches hab ich leider nicht da. Ist jemand hier dem ich mal die Werte schicken darf?



  • Wobei: wenn man wirklich viele Meßwerte hat, dann bekommt man oft ziemliche numerische Ungenauigkeiten. Aber 35000 ist jetzt nicht soo viel.

    double Varianz = (n*SummeXquadrat-(SummeX*SummeX))/(n*(n-1));
    

    Stimmt das denn überhaupt?

    Es gilt der Verschiebungssatz: Var(X)=E(X2)-E(X)2 mit E=Σ x_i W(x_i). Offenbar ist bei dir W(x_i) = 1/n (wobei n gleich Anzahl der Meßwerte), also

    Var(X) = 1/n (Σ x_i^2) - 1/n^2 (Σ x_i)^2 = 1/n (SummeXquadrat - 1/n SummeX*SummeX)

    Kann aber sein, daß ich jetzt danebenliege. Wie hast Du deinen Ausdruck hergeleitet?



  • Hallo Polofreak,

    z.B. Hab ich für die Varianz

    in Excel 877823607,1
    und in meinem Prog 877818418.34157133
    Wo kommt die ungenauigkeit her?

    Woher willst Du wissen, dass Excel recht hat? Vielleicht ist das ja ungenau.
    Sicherheitshalber solltes Du alle double als long machen, auch die Rückgabewerte der ersten beiden Funktionen. Es könnte sein, daß alle Variablen Deiner Formel erstmal auf double verkleinert werden, bevor sie in die Formel eingerechnet werden. Also rechne erstmal Deine Varianz mit long double aus.

    Dann sehn wir mal weiter.

    mfG
    rudiS



  • hergeleitet hab ich den Ausdruck eigentlich mehr oder weniger gar nicht ich hab einfach in der Excel-Hilfe (F1) nach Varianz gesucht und dann die Formel die dort steht versucht nachzubilden (also doch hergeleitet). Ich pack mal alles in long doubles, wobie ich mir nicht vorstellen kann, dass es das ist, da ich 1. dann ganz andere Ungenauigkeiten rein bekommen würde, 2. jedes mal was anderes raus bekommen würde wenn ich wirklich nen Buffer overflow hätte und 3. selbst double ausreichen sollte. Aber ich werde es dennoch probieren.



  • OK auch mit long double tut sich nichts in der Genauigkeit. Kann mir einer von euch mal ne (allgemeine) Formel für das zentrale moment nennen? Es gibt scheinbar zig verschiedene, ich brauch eine Formel die möglichst wenig Rechenaufwand benötigt, denn wie gesagt hab ich einige Werte und zum anderen muss ich das alles in der Taktzeit eines Testers schaffen.
    Vielen Dank schon mal für die Hilfe



  • Nochmal zur Standardabweichung: Das Problem scheint zu sein, daß die Differenzen von großen Zahlen nicht stabil ist, ich habe auch eben mal von 32000 Werten die Standardabweichungen mit einer naiven C-Implementierung und mit OpenOffice verglichen. Die C-Implementierung liefert deutlich andere Ergebnisse. Darum: nicht naiv implementieren.
    http://www.stanford.edu/~glynn/PDF/0208.pdf

    Die Kapitel für Statistik aus den Numerical Recipes könnten auch interessant sein: http://www.library.cornell.edu/nr/bookcpdf.html

    BTW: Meine und deine Formel unterscheiden sich für den Grenzfall n->oo überhaupt nicht und ansonsten ist deine eine etwas bessere Näherung für die Varianz aus empirischen Werten.

    Zum statistischen Moment: Allgemein gilt:
    Moment_k(X) = E([X-m]^k)

    In Worten von C gibt das für deinen Anwendungsbereich (naive Implementierung, ld=long double):

    ld moment(ld *x, int nmemb, ld mu, int k) {
       int i;
       ld sum = 0;
    
       for (i = 0; i < nmemb; ++i) sum += pow(x[i]-mu, k);
    
      return sum/nmemb;
    }
    

    Wenn k gleich 1 und mu gleich 0 ist, dann bekommst Du gerade den Erwartungswert. Ist k zwei und mu der Erwartungswert, dann bekommst Du die Varianz. Jetzt kannst Du einfach k immer weiter erhöhen und bekommst auch die Momente höherer Ordnungen der Verteilung.



  • Probiert einmal dieses Stück Code aus um etwas über die Genauigkeit der float typen zu erfahren, und dann kann man sich mal gedanken über die Genauigkeit von Excel machen

    #include <stdio.h>
    // #define NUMBERS 10000 diesen Wert für float einsetzen
    #define NUMBERS 1000000000 // double und long double werden in MSVC 6.0 gleich behandelt
    int main()
    {
        float a;
        double b;
        long double c;
        long int i;
        a=b=c=0.0;
        FILE *fp;
        fp=fopen("pad.pad","wt"); // no error handling
        for (i=1;i<= NUMBERS;i++)
        {
            a=a+i;  b=b+i;  c=c+i;
        }
        printf("Methode A a=%.16f b=%.16lf c=%.16lf\n",a,b,c);
        fprintf(fp,"Methode A a=%.16f b=%.16lf c=%.16lf\n",a,b,c);
    
        a=b=c=0.0;
        for (i=NUMBERS;i>0;i--)
        {
            a=a+i;  b=b+i;    c=c+i;
        }
        printf("Methode B a=%.16f b=%.16lf c=%.16lf\n",a,b,c);
        fprintf(fp,"Methode B a=%.16f b=%.16lf c=%.16lf\n",a,b,c);
        fclose (fp);
        return 0;
    }
    

    // #define NUMBERS 10000 diesen Wert für float einsetzen
    Methode A a=50002896.0000000000000000 b=50005000.0000000000000000 c=50005000.0000000000000000
    Methode B a=50009072.0000000000000000 b=50005000.0000000000000000 c=50005000.0000000000000000

    #define NUMBERS 1000000000 // double und long double werden in MSVC 6.0 gleich behandelt
    Methode A a=18014398509481984.0000000000000000 b=500000000067108990.0000000000000000 c=500000000067108990.0000000000000000
    Methode B a=18014398509481984.0000000000000000 b=500000000995475710.0000000000000000 c=500000000995475710.0000000000000000

    Die 16 Stellen nach dem Komma wurden bewußt gewählt um Rundungsfehler früh zu sehen



  • HI Danke für eure antworten, mir ist so einiges Klar geworden

    @ Daniel E.: Die Links sind Klasse! Vielen Dank sowohl für die Links als auch für die FKTs mein riesen Problem war sehr grundsätzlich, ich nahm an dass das 3. zentrale Moment der Schiefe entspricht 😮 naja jetzt weiß ich dass man nicht alles glauben darf was einem Dr.Google erzählt (wußte ich eigentlich auch davor) wenn ich nun über meine zentralen Momente Schiefe Kurtosis etc. Berechne liegt der Wert zwischen meinen bisherigen Werten und den Excel-Werten. Alles in allem bin ich meist kleine 0,09% Abweichung, und ich denke diese Ungenauigkeit werde ich nicht suchen und mit den errechneten Werten nun weiter rechnen. Falls es noch Probleme geben sollte, werde ich mich nochmal melden, ich denke aber dass nun alles soweit klar ist. Vielen Dank!!!!



  • Polofreak schrieb:

    Vielen Dank sowohl für die Links als auch für die FKTs mein riesen Problem war sehr grundsätzlich, ich nahm an dass das 3. zentrale Moment der Schiefe entspricht

    ?? Das stimmt auch. Das ist der Spezialfall meiner Funktion mit k=3 und mu als dem Erwartungswert. Mit meiner Funktion kannst Du beliebige Momente für gleichverteilte Zufallsfunktionen ausrechnen.


Anmelden zum Antworten