Changeset 796 for trunk/psLib/src/math/psStats.c
- Timestamp:
- May 27, 2004, 2:17:33 PM (22 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/math/psStats.c (modified) (31 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/math/psStats.c
r729 r796 15 15 16 16 #include "float.h" 17 #include <math.h>18 17 #define ROBUST_SIZE_THRESHOLD 10000 // Vectors that are large than this 19 18 // will use robust statistical methods. … … 25 24 #define CLIPPED_SIGMA_LB 1.0 26 25 #define CLIPPED_SIGMA_UB 10.0 27 26 #define true 1 27 #define false 0 28 #define MYMAXFLOAT 1e99 28 29 /****************************************************************************** 29 30 psStatsAlloc(): This routine must create a new psStats data structure. … … 39 40 newStruct->sampleUQ = NAN; 40 41 newStruct->sampleLQ = NAN; 42 newStruct->sampleLimit = NAN; 41 43 newStruct->robustMean = NAN; 42 newStruct->robustMeanNvalues = -1;43 44 newStruct->robustMedian = NAN; 44 newStruct->robustMedianNvalues = -1;45 45 newStruct->robustMode = NAN; 46 newStruct->robustModeNvalues = -1;47 46 newStruct->robustStdev = NAN; 48 47 newStruct->robustUQ = NAN; 49 48 newStruct->robustLQ = NAN; 49 newStruct->robustN50 = NAN; 50 newStruct->robustNfit = NAN; 50 51 newStruct->clippedMean = NAN; 51 newStruct->clippedMeanNvalues = -1;52 52 newStruct->clippedStdev = NAN; 53 53 newStruct->clipSigma = NAN; … … 55 55 newStruct->min = NAN; 56 56 newStruct->max = NAN; 57 newStruct-> nValues = -1;57 newStruct->binsize = NAN; 58 58 newStruct->options = options; 59 59 … … 74 74 psHistogram *psHistogramAlloc(float lower, 75 75 float upper, 76 float size ) 77 { 76 int n) 77 { 78 int i = 0; 78 79 psHistogram *newHist = NULL; 79 int numBins = 0; 80 81 82 numBins = 1 + ((upper - lower) / size); 80 float binSize = 0.0; 81 83 82 newHist = (psHistogram *) psAlloc(sizeof(psHistogram)); 84 newHist->lower = psVectorAlloc(PS_TYPE_FLOAT, numBins); 85 newHist->upper = psVectorAlloc(PS_TYPE_FLOAT, numBins); 86 newHist->nums = psVectorAlloc(PS_TYPE_INT32, numBins); 87 newHist->minVal = lower; 88 newHist->maxVal = upper; 83 newHist->bounds = psVectorAlloc(PS_TYPE_FLOAT, n+1); 84 binSize = (upper - lower) / (float) n; 85 for (i=0;i<n+1;i++) { 86 newHist->bounds->vec.f[i] = lower + (binSize * (float) i); 87 } 88 newHist->nums = psVectorAlloc(PS_TYPE_INT32, n); 89 89 newHist->minNum = 0; 90 90 newHist->maxNum = 0; 91 newHist->numBins = numBins; 91 newHist->uniform = true; 92 92 93 return(newHist); 93 94 } 94 95 95 psHistogram *psHistogramAllocGeneric(const psVector *restrict lower, 96 const psVector *restrict upper, 97 float minVal, 98 float maxVal) 96 97 psHistogram *psHistogramAllocGeneric(const psVector *restrict bounds) 99 98 { 100 99 psHistogram *newHist = NULL; 101 int numBins = 0;102 100 int i; 103 101 104 if (lower->n != upper->n) {105 psError(__func__, "There is a different number of upper/lower values");106 }107 numBins = lower->n;108 102 newHist = (psHistogram *) psAlloc(sizeof(psHistogram)); 109 newHist->lower = psVectorAlloc(PS_TYPE_FLOAT, numBins); 110 newHist->upper = psVectorAlloc(PS_TYPE_FLOAT, numBins); 111 for (i=0;i<numBins;i++) { 112 newHist->lower->vec.f[i] = lower->vec.f[i]; 113 newHist->upper->vec.f[i] = upper->vec.f[i]; 114 } 115 newHist->nums = psVectorAlloc(PS_TYPE_INT32, numBins); 116 newHist->minVal = minVal; 117 newHist->maxVal = maxVal; 103 newHist->bounds = psVectorAlloc(PS_TYPE_FLOAT, bounds->n); 104 for (i=0;i<bounds->n;i++) { 105 newHist->bounds->vec.f[i] = bounds->vec.f[i]; 106 } 107 newHist->nums = psVectorAlloc(PS_TYPE_INT32, (bounds->n)-1); 108 118 109 newHist->minNum = 0; 119 110 newHist->maxNum = 0; 111 newHist->uniform = false; 120 112 121 113 return(newHist); … … 141 133 myHist->maxNum 142 134 *****************************************************************************/ 143 psHistogram *psGetArrayHistogram(psHistogram *restrict myHist, 144 const psVector *restrict myVector) 145 { 146 int i = 0; 135 psHistogram *psHistogramVector(psHistogram *out, 136 psVector *in, 137 psVector *mask, 138 int maskVal) 139 { 140 int i = 0; 141 int j = 0; 147 142 float binSize = 0.0; 148 143 int binNum = 0; 149 150 binSize = (myHist->maxVal - myHist->minVal) / (float) myHist->nums->n; 151 for (i=0;i<myVector->n;i++) { 152 if (myVector->vec.f[i] < myHist->minVal) { 153 myHist->minNum++; 154 } else if (myVector->vec.f[i] > myHist->maxVal) { 155 myHist->maxNum++; 156 } else { 157 binNum = (int) ((myVector->vec.f[i] - myHist->minVal) / binSize); 158 if ((myVector->vec.f[i] >= myHist->lower->vec.f[i]) && 159 (myVector->vec.f[i] <= myHist->upper->vec.f[i])) { 160 myHist->nums->vec.i32[i]++; 144 int numBins = 0; 145 146 numBins = out->nums->n; 147 for (i=0;i<in->n;i++) { 148 // Check if this pixel is masked, and if so, skip it. 149 if (!(mask->vec.i32[i] & maskVal)) { 150 // Check if this pixel is below the minimum value, and if so 151 // count it, then skip it. 152 if (in->vec.f[i] < out->bounds->vec.f[0]) { 153 out->minNum++; 154 155 // Check if this pixel is above the maximum value, and if so 156 // count it, then skip it. 157 } else if (in->vec.f[i] > out->bounds->vec.f[numBins]) { 158 out->maxNum++; 161 159 } else { 162 psError(__func__, "data value was not within the bounds of the bin it should habe been in."); 163 } 164 } 165 } 166 return(myHist); 160 // If this is a uniform histogram, determining the correct 161 // number is trivial. 162 if (out->uniform == true) { 163 binSize = out->bounds->vec.f[1] - out->bounds->vec.f[0]; 164 165 binNum = (int) ((in->vec.f[i] - out->bounds->vec.f[0]) / 166 binSize); 167 (out->nums->vec.i32[binNum])++; 168 // If this is a non-uniform histogram, determining the correct 169 // bin number requires a bit more work. 170 } else { 171 // GUS: This is slow. Put a smarter algorithm here to 172 // find the correct bin number (bin search, probably) 173 for (j=0;j<(out->bounds->n)-1;j++) { 174 if ((out->bounds->vec.i32[j] <= in->vec.f[i]) && 175 (in->vec.f[i] <= out->bounds->vec.i32[j+1])) { 176 (out->nums->vec.i32[j])++; 177 } 178 } 179 } 180 } 181 } 182 } 183 return(out); 167 184 } 168 185 … … 184 201 185 202 /****************************************************************************** 203 ****************************************************************************** 204 ****************************************************************************** 186 205 MISC STATISTICAL FUNCTIONS 187 *****************************************************************************/ 188 void p_psArraySampleMean(const psVector *restrict myVector, 189 const psVector *restrict maskVector, 190 unsigned int maskVal, 191 psStats *newStruct) 206 ****************************************************************************** 207 ****************************************************************************** 208 *****************************************************************************/ 209 void p_psVectorSampleMean(const psVector *restrict myVector, 210 const psVector *restrict maskVector, 211 unsigned int maskVal, 212 psStats *stats) 192 213 { 193 214 int i = 0; 194 215 float mean = 0.0; 195 216 int count = 0; 196 197 if (maskVector != NULL) { 198 for (i=0;i<myVector->n;i++) { 199 if (!(maskVal & maskVector->vec.ui8[i])) { 217 float rangeMin = 0.0; 218 float rangeMax = 0.0; 219 220 if (stats->options & PS_STAT_USE_RANGE) { 221 rangeMin = stats->min; 222 rangeMax = stats->max; 223 if (maskVector != NULL) { 224 for (i=0;i<myVector->n;i++) { 225 if (!(maskVal & maskVector->vec.ui8[i]) && 226 (rangeMin <= myVector->vec.f[i]) && 227 (myVector->vec.f[i] <= rangeMax)) { 228 mean+= myVector->vec.f[i]; 229 count++; 230 } 231 } 232 mean/= (float) count; 233 } else { 234 for (i=0;i<myVector->n;i++) { 235 if ((rangeMin <= myVector->vec.f[i]) && 236 (myVector->vec.f[i] <= rangeMax)) { 237 mean+= myVector->vec.f[i]; 238 count++; 239 } 240 } 241 mean/= (float) count; 242 } 243 } else { 244 if (maskVector != NULL) { 245 for (i=0;i<myVector->n;i++) { 246 if (!(maskVal & maskVector->vec.ui8[i])) { 247 mean+= myVector->vec.f[i]; 248 count++; 249 } 250 } 251 mean/= (float) count; 252 } else { 253 for (i=0;i<myVector->n;i++) { 200 254 mean+= myVector->vec.f[i]; 201 count++; 202 } 203 } 204 mean/= (float) count; 255 } 256 mean/= (float) myVector->n; 257 } 258 } 259 260 stats->sampleMean = mean; 261 } 262 263 void p_psVectorMax(const psVector *restrict myVector, 264 const psVector *restrict maskVector, 265 unsigned int maskVal, 266 psStats *stats) 267 { 268 int i = 0; 269 float max = -MYMAXFLOAT; 270 float rangeMin = 0.0; 271 float rangeMax = 0.0; 272 273 if (stats->options & PS_STAT_USE_RANGE) { 274 rangeMin = stats->min; 275 rangeMax = stats->max; 276 if (maskVector != NULL) { 277 for (i=0;i<myVector->n;i++) { 278 if (!(maskVal & maskVector->vec.ui8[i])) { 279 if ((myVector->vec.f[i] > max) && 280 (rangeMin <= myVector->vec.f[i]) && 281 (myVector->vec.f[i] <= rangeMax)) { 282 max = myVector->vec.f[i]; 283 } 284 } 285 } 286 } else { 287 for (i=0;i<myVector->n;i++) { 288 if ((myVector->vec.f[i] > max) && 289 (rangeMin <= myVector->vec.f[i]) && 290 (myVector->vec.f[i] <= rangeMax)) { 291 max = myVector->vec.f[i]; 292 } 293 } 294 } 205 295 } else { 206 for (i=0;i<myVector->n;i++) { 207 mean+= myVector->vec.f[i]; 208 } 209 mean/= (float) myVector->n; 210 } 211 newStruct->sampleMean = mean; 212 } 213 214 void p_psArrayMax(const psVector *restrict myVector, 215 const psVector *restrict maskVector, 216 unsigned int maskVal, 217 psStats *newStruct) 218 { 219 int i = 0; 220 float max = -1e99; 221 222 if (maskVector != NULL) { 223 for (i=0;i<myVector->n;i++) { 224 if (!(maskVal & maskVector->vec.ui8[i])) { 296 if (maskVector != NULL) { 297 for (i=0;i<myVector->n;i++) { 298 if (!(maskVal & maskVector->vec.ui8[i])) { 299 if (myVector->vec.f[i] > max) { 300 max = myVector->vec.f[i]; 301 } 302 } 303 } 304 } else { 305 for (i=0;i<myVector->n;i++) { 225 306 if (myVector->vec.f[i] > max) { 226 307 max = myVector->vec.f[i]; … … 228 309 } 229 310 } 311 } 312 313 stats->max = max; 314 } 315 316 void p_psVectorMin(const psVector *restrict myVector, 317 const psVector *restrict maskVector, 318 unsigned int maskVal, 319 psStats *stats) 320 { 321 int i = 0; 322 float min = MYMAXFLOAT; 323 float rangeMin = 0.0; 324 float rangeMax = 0.0; 325 326 if (stats->options & PS_STAT_USE_RANGE) { 327 rangeMin = stats->min; 328 rangeMax = stats->max; 329 if (maskVector != NULL) { 330 for (i=0;i<myVector->n;i++) { 331 if (!(maskVal & maskVector->vec.ui8[i])) { 332 if ((myVector->vec.f[i] < min) && 333 (rangeMin <= myVector->vec.f[i]) && 334 (myVector->vec.f[i] <= rangeMax)) { 335 min = myVector->vec.f[i]; 336 } 337 } 338 } 339 } else { 340 for (i=0;i<myVector->n;i++) { 341 if ((myVector->vec.f[i] < min) && 342 (rangeMin <= myVector->vec.f[i]) && 343 (myVector->vec.f[i] <= rangeMax)) { 344 min = myVector->vec.f[i]; 345 } 346 } 347 } 230 348 } else { 231 for (i=0;i<myVector->n;i++) { 232 if (myVector->vec.f[i] > max) { 233 max = myVector->vec.f[i]; 234 } 235 } 236 } 237 newStruct->max = max; 238 } 239 240 void p_psArrayMin(const psVector *restrict myVector, /* FLOATS */ 241 const psVector *restrict maskVector, /* INTS */ 242 unsigned int maskVal, 243 psStats *newStruct) 244 { 245 int i = 0; 246 float min = 1e99; 247 248 if (maskVector != NULL) { 249 for (i=0;i<myVector->n;i++) { 250 if (!(maskVal & maskVector->vec.ui8[i])) { 349 if (maskVector != NULL) { 350 for (i=0;i<myVector->n;i++) { 351 if (!(maskVal & maskVector->vec.ui8[i])) { 352 if (myVector->vec.f[i] < min) { 353 min = myVector->vec.f[i]; 354 } 355 } 356 } 357 } else { 358 for (i=0;i<myVector->n;i++) { 251 359 if (myVector->vec.f[i] < min) { 252 360 min = myVector->vec.f[i]; … … 254 362 } 255 363 } 256 } else { 257 for (i=0;i<myVector->n;i++) { 258 if (myVector->vec.f[i] < min) { 259 min = myVector->vec.f[i]; 260 } 261 } 262 } 263 newStruct->min = min; 364 } 365 366 stats->min = min; 264 367 } 265 368 266 369 /****************************************************************************** 267 268 *****************************************************************************/ 269 void p_psArrayNValues(const psVector *restrict myVector,370 This routine calculates the number of non-masked pixels in the vector. 371 *****************************************************************************/ 372 int p_psVectorNValues(const psVector *restrict myVector, 270 373 const psVector *restrict maskVector, 271 374 unsigned int maskVal, … … 284 387 numData = myVector->n; 285 388 } 286 newStruct->nValues = numData;287 } 288 289 290 291 void p_ps ArraySampleMedian(const psVector *restrict myVector,292 const psVector *restrict maskVector,293 unsigned int maskVal,294 psStats *newStruct)389 return(numData); 390 } 391 392 393 394 void p_psVectorSampleMedian(const psVector *restrict myVector, 395 const psVector *restrict maskVector, 396 unsigned int maskVal, 397 psStats *newStruct) 295 398 { 296 399 psVector *unsortedVector = NULL; … … 299 402 int i = 0; 300 403 float median = 0.0; 301 302 if (-1 == newStruct->nValues) { 303 p_psArrayNValues(myVector, maskVector, maskVal, newStruct); 304 } 305 unsortedVector = psVectorAlloc(PS_TYPE_FLOAT, newStruct->nValues); 404 int nValues = 0; 405 406 nValues = p_psVectorNValues(myVector, maskVector, maskVal, newStruct); 407 unsortedVector = psVectorAlloc(PS_TYPE_FLOAT, nValues); 306 408 unsortedVector->n = unsortedVector->nalloc; 307 sortedVector = psVectorAlloc(PS_TYPE_FLOAT, n ewStruct->nValues);409 sortedVector = psVectorAlloc(PS_TYPE_FLOAT, nValues); 308 410 sortedVector->n = sortedVector->nalloc; 309 411 … … 320 422 } 321 423 322 if (0 == (n ewStruct->nValues % 2)) {323 median = 0.5 * (sortedVector->vec.f[(n ewStruct->nValues/2)-1] +324 sortedVector->vec.f[n ewStruct->nValues/2]);424 if (0 == (nValues % 2)) { 425 median = 0.5 * (sortedVector->vec.f[(nValues/2)-1] + 426 sortedVector->vec.f[nValues/2]); 325 427 } else { 326 median = sortedVector->vec.f[n ewStruct->nValues/2];428 median = sortedVector->vec.f[nValues/2]; 327 429 } 328 430 … … 332 434 } 333 435 334 void p_ps ArraysmoothHistGaussian(psHistogram *robustHistogram,335 float sigma)436 void p_psVectorsmoothHistGaussian(psHistogram *robustHistogram, 437 float sigma) 336 438 { 337 439 int i = 0; … … 365 467 } 366 468 367 for(i=0;i<robustHistogram->num Bins;i++) {469 for(i=0;i<robustHistogram->nums->n;i++) { 368 470 for (j=-GAUSS_WIDTH;j<=+GAUSS_WIDTH;j++) { 369 if (((j+i) >= 0) && ((j+i) < robustHistogram->num Bins)) {471 if (((j+i) >= 0) && ((j+i) < robustHistogram->nums->n)) { 370 472 robustHistogram->nums->vec.i32[j+i]+= 371 473 (gaussianCoefs[j+GAUSS_WIDTH] * … … 377 479 378 480 /****************************************************************************** 379 p_ps ArraySampleQuartiles()481 p_psVectorSampleQuartiles() 380 482 This procedure calculates the upper and/or lower quartiles of the 381 483 data set. It is assumed that the data set is small enough that we 382 484 can sort all the data points and calculate the quartiles exactly. 383 485 *****************************************************************************/ 384 void p_ps ArraySampleQuartiles(const psVector *restrict myVector,385 const psVector *restrict maskVector,386 unsigned int maskVal,387 psStats *newStruct)486 void p_psVectorSampleQuartiles(const psVector *restrict myVector, 487 const psVector *restrict maskVector, 488 unsigned int maskVal, 489 psStats *newStruct) 388 490 { 389 491 psVector *unsortedVector = NULL; … … 392 494 int ind = 0; 393 495 int i = 0; 496 int nValues = 0; 394 497 395 498 // return is we have already calculated both quartile points. … … 399 502 } 400 503 401 if (-1 == newStruct->nValues) { 402 p_psArrayNValues(myVector, maskVector, maskVal, newStruct); 403 } 404 405 406 unsortedVector = psVectorAlloc(PS_TYPE_FLOAT, newStruct->nValues); 407 sortedVector = psVectorAlloc(PS_TYPE_FLOAT, newStruct->nValues); 504 nValues = p_psVectorNValues(myVector, maskVector, maskVal, newStruct); 505 506 unsortedVector = psVectorAlloc(PS_TYPE_FLOAT, nValues); 507 sortedVector = psVectorAlloc(PS_TYPE_FLOAT, nValues); 408 508 409 509 count = 0; … … 419 519 } 420 520 421 if (newStruct->options & PS_STAT_SAMPLE_LQ) { 422 ind = 3 * (newStruct->nValues / 4); 423 newStruct->sampleUQ = sortedVector->vec.f[ind]; 424 } 425 426 if (newStruct->options & PS_STAT_SAMPLE_UQ) { 427 ind = (newStruct->nValues / 4); 428 newStruct->sampleLQ = sortedVector->vec.f[ind]; 429 } 521 ind = 3 * (nValues / 4); 522 newStruct->sampleUQ = sortedVector->vec.f[ind]; 523 ind = (nValues / 4); 524 newStruct->sampleLQ = sortedVector->vec.f[ind]; 430 525 431 526 psVectorFree(unsortedVector); … … 435 530 436 531 /****************************************************************************** 437 p_ps ArrayRobustStats(): this procedure calcualtes a variety of robust532 p_psVectorRobustStats(): this procedure calcualtes a variety of robust 438 533 stat measures: 439 534 PS_STAT_ROBUST_MEAN 440 PS_STAT_ROBUST_MEAN_NVALUES441 535 PS_STAT_ROBUST_MEDIAN 442 PS_STAT_ROBUST_MEDIAN_NVALUES443 536 PS_STAT_ROBUST_MODE 444 PS_STAT_ROBUST_MODE_NVALUES445 537 PS_STAT_ROBUST_STDEV 446 538 I have included all that computation in a single function, as opposed to … … 452 544 processing would be duplicated. 453 545 *****************************************************************************/ 454 void p_ps ArrayRobustStats(const psVector *restrict myVector,455 const psVector *restrict maskVector,456 unsigned int maskVal,457 psStats *newStruct)546 void p_psVectorRobustStats(const psVector *restrict myVector, 547 const psVector *restrict maskVector, 548 unsigned int maskVal, 549 psStats *newStruct) 458 550 { 459 551 psHistogram *robustHistogram = NULL; … … 474 566 475 567 if (0.0 == newStruct->sampleUQ) { 476 newStruct->options = newStruct->options | PS_STAT_SAMPLE_UQ; 477 p_psArraySampleQuartiles(myVector, 478 maskVector, 479 maskVal, 480 newStruct); 568 // GUS: fix this 569 // newStruct->options = newStruct->options | PS_STAT_SAMPLE_UQ; 570 p_psVectorSampleQuartiles(myVector, 571 maskVector, 572 maskVal, 573 newStruct); 481 574 } 482 575 483 576 if (isnan(newStruct->sampleLQ)) { 484 newStruct->options = newStruct->options | PS_STAT_SAMPLE_LQ; 485 p_psArraySampleQuartiles(myVector, 486 maskVector, 487 maskVal, 488 newStruct); 577 // GUS: fix this 578 // newStruct->options = newStruct->options | PS_STAT_SAMPLE_LQ; 579 p_psVectorSampleQuartiles(myVector, 580 maskVector, 581 maskVal, 582 newStruct); 489 583 } 490 584 … … 495 589 // Detemine minimum and maximum values in the data vector. 496 590 if (isnan(newStruct->min)) { 497 p_ps ArrayMin(myVector, maskVector, maskVal, newStruct);591 p_psVectorMin(myVector, maskVector, maskVal, newStruct); 498 592 } 499 593 if (isnan(newStruct->max)) { 500 p_ps ArrayMax(myVector, maskVector, maskVal, newStruct);594 p_psVectorMax(myVector, maskVector, maskVal, newStruct); 501 595 } 502 596 … … 506 600 binSize); 507 601 // Populate the histogram arrat. 508 robustHistogram = psGetArrayHistogram(robustHistogram, myVector); 602 // GUS: fix this 603 // robustHistogram = psHistogramVector(robustHistogram, myVector); 604 // 509 605 510 606 // Smooth the histogram. 511 p_ps ArraysmoothHistGaussian(robustHistogram, sigmaE/4.0f);607 p_psVectorsmoothHistGaussian(robustHistogram, sigmaE/4.0f); 512 608 513 609 LQBinNum = -1; 514 610 UQBinNum = -1; 515 for (i=0;i<robustHistogram->num Bins;i++) {611 for (i=0;i<robustHistogram->nums->n;i++) { 516 612 if ((robustHistogram->nums->vec.i32[i] <= newStruct->sampleLQ) && 517 613 (newStruct->sampleLQ <= robustHistogram->nums->vec.i32[i])) { … … 546 642 newStruct->robustMean = 0.0; 547 643 } 548 if (newStruct->options & PS_STAT_ROBUST_MEAN_NVALUES) { 549 newStruct->robustMeanNvalues = 0.0; 550 } 644 551 645 if (newStruct->options & PS_STAT_ROBUST_MEDIAN) { 552 646 newStruct->robustMedian = 0.0; 553 647 } 554 if (newStruct->options & PS_STAT_ROBUST_MEDIAN_NVALUES) {555 newStruct->robustMedianNvalues = 0.0;556 }557 648 if (newStruct->options & PS_STAT_ROBUST_MODE) { 558 649 newStruct->robustMode = maxBinNum; 559 650 } 560 if (newStruct->options & PS_STAT_ROBUST_MODE_NVALUES) {561 newStruct->robustModeNvalues = 0.0;562 }563 651 if (newStruct->options & PS_STAT_ROBUST_STDEV) { 564 652 newStruct->robustStdev = 0.0; 565 653 } 566 if (newStruct->options & PS_STAT_ROBUST_ UQ) {654 if (newStruct->options & PS_STAT_ROBUST_QUARTILE) { 567 655 newStruct->robustUQ = 0.0; 568 }569 if (newStruct->options & PS_STAT_ROBUST_LQ) {570 656 newStruct->robustLQ = 0.0; 571 657 } 572 658 } 573 659 574 void p_psArraySampleStdev(const psVector *restrict myVector, 575 const psVector *restrict maskVector, 576 unsigned int maskVal, 577 psStats *newStruct) 660 /***************************************************************************** 661 NOTE: This function assumes that p_psVectorMean() has already been called 662 and the correct value is stored in stats->sampleMean. 663 *****************************************************************************/ 664 void p_psVectorSampleStdev(const psVector *restrict myVector, 665 const psVector *restrict maskVector, 666 unsigned int maskVal, 667 psStats *stats) 578 668 { 579 669 int i = 0; … … 584 674 float sumSquares = 0.0; 585 675 float sumDiffs = 0.0; 586 587 if (0 != isnan(newStruct->sampleMean)) { 588 p_psArraySampleMean(myVector, maskVector, maskVal, newStruct); 589 } 590 mean = newStruct->sampleMean; 591 592 if (maskVector != NULL) { 593 for (i=0;i<myVector->n;i++) { 594 if (!(maskVal & maskVector->vec.ui8[i])) { 676 float rangeMin = 0.0; 677 float rangeMax = 0.0; 678 679 if (0 != isnan(stats->sampleMean)) { 680 psAbort(__func__, "stats->sampleMean == NAN"); 681 } 682 mean = stats->sampleMean; 683 684 if (stats->options & PS_STAT_USE_RANGE) { 685 if (maskVector != NULL) { 686 for (i=0;i<myVector->n;i++) { 687 if (!(maskVal & maskVector->vec.ui8[i]) && 688 (rangeMin <= myVector->vec.f[i]) && 689 (myVector->vec.f[i] <= rangeMax)) { 690 diff = myVector->vec.f[i] - mean; 691 sumSquares+= (diff * diff); 692 sumDiffs+= diff; 693 countInt++; 694 } 695 } 696 } else { 697 for (i=0;i<myVector->n;i++) { 698 if ((rangeMin <= myVector->vec.f[i]) && 699 (myVector->vec.f[i] <= rangeMax)) { 700 diff = myVector->vec.f[i] - mean; 701 sumSquares+= (diff * diff); 702 sumDiffs+= diff; 703 countInt++; 704 } 705 } 706 countInt = myVector->n; 707 } 708 } else { 709 if (maskVector != NULL) { 710 for (i=0;i<myVector->n;i++) { 711 if (!(maskVal & maskVector->vec.ui8[i])) { 712 diff = myVector->vec.f[i] - mean; 713 sumSquares+= (diff * diff); 714 sumDiffs+= diff; 715 countInt++; 716 } 717 } 718 } else { 719 for (i=0;i<myVector->n;i++) { 595 720 diff = myVector->vec.f[i] - mean; 596 721 sumSquares+= (diff * diff); 597 722 sumDiffs+= diff; 598 723 countInt++; 599 600 } 601 } 602 } else { 603 for (i=0;i<myVector->n;i++) { 604 diff = myVector->vec.f[i] - mean; 605 sumSquares+= (diff * diff); 606 sumDiffs+= diff; 607 countInt++; 608 } 609 countInt = myVector->n; 724 } 725 countInt = myVector->n; 726 } 610 727 } 611 728 countFloat = (float) countInt; … … 613 730 #ifdef DARWIN 614 731 615 newStruct->sampleStdev = (float) sqrt( (sumSquares-(sumDiffs *616 sumDiffs/countFloat))/ (countFloat-1));732 stats->sampleStdev = (float) sqrt( (sumSquares-(sumDiffs * 733 sumDiffs/countFloat))/ (countFloat-1)); 617 734 #else 618 735 619 newStruct->sampleStdev = sqrtf( (sumSquares-(sumDiffs *620 sumDiffs/countFloat))/ (countFloat-1));736 stats->sampleStdev = sqrtf( (sumSquares-(sumDiffs * 737 sumDiffs/countFloat))/ (countFloat-1)); 621 738 #endif 622 739 } 623 740 624 void p_ps ArrayClippedStats(const psVector *restrict myVector,625 const psVector *restrict maskVector,626 unsigned int maskVal,627 psStats *newStruct)741 void p_psVectorClippedStats(const psVector *restrict myVector, 742 const psVector *restrict maskVector, 743 unsigned int maskVal, 744 psStats *newStruct) 628 745 { 629 746 int i = 0; … … 653 770 654 771 // 1. Compute the sample median. 655 p_ps ArraySampleMedian(myVector, maskVector, maskVal, newStruct);772 p_psVectorSampleMedian(myVector, maskVector, maskVal, newStruct); 656 773 657 774 // 2. Compute the sample standard deviation. 658 p_ps ArraySampleStdev(myVector, maskVector, maskVal, newStruct);775 p_psVectorSampleStdev(myVector, maskVector, maskVal, newStruct); 659 776 660 777 // 3. Use the sample median as the first estimator of the mean X. … … 676 793 // GUS: I should probably create a new struct here since the 677 794 // following calls will overwrite any old values in sampleMean. 678 p_ps ArraySampleMedian(myVector, tmpMask, maskVal, newStruct);679 p_ps ArraySampleStdev(myVector, tmpMask, maskVal, newStruct);795 p_psVectorSampleMedian(myVector, tmpMask, maskVal, newStruct); 796 p_psVectorSampleStdev(myVector, tmpMask, maskVal, newStruct); 680 797 681 798 // c) Use the new mean for x … … 695 812 if (newStruct->options & PS_STAT_CLIPPED_STDEV) { 696 813 newStruct->clippedStdev = clippedStdev; 697 }698 699 if (newStruct->options & PS_STAT_CLIPPED_MEAN_NVALUES) {700 p_psArrayNValues(myVector, tmpMask, maskVal, newStruct);701 }702 703 if (newStruct->options & PS_STAT_CLIPPED_MEAN_NSIGMA) {704 // GUS: What to do here?705 814 } 706 815 … … 716 825 717 826 *****************************************************************************/ 718 psStats *psArrayStats(const psVector *restrict myVector, 719 const psVector *restrict maskVector, 720 unsigned int maskVal, 721 psStats *stats) 722 { 723 psStats *newStruct = NULL; 724 725 if (myVector == NULL) { 726 psAbort(__func__, 727 "Input data array (myVector) was NULL."); 728 } 729 730 if (myVector->type.type != PS_TYPE_FLOAT) { 827 psStats *psVectorStats(psStats *stats, 828 psVector *in, 829 psVector *mask, 830 unsigned int maskVal) 831 { 832 if (in == NULL) { 833 psAbort(__func__, "Input data vector (in) was NULL."); 834 } 835 836 if (in->type.type != PS_TYPE_FLOAT) { 731 837 psAbort(__func__, 732 838 "Only data type PS_TYPE_FLOAT is currently supported."); 733 839 } 734 if (mask Vector!= NULL) {735 if ( myVector->n != maskVector->n) {840 if (mask != NULL) { 841 if (in->n != mask->n) { 736 842 psAbort(__func__, 737 843 "Vector data and vector mask are of different sizes."); 738 844 } 739 if (mask Vector->type.type != PS_TYPE_UINT8) {845 if (mask->type.type != PS_TYPE_UINT8) { 740 846 psAbort(__func__, 741 847 "Vector mask must be type PS_TYPE_UINT8"); 742 848 } 743 849 } 744 newStruct = psStatsAlloc(stats->options);745 850 746 851 // ************************************************************************ 747 852 if (stats->options & PS_STAT_SAMPLE_MEAN) { 748 p_psArraySampleMean(myVector, maskVector, maskVal, newStruct); 853 p_psVectorSampleMean(in, mask, maskVal, stats); 854 } 855 856 // ************************************************************************ 857 if (stats->options & PS_STAT_SAMPLE_MEDIAN) { 858 p_psVectorSampleMedian(in, mask, maskVal, stats); 859 } 860 861 // ************************************************************************ 862 if (stats->options & PS_STAT_SAMPLE_STDEV) { 863 p_psVectorSampleStdev(in, mask, maskVal, stats); 864 } 865 866 // ************************************************************************ 867 if (stats->options & PS_STAT_SAMPLE_QUARTILE) { 868 p_psVectorSampleQuartiles(in, mask, maskVal, stats); 869 } 870 871 if ((stats->options & PS_STAT_ROBUST_MEAN) || 872 (stats->options & PS_STAT_ROBUST_MEDIAN) || 873 (stats->options & PS_STAT_ROBUST_MODE) || 874 (stats->options & PS_STAT_ROBUST_STDEV) || 875 (stats->options & PS_STAT_ROBUST_QUARTILE)) { 876 p_psVectorRobustStats(in, mask, maskVal, stats); 877 } 878 879 if ((stats->options & PS_STAT_CLIPPED_MEAN) || 880 (stats->options & PS_STAT_CLIPPED_STDEV)) { 881 p_psVectorClippedStats(in, mask, maskVal, stats); 749 882 } 750 883 751 884 // ************************************************************************ 752 885 if (stats->options & PS_STAT_MAX) { 753 p_ps ArrayMax(myVector, maskVector, maskVal, newStruct);886 p_psVectorMax(in, mask, maskVal, stats); 754 887 } 755 888 756 889 // ************************************************************************ 757 890 if (stats->options & PS_STAT_MIN) { 758 p_psArrayMin(myVector, maskVector, maskVal, newStruct); 759 } 760 761 // ************************************************************************ 762 if (stats->options & PS_STAT_NVALUES) { 763 p_psArrayNValues(myVector, maskVector, maskVal, newStruct); 764 } 765 766 // ************************************************************************ 767 if (stats->options & PS_STAT_SAMPLE_MEDIAN) { 768 p_psArraySampleMedian(myVector, maskVector, maskVal, newStruct); 769 } 770 771 // ************************************************************************ 772 if (stats->options & PS_STAT_SAMPLE_STDEV) { 773 p_psArraySampleStdev(myVector, maskVector, maskVal, newStruct); 774 } 775 776 // ************************************************************************ 777 if ((stats->options & PS_STAT_SAMPLE_UQ) || 778 (stats->options & PS_STAT_SAMPLE_LQ)) { 779 p_psArraySampleQuartiles(myVector, maskVector, maskVal, newStruct); 780 } 781 782 if ((stats->options & PS_STAT_ROBUST_MEAN) || 783 (stats->options & PS_STAT_ROBUST_MEAN_NVALUES) || 784 (stats->options & PS_STAT_ROBUST_MEDIAN) || 785 (stats->options & PS_STAT_ROBUST_MEDIAN_NVALUES) || 786 (stats->options & PS_STAT_ROBUST_MODE) || 787 (stats->options & PS_STAT_ROBUST_MODE_NVALUES) || 788 (stats->options & PS_STAT_ROBUST_STDEV) || 789 (stats->options & PS_STAT_ROBUST_UQ) || 790 (stats->options & PS_STAT_ROBUST_LQ)) { 791 p_psArrayClippedStats(myVector, maskVector, maskVal, newStruct); 792 } 793 794 if ((stats->options & PS_STAT_CLIPPED_MEAN) || 795 (stats->options & PS_STAT_CLIPPED_MEAN_NVALUES) || 796 (stats->options & PS_STAT_CLIPPED_MEAN_NSIGMA) || 797 (stats->options & PS_STAT_CLIPPED_STDEV)) { 798 p_psArrayClippedStats(myVector, maskVector, maskVal, newStruct); 891 p_psVectorMin(in, mask, maskVal, stats); 799 892 } 800 893 … … 803 896 // psAbort(__func__, "Unknown options 0x%x.\n", stats->options); 804 897 805 return( newStruct);806 } 898 return(stats); 899 }
Note:
See TracChangeset
for help on using the changeset viewer.
