/* statr.c Copyright (c) Kapteyn Laboratorium Groningen 1990 All Rights Reserved. #> statr.dc2 Function: STATR Purpose: Determines the min, max, running mean and rms of an array of reals. File: statr.c Author: K.G. Begeman Use: CALL STATR( ARRAY , input REAL ARRAY NITEM , input INTEGER AMIN , output REAL AMAX , output REAL MEAN , output REAL RMS , output REAL NBLANK , output INTEGER NTOT ) input INTEGER ARRAY Input array (part of subset). NITEM Number of reals in ARRAY. AMIN Running minimum in subset. AMAX Running maximum in subset. MEAN Running mean in subset. RMS Running rms in subset. NBLANK Number of blank values. NTOT Number of values checked. Description: The routine is initialized when NTOT = 0. If not enough defined values to determine AMIN, AMAX, MEAN or RMS then the routine will return BLANK (can be checked with logical function FBLANK). Example: NTOT=0 REPEAT CALL GDSI_READ( , , , A, , N, IER ) CALL STATR(A,N,MIN,MAX,MEAN,RMS,NBLANK,NTOT) UNTIL (IER.EQ.0) Updates: Dec 16, 1988: KGB, original document. #< @ subroutine statr( real, integer, real, real, real, real, integer, integer ) */ #include "stdio.h" #include "math.h" #include "gipsyc.h" #include "setfblank.h" void statr_c( float *array , fint *nitem , float *amin , float *amax , float *mean , float *rms , fint *nblank, fint *ntot ) { double local_amax; double local_amin; double local_mean = 0.0; double local_sum; double local_sumsqr = 0.0; fint i = 0; fint local_nblank = 0; fint local_ndef = 0; fint ndef; float blank; float v; setfblank_c( &blank ); /* get system defined BLANK */ if (*ntot == 0) { /* not yet initialized ? */ *amin = *amax = *mean = *rms = blank; *nblank = 0; } ndef = (*ntot - *nblank); /* number of defined values treated already */ /* * First we try to find the first defined data value. */ while (!local_ndef && i < *nitem) { /* loop until defined value found */ v = array[i++]; /* get next value */ if (blank == v ) { local_nblank += 1; /* another blank */ } else { local_ndef = 1; /* the first defined value */ local_amin = v; local_amax = v; local_sum = v; } } /* * Now we have found a defined data value, so we will now determine * the local average. */ while (i < *nitem) { /* loop through rest of array */ v = array[i++]; /* get next value */ if (blank == v ) { local_nblank += 1; /* another blank */ } else { local_ndef++; /* another defined value */ local_sum += v; if (v > local_amax) { local_amax = v; } else if (v < local_amin) { local_amin = v; } } } /* * If local average could be defined, then determine the sum of * the squared deviations from the mean. */ if (local_ndef) { local_mean = local_sum / (double) local_ndef; for (i = 0; i < *nitem; i++) { v = array[i]; if (v != blank) { double r = v - local_mean; local_sumsqr += r * r; } } if (ndef) { /* was already defined in previous calls */ double old_sumsqr; double r = (*mean) - local_mean; double f = (double) ndef * (double) local_ndef / (double) (ndef + local_ndef); if (ndef > 1) { old_sumsqr = (*rms) * (*rms) * (double) (ndef - 1); } else { old_sumsqr = 0.0; } local_sumsqr += old_sumsqr + r * r * f; *rms = sqrt( local_sumsqr / (double) (local_ndef + ndef - 1) ); *mean *= (double) ndef; *mean += (double) local_ndef * local_mean; *mean /= (double) (ndef + local_ndef); if (*amax < local_amax) *amax = local_amax; if (*amin > local_amin) *amin = local_amin; } else { /* define it now */ if (local_ndef > 1) { *rms = sqrt( local_sumsqr / (double) (local_ndef - 1) ); } *mean = local_mean; *amax = local_amax; *amin = local_amin; } } *nblank += local_nblank; /* new number of blanks */ *ntot += *nitem; /* new number of values treated */ } #if defined(TESTBED) main() { float a[100], min = 4.0, max = -4.0, mean = 0.0, rms = 0.0; float ndef; fint i, n = 5, nblank = 0, ntot = 0, ndat = 100; for (i = 0; i < ndat; i++) { if (i%10) { a[i] = 4.5 - (float) (i%10); if (min > a[i]) min = a[i]; else if (max < a[i]) max = a[i]; mean += a[i]; rms += a[i] * a[i]; } else { setfblank_c(&a[i]); nblank++; } } ndef = (float) (100 - nblank); mean = mean / ndef; rms = sqrt( (rms - ndef * mean * mean) / (ndef - 1.0) ); printf( "min: %8.5f,max: %8.5f,mean: %8.5f,rms: %8.5f,nblank: %2ld,ntot: %3ld\n", min, max, mean, rms, nblank, ndat ); while (ntot < ndat) { statr_c( &a[ntot], &n, &min, &max, &mean, &rms, &nblank, &ntot ); printf( "min: %8.5f,max: %8.5f,mean: %8.5f,rms: %8.5f,nblank: %2ld,ntot: %3ld\n", min, max, mean, rms, nblank, ntot ); } } #endif