Standardabweichung, mittlere Abweichung und arithmetrischer Mittelwert



  • Probiers mal mit diesem kleinen Programm, das sollte dir alle nötigen statistischen Daten für beliebig viele Werte liefern. Wir haben es inzwischen durch eine C++ Klasse, die noch weitere Werte ermittelt, ersetzt, da wir dann das initialisieren über den Konstruktor machen lassen, und es somit niemand vergisst und sich dann über die Ergebnisse wundert.
    Wenn du TESTMAIN auskommentierst kannst du es als Unterorutinen in dein Programm einbinden.

    #define TESTMAIN
    #include <math.h>
    #include "values.h"
    typedef struct
    {
    double ANZAHL  ; double SUMME   ; double QUADSM  ; double MW      ;
    double QUDEMI  ; double STDN    ; double STDN1   ; double VAR     ;
    double _1SIG   ; double _2SIG   ; double _3SIG   ; double RMS     ;
    double MIN     ; double MAX     ; double AMAX    ; 
    } Calcstat;
    
    int CalcStat( double xi , Calcstat *res );
    int CalcStatInit(Calcstat *res);
    
    /**************************************************************************.FA*
     .FUNCTION [CalcStatInit]
    -------------------------------------------------------------------------------
     .DESCRIPTION
      initialisation of the statitiks package, all relvant data of the res structure
      will be initialised.
      It can also be used to reset the complete statitiks data to initial state.
    -------------------------------------------------------------------------------
     .PARAMETER 
      INPUT:   Calcstat *res
      OUTPUT:  Calcstat *res Setted to correct Statvalues
    -------------------------------------------------------------------------------
     .RETURNVALUE
      0 allways
    -------------------------------------------------------------------------------
     .HISTORY
      Date	     Author		 Comment
      07.09.1997 PAD /DDT
    *************************************************************************.HE**/
    int CalcStatInit(Calcstat *res)
    {
      res->ANZAHL  =0.0L;   res->SUMME   =0.0L;   res->QUADSM  =0.0L;   res->MW      =0.0L;
      res->QUDEMI  =0.0L;   res->STDN    =0.0L;   res->STDN1   =0.0L;   res->VAR     =0.0L;
      res->_1SIG   =0.0L;   res->_2SIG   =0.0L;   res->_3SIG   =0.0L;   res->RMS     =0.0L;
      res->MIN     =MAXDOUBLE;
      res->MAX     =-MAXDOUBLE;
      res->AMAX    =-MAXDOUBLE;
      return 0;
    }
    /************************************************************************.FE**/
    
    /**************************************************************************.FA*
     .FUNCTION [CalcStat]
    -------------------------------------------------------------------------------
    .DESCRIPTION
      This routine does some statitiscs on the input data.
      This function must be called for every new value which gets part of the statistiks.
      on return the aktual statitikal values will be present. The names are selfdecaring
      so the will not be listed here.
      The resultstructure ist passed by reference so you can have several statistiks
      running in parallel if you define different result structures for each. The result
      structure is also be used to keep the intermediate results, therefore it is forbidden
      to change it elsewhere.
      The routine CalcStatInit must be called before the first call to this routine.
      An example for the usage you can see in the part TESTMAIN
    -------------------------------------------------------------------------------
     .PARAMETER
      INPUT:   double xi	the value to be added to the statistiks
      OUTPUT :   Calcstat *res  the resultstructure containing the results and the intermediate
      values for this set of data.
    -------------------------------------------------------------------------------
     .RETURNVALUE
      0 if everything is ok
      1 if there are not enough values to calculate the statistik
    -------------------------------------------------------------------------------
     .HISTORY
      Date	     Author		 Comment
      07.09.1997 PAD /DDT
    *************************************************************************.HE**/
    int CalcStat( double xi , Calcstat *res )
    {
      double temp;
      temp=fabs(xi);
      res->ANZAHL++;
      res->SUMME+=xi;				 /**********  Summe xi	   ********/
      res->QUADSM +=(xi*xi);			 /**********  Summe xi^2   ********/
      res->MW=res->SUMME/(res->ANZAHL);		 /**********  Mittelwert   ********/
      res->QUDEMI =(res->MW*res->MW*res->ANZAHL);	 /**********  Quadr der MW ********/
      if (0 <(res->QUADSM /res->ANZAHL));
      res->RMS=sqrt(res->QUADSM /res->ANZAHL);	 /**********  RMS	 ********/
      if (xi > res->MAX)				 /**********  groesster MessW *****/
        res->MAX=xi;
      if (temp > res->AMAX) 			 /**********  |groesster MessW| *****/
        res->AMAX=temp;
      if (xi < res->MIN)				 /**********  kleinster MessW *****/
        res->MIN =xi;
      if(res->ANZAHL>1)
      {
        if (0<(res->QUADSM - res->QUDEMI))
        {
          res->STDN=sqrt((res->QUADSM -(res->QUDEMI))/(res->ANZAHL));    /********** Standardabw.  ****/
          res->STDN1=sqrt((res->QUADSM -(res->QUDEMI))/(res->ANZAHL-1)); /********** Standardabw. (n-1) ****/
        }
        if (0< (res->QUADSM - res->MW * res->MW ))
          res->VAR=(res->QUADSM - res->MW * res->MW * res->ANZAHL)/res->ANZAHL;   /**********  Varianz     ********/
        if (0<res->VAR)
        {
          res->_1SIG=sqrt(res->VAR);		 /**********  Sigma 1  ********/
          res->_2SIG=sqrt(2.0*res->VAR);		 /**********  Sigma 2  ********/
          res->_3SIG=sqrt(3.0*res->VAR);		 /**********  Sigma 3  ********/
        }
        return(0);
      }
      return 1;
    }
    #ifdef TESTMAIN
    main()
    {
      int i;
      Calcstat    res;
      CalcStatInit(&res);
      for (i=1;i<4;i++)
        CalcStat ((double)i , &res);                    // Sollwerte
      printf("Anzahl              = %lf\n",res.ANZAHL); // Anzahl	           = 3.000000
      printf("Summe               = %lf\n",res.SUMME ); // Summe 	           = 6.000000
      printf("Summe der Quadrate  = %lf\n",res.QUADSM); // Summe der Quadrate  = 14.000000
      printf("Mittelwert          = %lf\n",res.MW    ); // Mittelwert	   = 2.000000
      printf("Quadrat der Mittelw.= %lf\n",res.QUDEMI); // Quadrat der Mittelw.= 12.000000
      printf("Standartabweichnung = %lf\n",res.STDN  ); // Standartabweichnung = 0.816497
      printf("Standartabw.(n-1)   = %lf\n",res.STDN1 ); // Standartabw.(n-1)   = 1.000000
      printf("Varianz             = %lf\n",res.VAR   ); // Varianz	           = 0.666667
      printf("1 sigma             = %lf\n",res._1SIG ); // 1 sigma	           = 0.500000
      printf("2.sigma             = %lf\n",res._2SIG ); // 2.sigma	           = 0.707107
      printf("3.sigma             = %lf\n",res._3SIG ); // 3.sigma	           = 1.414214
      printf("RMS                 = %lf\n",res.RMS   ); // RMS	           = 2.160247
      printf("MAX                 = %lf\n",res.MAX   ); // Max                 = 3.000000
      printf("MIN                 = %lf\n",res.MIN   ); // Min                 = 1.000000
      printf("Maximum Betrag      = %lf\n",res.AMAX  ); // abs(Max)            = 3.000000
      printf("\n");
    return 0;
    }
    #endif
    


  • Was hat es mit diesem res-> auf sich und wie kann ich mit Schleifen Summen benutzen?
    Und nein, Beträge kriege ich nicht hin.



  • in dem Stück was mit main beginnt, ist ein Beispiel für die Benutzung.

    Es werden in einer Schleife die Zahlen 1,2,3 als Messwerte an die Statistikroutine übergeben.

    Anschließend werden die Ergebnisse der Statistik die dich interessiern unter zu Hilfe name von printf ausgedruckt.

    Das interessante an dem Verfahren ist, das du nicht durch irgendwelche Feldgrößen eingeschränkt wirst. und bei Bedarf nach jedem Messwert, den kompletten Statistiksatz zur Verfügung hast.



  • Jasper schrieb:

    Was hat es mit diesem res-> auf sich und wie kann ich mit Schleifen Summen benutzen?
    Und nein, Beträge kriege ich nicht hin.

    Hast du schonmal darüber nachgedacht vielleicht ein Tutorial oder ein Buch zu benutzen?

    Was ist denn ein Betrag? Der Betrag |z| ist z wenn z >= 0 und -z wenn z < 0. Prima, das können wir sofort runterschreiben:

    if(z < 0)
      betragZ = -z;
    else
      betragZ = z;
    

    Wir können aber auch die dafür vorgesehene Funktion aus der Standard-Library benutzen.

    betragZ = abs(z);
    


  • Jasper schrieb:

    Was hat es mit diesem res-> auf sich und wie kann ich mit Schleifen Summen benutzen?
    Und nein, Beträge kriege ich nicht hin.

    Dann empfehle ich dir erstmal nen C-Kurs zu machen, davon gibts oben rechts bei tutorials ne Menge. Der Betrag ist eine der Grundfunktionen. Wenn du noch nicht einmal weisst, dass man eine Summe mit einer Schleife machen kann, dann fehlt dir da immenses Grundwissen. Und ohne das bringen dir die Snippets hier auch nix.



  • Hallo,

    Ich habe versucht die Funktionen zu benutzten.

    Mein BCB6 sagt jedoch

    [C++ Fehler] UnStat.cpp(33): E2451 Undefiniertes Symbol 'MAXDOUBLE'

    Wo, und als was sollte MAXDOUBLE deklariert werden ???
    In der Math.h ist sie auch nicht drin.

    Wie kann ich diese Problem lösen ???

    Grüße



  • C_Bernd schrieb:

    Wo, und als was sollte MAXDOUBLE deklariert werden ???
    In der Math.h ist sie auch nicht drin.

    Wie kann ich diese Problem lösen ???

    Grüße

    in der values.h



  • MAXDOUBLE ist die größte als double darstellbare Zahl im floating point format.
    siehe unten. Früher standen diese Werte in values.h "BC 3.1" in VC konnte ich sie nicht finden und hab sie in einer
    meiner Standard Defintionsdateien dazudefiniert

    #define MAXDOUBLE 1.797693E+308
    #define MAXFLOAT 3.37E+38
    #define MINDOUBLE 2.225074E-308
    #define MINFLOAT 8.43E-37

    #define MAXINT64 (9223372036854775807i64)
    #define MININT64 (-9223372036854775807i64 - 1)
    #define MAXINT32 2147483647L
    #define MININT32 (-2147483647L - 1)
    #define MAXINT16 32767
    #define MININT16 (-32768)
    #define MAXINT8 127
    #define MININT8 (-128)
    #define UMAXINT32 0xffffffffUL
    #define UMAXINT16 0xffff
    #define UMAXINT8 0xff

    Ein Teil der Werte findet sich bei VC 6 in limits.h wieder, die float defines leider nicht



  • Hallo und Vielen Dank erstmal,

    eine Frage habe ich noch:

    Die angegebenen Sollwerte für 1.Sigma und 2.Sigma stimmen nicht mit denen die bei mir errechnet werden überein !!!

    Meine Werte: auskommentierte Sollwerte:
    -----------------------------------------------------
    0,816496580927726 1 sigma 0.500000
    1,15470053837925 2.sigma 0.707107

    An was liegt der Fehler ist dies nur bei mir so, oder stimmen die "Sollwerte" nicht ??



  • Das waren Fehler in den Sollwert Kommentaren:
    Hier noch mal eine aktuelle Berechnung
    Anzahl = 3.000000
    Summe = 6.000000
    Summe der Quadrate = 14.000000
    Mittelwert = 2.000000
    Quadrat der Mittelw.= 12.000000
    Standartabweichnung = 0.816497
    Standartabw.(n-1) = 1.000000
    Varianz = 0.666667
    1 sigma = 0.816497
    2.sigma = 1.632993
    3.sigma = 2.449490
    RMS = 2.160247
    MAX = 3.000000
    MIN = 1.000000
    Maximum Betrag = 3.000000

    Danke für den Hinweis, leider ist mir dabei ein anderer Fehler in den sigma Berechnungen aufgefallen
    Diese zwei Zeilen:

    res->_2SIG=sqrt(2.0*res->VAR);         /**********  Sigma 2  ********/
          res->_3SIG=sqrt(3.0*res->VAR);         /**********  Sigma 3  ********/
    

    müssen ersetzt werden durch

    res->_2SIG=2.0* res->_1SIG;         /**********  Sigma 2  ********/
          res->_3SIG=3.0* res->_1SIG;         /**********  Sigma 3  ********/
    

Anmelden zum Antworten