Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

stats.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1995 Microsoft Corporation 00004 00005 Module Name 00006 00007 stats.c 00008 00009 Abstract: 00010 00011 Perform basic statistics on a sample array of data: Average, Standard Deviation Coefficient. 00012 Perform simple filtering of Data to meet a specified Standard Deviation Coeficient (Optional). 00013 00014 Author: 00015 00016 Dan Almosnino (danalm) 20-Nov-1995 - Wrote it 00017 00018 Enviornment: 00019 00020 User Mode 00021 00022 Revision History: 00023 00024 ++*/ 00025 00026 #include "precomp.h" 00027 #include "stats.h" 00028 00029 /*++ 00030 00031 Routine Description: 00032 00033 Shell for statistic processing of data 00034 00035 Arguments 00036 00037 double *array, Raw data array 00038 long num_samples, Number of samples taken 00039 const filter_option, available options: HI_FILTER, LO_FILTER, HI_LO_FILTER, NO_FILTER 00040 long var_limit, Filter data so that its variation coefficient (StdDev/Average) 00041 Won't exceed var_limit (in whole percent units) 00042 PTEST_STATS stats) Pointer to struct that contains the calculated statistical data 00043 Members: double Average, StdDev(%) (variation coefficient), 00044 Minimum_Result, Maximum_Result 00045 long NumSamplesValid (after filtering) 00046 Notes: Minimum_Result and Max_Result are always before filtering. 00047 A negative value of StdDev means that the average was zero, and 00048 the number returned is the negative value of the standard deviation 00049 itself and not a relative number (coeficient of variation) 00050 Return Value 00051 00052 TRUE for Success 00053 FALSE for Failure (Indicates a failure of one of the called functions due to either: 00054 Too small No. of original Samples or Valid Samples left after filtering, or 00055 Zero Arithmetic Average of data (filtering cannot continue), or 00056 Invalid filter option. 00057 00058 --*/ 00059 00060 BOOL 00061 Get_Stats( 00062 double *array, 00063 long num_samples, 00064 const filter_option, 00065 long var_limit, 00066 PTEST_STATS stats) 00067 00068 { 00069 00070 double Averagetmp; 00071 double StdDevtmp; 00072 long NumSamplestmp; 00073 00074 if(!GetAverage(array, num_samples, &Averagetmp)) 00075 return FALSE; 00076 00077 SortUp(array, num_samples); 00078 00079 if(!GetStdDev(array, Averagetmp, num_samples, &StdDevtmp)) 00080 return FALSE; 00081 00082 stats->Minimum_Result = array[0]; 00083 stats->Maximum_Result = array[num_samples - 1]; 00084 00085 if(filter_option == NO_FILTER) 00086 { 00087 stats->Average = Averagetmp; 00088 stats->StdDev = StdDevtmp; 00089 stats->NumSamplesValid = num_samples; 00090 return TRUE; 00091 } 00092 00093 00094 NumSamplestmp = num_samples; 00095 if(!FilterResults(array,&Averagetmp,&StdDevtmp,&NumSamplestmp,var_limit,filter_option)) 00096 return FALSE; 00097 00098 stats->Average = Averagetmp; 00099 stats->StdDev = StdDevtmp; 00100 stats->NumSamplesValid = NumSamplestmp; 00101 return TRUE; 00102 00103 } 00104 00105 /*++ 00106 00107 Routine Description: 00108 00109 Calculate the arithmetic average of an array of numbers 00110 00111 Arguments 00112 00113 double Sample_Array - data array 00114 long No_Samples - number of samples to calculate the average of 00115 double *Average - pointer to the result 00116 00117 Return Value 00118 00119 TRUE for Success 00120 FALSE for Failure (No_Samples is zero) 00121 00122 --*/ 00123 00124 00125 BOOL 00126 GetAverage( 00127 double Sample_Array[], 00128 long No_Samples, 00129 double *Average) 00130 { 00131 long i; 00132 (*Average) = 0.0; 00133 00134 if(No_Samples == 0)return FALSE; 00135 00136 for(i = 0; i < No_Samples; i++) 00137 { 00138 (*Average) += Sample_Array[i]; 00139 } 00140 00141 (*Average) /= No_Samples; 00142 00143 return TRUE; 00144 00145 } 00146 00147 /*++ 00148 00149 Routine Description: 00150 00151 Calculate the standard deviation of a set of data 00152 00153 Arguments 00154 00155 double Sample_Array - The data array 00156 double Average - The arithmetic Average of the Sample_Array 00157 long No_Samples - Number of Samples to Calculate 00158 double *varcoef - The resulting coeficient of variation (StdDev / Average) in percent 00159 (If the average is zero then the standard deviation itself is returned in 00160 negative value) 00161 00162 Return Value 00163 00164 TRUE for Success 00165 FALSE for Failure (No. of Samples is less than two) 00166 00167 --*/ 00168 00169 00170 00171 BOOL 00172 GetStdDev( 00173 double Sample_Array[], 00174 double Average, 00175 long No_Samples, 00176 double *varcoef) 00177 { 00178 long i; 00179 double tmp; 00180 double Sum = 0.0; 00181 00182 if(No_Samples <= 1L) 00183 { 00184 return FALSE; 00185 } 00186 00187 for(i=0; i<No_Samples; i++) 00188 { 00189 tmp = (Sample_Array[i] - Average); 00190 Sum += (tmp*tmp); 00191 } 00192 00193 Sum /= (No_Samples - 1); 00194 00195 if(fabs( (float)Average) < 1.E-6) 00196 { 00197 *varcoef = (-sqrt(Sum)); // return the Standard Deviation itself in negative sign for distinction 00198 } 00199 else 00200 { 00201 *varcoef = (100*sqrt(Sum)/Average); // return the variation coeficient in percents 00202 } 00203 00204 return TRUE; 00205 } 00206 00207 /*++ 00208 00209 Routine Description: 00210 00211 Simplest Quick Sort routine (sorts-up an array of doubles) 00212 00213 Arguments 00214 00215 double *Array - Pointer to the array to be sorted (result is returned in the same address) 00216 long array_size - Size of array to be sorted 00217 00218 Return Value 00219 00220 none 00221 00222 --*/ 00223 00224 00225 void 00226 SortUp( 00227 double *array, 00228 long array_size) 00229 { 00230 long gap, i, j; 00231 double temp; 00232 00233 for(gap = array_size/2; gap > 0; gap /= 2) 00234 for(i = gap; i < array_size; i++) 00235 for(j = i - gap; j >= 0 && array[j] > array[j + gap]; j -= gap) 00236 { 00237 temp = array[j]; 00238 array[j] = array[j + gap]; 00239 array[j + gap] = temp; 00240 } 00241 00242 } 00243 00244 /*++ 00245 00246 Routine Description: 00247 00248 Filter a set of data to meet a pre-defined coeficient of variation 00249 00250 Arguments 00251 00252 double Sorted_Array - A pointer to a pre-sorted up array of data to be filtered 00253 double *tmpAverage - A pointer to the arithmetic average of the array of data. 00254 Upon exit will contain the resulting average of the filtered data. 00255 double *tmpSD - A pointer to the variation coefficient (in percent) of the input array of data. 00256 Upon exit will contain the resulting variation coefficient of the filtered data 00257 after the constraint was met. 00258 long *tmpNumSamples - A pointer to the number of samples to be filtered. 00259 Upon return will contain the number of valid samples left after the filtering. 00260 long limit - The pre defined coefficient of variation (StdDev / Average)to be met 00261 (in whole percents). 00262 const filter_option - One of the following: 00263 HI_FILTER - filter eliminates the high values from top down until limit is met 00264 LO_FILTER - filter eliminates the low values from bottom up until limit is met 00265 HI_LO_FILTER- filter eliminates both high and low values in this order until limit is met 00266 other - routine will return a FALSE 00267 00268 Return Value 00269 00270 TRUE for Success 00271 FALSE for failure (Either number of samples left after sequential filtering passes is less than three, 00272 or for some reason the filtered average became zero, 00273 or the filter option is an invalid value) 00274 00275 --*/ 00276 00277 00278 00279 BOOL 00280 FilterResults( 00281 double Sorted_Array[], 00282 double *tmpAverage, 00283 double *tmpSD, 00284 long *tmpNumSamples, 00285 long limit, 00286 const filter_option) 00287 { 00288 00289 00290 switch (filter_option) 00291 { 00292 case HI_FILTER: 00293 { 00294 while(*tmpSD > (double)limit) 00295 { 00296 00297 if(*tmpNumSamples <= 2)return FALSE; 00298 00299 (*tmpAverage) *= (*tmpNumSamples); 00300 (*tmpAverage) -= Sorted_Array[(*tmpNumSamples) - 1]; 00301 (*tmpNumSamples)--; 00302 (*tmpAverage) /= (*tmpNumSamples); 00303 00304 GetStdDev(Sorted_Array, *tmpAverage, *tmpNumSamples, &(*tmpSD)); 00305 00306 } 00307 00308 if(*tmpSD < 0)return FALSE; 00309 } 00310 break; 00311 00312 case LO_FILTER: 00313 { 00314 00315 while(*tmpSD > (double)limit) 00316 { 00317 00318 if(*tmpNumSamples <= 2)return FALSE; 00319 00320 (*tmpAverage) *= (*tmpNumSamples); 00321 (*tmpAverage) -= (*Sorted_Array); 00322 Sorted_Array++; 00323 (*tmpNumSamples)--; 00324 (*tmpAverage) /= (*tmpNumSamples); 00325 00326 GetStdDev(Sorted_Array, *tmpAverage, *tmpNumSamples, &(*tmpSD)); 00327 00328 } 00329 00330 if(*tmpSD < 0)return FALSE; 00331 00332 } 00333 break; 00334 00335 case HI_LO_FILTER: 00336 { 00337 00338 while(*tmpSD > (double)limit) 00339 { 00340 00341 if(*tmpNumSamples <= 2)return FALSE; 00342 00343 if(fabs((*Sorted_Array) - (*tmpAverage)) > fabs(Sorted_Array[*tmpNumSamples - 1] - *tmpAverage)) 00344 { 00345 (*tmpAverage) *= (*tmpNumSamples); 00346 (*tmpAverage) -= (*Sorted_Array); 00347 Sorted_Array++; 00348 } 00349 else 00350 { 00351 (*tmpAverage) *= (*tmpNumSamples); 00352 (*tmpAverage) -= Sorted_Array[(*tmpNumSamples) - 1]; 00353 } 00354 00355 (*tmpNumSamples)--; 00356 (*tmpAverage) /= (*tmpNumSamples); 00357 00358 GetStdDev(Sorted_Array, *tmpAverage, *tmpNumSamples, &(*tmpSD)); 00359 00360 } 00361 00362 if(*tmpSD < 0)return FALSE; 00363 00364 } 00365 break; 00366 00367 default: 00368 return FALSE; 00369 00370 } //switch filter_option 00371 00372 return TRUE; 00373 00374 } 00375 00376 00377

Generated on Sat May 15 19:41:52 2004 for test by doxygen 1.3.7