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 0xffEin 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.707107An 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.000000Danke 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 ********/