00001 #ident "$Header: /home/cvsuser/cvsroot/JSOC/proj/lev1.5_hmi/libs/lev15/fstats.c,v 1.2 2011/11/23 21:53:56 couvidat Exp $"
00002
00003
00004
00005 #include <stdlib.h>
00006 #include <math.h>
00007 #include <float.h>
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #define SWAP(a,b) temp=(a);(a)=(b);(b)=temp;
00018
00019 static double median(int n, float arr[])
00020 {
00021 int k, i, ir, j, l, mid;
00022 float a, temp;
00023
00024 if (n < 1)
00025 return __builtin_nan("");
00026
00027 k = n / 2;
00028 l = 0;
00029 ir = n - 1;
00030 for (;;) {
00031 if (ir <= l + 1) {
00032 if (ir == l + 1 && arr[ir] < arr[l]) {
00033 SWAP(arr[l], arr[ir])
00034 }
00035 return (double) arr[k];
00036 } else {
00037 mid = (l + ir) >> 1;
00038 SWAP(arr[mid], arr[l + 1])
00039 if (arr[l] > arr[ir]) {
00040 SWAP(arr[l], arr[ir])
00041 }
00042 if (arr[l + 1] > arr[ir]) {
00043 SWAP(arr[l + 1], arr[ir])
00044 }
00045 if (arr[l] > arr[l + 1]) {
00046 SWAP(arr[l], arr[l + 1])
00047 }
00048 i = l + 1;
00049 j = ir;
00050 a = arr[l + 1];
00051 for (;;) {
00052 do
00053 i++;
00054 while (arr[i] < a);
00055 do
00056 j--;
00057 while (arr[j] > a);
00058 if (j < i)
00059 break;
00060 SWAP(arr[i], arr[j])
00061 }
00062 arr[l + 1] = arr[j];
00063 arr[j] = a;
00064 if (j >= k)
00065 ir = j - 1;
00066 if (j <= k)
00067 l = i;
00068 }
00069 }
00070 }
00071
00072 #define OK 0
00073 #define OUT_OF_MEMORY -1
00074 #define TOO_FEW_GOOD_POINTS -2
00075
00076 int fstats(int n, float arr[], double *min, double *max, double *medn,
00077 double *mean, double *sig, double *skew, double *kurt, int *ngood)
00078 {
00079 int i;
00080 int nv = 0;
00081 float *dat, fmin = FLT_MAX, fmax = -FLT_MAX;
00082 double s = 0.0, s2 = 0.0, s3 = 0.0, s4 = 0.0, avg, var;
00083
00084 *min = *max = *medn = *mean = *sig = *skew = *kurt = __builtin_nan("");
00085
00086 if (!(dat = (float *) malloc(n * sizeof(float))))
00087 return OUT_OF_MEMORY;
00088
00089 for (i = 0; i < n; ++i) {
00090 float t = arr[i];
00091 if (isnanf(t))
00092 continue;
00093 dat[nv++] = t;
00094 if (fmin > t)
00095 fmin = t;
00096 if (fmax < t)
00097 fmax = t;
00098 s += t;
00099 }
00100 *ngood = nv;
00101
00102 if (nv < 2) {
00103 if (nv == 1)
00104 *min = *max = *medn = *mean = s;
00105 free(dat);
00106 return TOO_FEW_GOOD_POINTS;
00107 }
00108
00109 if (fmin == fmax) {
00110 *min = *max = *medn = *mean = fmin;
00111 *sig = *skew = *kurt = 0;
00112 free(dat);
00113 return OK;
00114 }
00115
00116 avg = s / nv;
00117 for (i = 0; i < nv; ++i) {
00118 double tt;
00119 double t = dat[i] - avg;
00120 tt = t * t;
00121 s2 += tt;
00122 tt *= t;
00123 s3 += tt;
00124 tt *= t;
00125 s4 += tt;
00126 }
00127
00128 *min = fmin;
00129 *max = fmax;
00130 *medn = median(nv, dat);
00131 *mean = avg;
00132 var = s2 / (nv - 1);
00133 *sig = sqrt(var);
00134 *skew = s3 / (var * *sig * nv);
00135 *kurt = s4 / (var * var * nv) - 3.0;
00136
00137 free(dat);
00138 return OK;
00139 }