Changeset 1020
- Timestamp:
- Jun 14, 2004, 9:33:09 AM (22 years ago)
- Location:
- trunk/psLib/src
- Files:
-
- 10 edited
-
dataManip/psFunctions.c (modified) (17 diffs)
-
dataManip/psFunctions.h (modified) (2 diffs)
-
dataManip/psStats.c (modified) (53 diffs)
-
dataManip/psStats.h (modified) (5 diffs)
-
math/psPolynomial.c (modified) (17 diffs)
-
math/psPolynomial.h (modified) (2 diffs)
-
math/psSpline.c (modified) (17 diffs)
-
math/psSpline.h (modified) (2 diffs)
-
math/psStats.c (modified) (53 diffs)
-
math/psStats.h (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/dataManip/psFunctions.c
r889 r1020 4 4 * routines. 5 5 * 6 * @author George Gusciora, MHPCC 6 * This file will hold the functions for allocated, freeing, and evaluating 7 * polynomials. It also contains a Gaussian functions. 7 8 * 8 * @version $Revision: 1.1 1$ $Name: not supported by cvs2svn $9 * @date $Date: 2004-06- 07 00:32:53$9 * @version $Revision: 1.12 $ $Name: not supported by cvs2svn $ 10 * @date $Date: 2004-06-14 19:32:42 $ 10 11 * 11 12 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 103 104 psPolynomial1D *psPolynomial1DAlloc(int n) 104 105 { 106 int i = 0; 105 107 psPolynomial1D *newPoly = NULL; 106 108 … … 110 112 newPoly->coeffErr = (float *) psAlloc(n * sizeof(float)); 111 113 newPoly->mask = (char *) psAlloc(n * sizeof(char)); 114 for (i=0;i<n;i++) { 115 newPoly->coeff[i] = 0.0; 116 newPoly->coeffErr[i] = 0.0; 117 newPoly->mask[i] = 0.0; 118 } 112 119 113 120 return(newPoly); … … 117 124 { 118 125 int x = 0; 126 int y = 0; 119 127 psPolynomial2D *newPoly = NULL; 120 128 … … 131 139 newPoly->mask[x] = (char *) psAlloc(nY * sizeof(char)); 132 140 } 133 141 for (x=0;x<nX;x++) { 142 for (y=0;y<nY;y++) { 143 newPoly->coeff[x][y] = 0.0; 144 newPoly->coeffErr[x][y] = 0.0; 145 newPoly->mask[x][y] = 0; 146 } 147 } 134 148 135 149 return(newPoly); … … 140 154 int x = 0; 141 155 int y = 0; 156 int z = 0; 142 157 psPolynomial3D *newPoly = NULL; 143 158 … … 160 175 } 161 176 } 177 for (x=0;x<nX;x++) { 178 for (y=0;y<nY;y++) { 179 for (z=0;z<nZ;z++) { 180 newPoly->coeff[x][y][z] = 0.0; 181 newPoly->coeffErr[x][y][z] = 0.0; 182 newPoly->mask[x][y][z] = 0; 183 } 184 } 185 } 162 186 163 187 return(newPoly); … … 169 193 int x = 0; 170 194 int y = 0; 195 int z = 0; 171 196 psPolynomial4D *newPoly = NULL; 172 197 … … 195 220 } 196 221 } 222 for (w=0;w<nW;w++) { 223 for (x=0;x<nX;x++) { 224 for (y=0;y<nY;y++) { 225 for (z=0;z<nZ;z++) { 226 newPoly->coeff[w][x][y][z] = 0.0; 227 newPoly->coeffErr[w][x][y][z] = 0.0; 228 newPoly->mask[w][x][y][z] = 0; 229 } 230 } 231 } 232 } 197 233 198 234 return(newPoly); … … 394 430 psDPolynomial1D *psDPolynomial1DAlloc(int n) 395 431 { 432 int i = 0; 396 433 psDPolynomial1D *newPoly = NULL; 397 434 … … 401 438 newPoly->coeffErr = (double *) psAlloc(n * sizeof(double)); 402 439 newPoly->mask = (char *) psAlloc(n * sizeof(char)); 440 for (i=0;i<n;i++) { 441 newPoly->coeff[i] = 0.0; 442 newPoly->coeffErr[i] = 0.0; 443 newPoly->mask[i] = 0.0; 444 } 403 445 404 446 return(newPoly); … … 408 450 { 409 451 int x = 0; 452 int y = 0; 410 453 psDPolynomial2D *newPoly = NULL; 411 454 … … 422 465 newPoly->mask[x] = (char *) psAlloc(nY * sizeof(char)); 423 466 } 467 for (x=0;x<nX;x++) { 468 for (y=0;y<nY;y++) { 469 newPoly->coeff[x][y] = 0.0; 470 newPoly->coeffErr[x][y] = 0.0; 471 newPoly->mask[x][y] = 0; 472 } 473 } 424 474 425 475 return(newPoly); … … 430 480 int x = 0; 431 481 int y = 0; 482 int z = 0; 432 483 psDPolynomial3D *newPoly = NULL; 433 484 … … 450 501 } 451 502 } 503 for (x=0;x<nX;x++) { 504 for (y=0;y<nY;y++) { 505 for (z=0;z<nZ;z++) { 506 newPoly->coeff[x][y][z] = 0.0; 507 newPoly->coeffErr[x][y][z] = 0.0; 508 newPoly->mask[x][y][z] = 0; 509 } 510 } 511 } 452 512 453 513 return(newPoly); … … 459 519 int x = 0; 460 520 int y = 0; 521 int z = 0; 461 522 psDPolynomial4D *newPoly = NULL; 462 523 … … 485 546 } 486 547 } 548 for (w=0;w<nW;w++) { 549 for (x=0;x<nX;x++) { 550 for (y=0;y<nY;y++) { 551 for (z=0;z<nZ;z++) { 552 newPoly->coeff[w][x][y][z] = 0.0; 553 newPoly->coeffErr[w][x][y][z] = 0.0; 554 newPoly->mask[w][x][y][z] = 0; 555 } 556 } 557 } 558 } 487 559 488 560 return(newPoly); -
trunk/psLib/src/dataManip/psFunctions.h
r974 r1020 1 /** @file psFunctions.h 2 * \brief Standard Mathematical Functions. 3 * \ingroup Stats 4 * 5 * This file will hold the prototypes for procedures which allocate, free, 6 * and evaluate various polynomials. Those polynomial structures are also 7 * defined here. 8 * 9 * @ingroup Stats 10 * 11 * @author Someone at IfA 12 * @author George Gusciora, MHPCC 13 * 14 * @version $Revision: 1.6 $ $Name: not supported by cvs2svn $ 15 * @date $Date: 2004-06-14 19:32:42 $ 16 * 17 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii 18 */ 19 1 20 #if !defined(PS_FUNCTIONS_H) 2 21 #define PS_FUNCTIONS_H 3 22 4 /** \file psFunctions.h5 * \brief Standard Mathematical Functions.6 * \ingroup Stats7 */8 23 9 24 /** \addtogroup Stats … … 23 38 24 39 25 psVector *psGaussianDev(float mean, 26 float sigma, 27 int Npts); 28 29 /*****************************************************************************/ 40 /** Produce a vector of random numbers from a Gaussian distribution with 41 the specified mean and sigma */ 42 psVector *psGaussianDev(float mean, ///< The mean of the Gaussian 43 float sigma, ///< The sigma of the Gaussian 44 int Npts); ///< The size of the vector 45 46 47 48 30 49 31 50 /** One-dimensional polynomial */ 32 51 typedef struct 33 52 { 34 int n; ///< Number of terms35 float *coeff; ///< Coefficients36 float *coeffErr; ///< Error in coefficients37 char *mask; ///< Coefficient mask53 int n; ///< Number of terms 54 float *coeff; ///< Coefficients 55 float *coeffErr; ///< Error in coefficients 56 char *mask; ///< Coefficient mask 38 57 } 39 58 psPolynomial1D; -
trunk/psLib/src/dataManip/psStats.c
r978 r1020 15 15 16 16 #include "float.h" 17 #define ROBUST_SIZE_THRESHOLD 30000 // Vectors that are large than this17 #define DEFAULT_ROBUST_SIZE_THRESHOLD 30000 // Vectors that are large than this 18 18 // will use robust statistical methods. 19 #define GAUSS_WIDTH 20 // The width of the Gaussian or boxcar 20 // smoothing. 21 #define PI 3.141592653 19 #define GAUSS_WIDTH 20 // The width of the Gaussian or boxcar smoothing. 22 20 #define CLIPPED_NUM_ITER_LB 1 23 21 #define CLIPPED_NUM_ITER_UB 10 … … 26 24 #define true 1 27 25 #define false 0 28 #define MYMAXFLOAT 1e9926 #define MYMAXFLOAT HUGE 29 27 30 28 #ifndef DOXYGEN … … 48 46 newStruct->sampleUQ = NAN; 49 47 newStruct->sampleLQ = NAN; 50 newStruct->sampleLimit = ROBUST_SIZE_THRESHOLD;48 newStruct->sampleLimit = DEFAULT_ROBUST_SIZE_THRESHOLD; 51 49 newStruct->robustMean = NAN; 52 50 newStruct->robustMedian = NAN; … … 78 76 79 77 /****************************************************************************** 80 HISTOGRAM FUNCTIONS 78 psHistogramAlloc(lower, upper, n): allocate a uniform histogram structure 79 with the specifed upper and lower limits, and the specifed number of bins. 80 This routine will also set the bounds for each of the bins. 81 82 Input: 83 lower 84 upper 85 n 86 Returns: 87 The histogram structure 81 88 *****************************************************************************/ 82 89 psHistogram *psHistogramAlloc(float lower, … … 84 91 int n) 85 92 { 86 int i = 0; 87 psHistogram *newHist = NULL; 88 float binSize = 0.0; 89 93 int i = 0; // Loop index variable 94 psHistogram *newHist = NULL; // The new histogram structure 95 float binSize = 0.0; // The histogram bin size 96 97 // GUS: Verify that this is the correct action. 90 98 if (n == 0) { 91 psAbort(__func__, "psHistogram requested with 0 bins");99 return(NULL); 92 100 } 93 101 94 102 // GUS: Verify that this is the correct action. 95 103 if (lower > upper) { 96 // psAbort(__func__, "psHistogram requested with lower>upper");97 104 return(NULL); 98 105 } 99 106 107 // Allocate memory for the new histogram structure. If there are N 108 // bins, then there are N+1 bounds to those bins. 100 109 newHist = (psHistogram *) psAlloc(sizeof(psHistogram)); 101 110 newHist->bounds = psVectorAlloc(n+1, PS_TYPE_F32); 102 111 newHist->bounds->n = newHist->bounds->nalloc; 103 112 113 // Calculate the bounds for each bin. 104 114 binSize = (upper - lower) / (float) n; 105 115 for (i=0;i<n+1;i++) { 106 116 newHist->bounds->data.F32[i] = lower + (binSize * (float) i); 107 117 } 118 119 // Allocate the bins, and initialize them to zero. 108 120 newHist->nums = psVectorAlloc(n, PS_TYPE_S32); 109 121 newHist->nums->n = newHist->nums->nalloc; … … 111 123 newHist->nums->data.S32[i] = 0; 112 124 } 125 126 // Initialize the other members. 113 127 newHist->minNum = 0; 114 128 newHist->maxNum = 0; … … 118 132 } 119 133 120 // When this is called, the number of data elements in bounds 121 // is n. Therefore, the number of bins is n-1. 134 /****************************************************************************** 135 psHistogramAlloc(lower, upper, n): allocate a non-uniform histogram structure 136 with the specifed bounds. The number of elements in the bounds vector is n. 137 Therefore, the number of bins is n-1. 138 Input: 139 bounds 140 Returns: 141 The histogram structure 142 *****************************************************************************/ 122 143 psHistogram *psHistogramAllocGeneric(const psVector *restrict bounds) 123 144 { 124 psHistogram *newHist = NULL; 125 int i; 145 psHistogram *newHist = NULL; // The new histogram structure 146 int i; // Loop index variable 126 147 127 148 // GUS: Verify that this is the correct action. … … 131 152 } 132 153 154 // GUS: Verify that this is the correct action. 155 if (bounds->n <= 1) { 156 // psAbort(__func__, "psHistogram requested with NULL bounds"); 157 return(NULL); 158 } 159 160 // Allocate memory for the new histogram structure. 133 161 newHist = (psHistogram *) psAlloc(sizeof(psHistogram)); 134 162 newHist->bounds = psVectorAlloc(bounds->n, PS_TYPE_F32); … … 137 165 newHist->bounds->data.F32[i] = bounds->data.F32[i]; 138 166 } 167 168 // Allocate the bins, and initialize them to zero. If there are N bounds, 169 // then there are N-1 bins. 139 170 newHist->nums = psVectorAlloc((bounds->n)-1, PS_TYPE_S32); 140 171 newHist->nums->n = newHist->nums->nalloc; … … 143 174 } 144 175 176 // Initialize the other members. 145 177 newHist->minNum = 0; 146 178 newHist->maxNum = 0; … … 159 191 160 192 /***************************************************************************** 161 NOTE: Can we assume fixed size bins in the myHist data structure? 193 psHistogramVector(out, in, mask, maskVal): this procedure takes as input a 194 preallocated and initialized histogram structure. It fills the bins in that 195 histogram structure in accordance with the input data "in" and the, possibly 196 NULL, mask vector. 162 197 163 NOTE: This procedure assumes that the following has been already set 164 myHist->lower 165 myHist->upper 166 myHist->minVal 167 myHist->maxVal 168 This procedure sets 169 myHist->nums 170 myHist->minNum 171 myHist->maxNum 198 Inputs: 199 out 200 in 201 mask 202 maskVal 203 Returns: 204 The histogram structure "out". 172 205 *****************************************************************************/ 173 206 psHistogram *psHistogramVector(psHistogram *out, 174 psVector *in,175 psVector *mask,207 const psVector *restrict in, 208 const psVector *restrict mask, 176 209 int maskVal) 177 210 { 178 int i = 0; 179 int j = 0; 180 float binSize = 0.0; 181 int binNum = 0; 182 int numBins = 0; 211 int i = 0; // Loop index variable 212 int j = 0; // Loop index variable 213 float binSize = 0.0; // Histogram bin size 214 int binNum = 0; // A temporary bin number 215 int numBins = 0; // The total number of bins 183 216 184 217 // GUS: Verify that this is the correct action. 185 218 if (out == NULL) { 186 // psAbort(__func__, "psHistogram requested with NULL struct");187 219 return(NULL); 188 220 } … … 190 222 // GUS: Verify that this is the correct action. 191 223 if (in == NULL) { 192 // psAbort(__func__, "psHistogram requested with NULL struct");193 224 return(out); 194 225 } 195 226 227 if (in->type.type != PS_TYPE_F32) { 228 psAbort(__func__, 229 "Only data type PS_TYPE_F32 is currently supported (0x%x).", 230 in->type.type); 231 } 232 233 if (mask != NULL) { 234 if (in->n != mask->n) { 235 psAbort(__func__, 236 "Vector data and vector mask are of different sizes."); 237 } 238 if (mask->type.type != PS_TYPE_U8) { 239 psAbort(__func__, "Vector mask must be type PS_TYPE_U8"); 240 } 241 } 242 // GUS: determine the correct action for a variety of other cases: 243 // in vector has 0 elements, and histogram structure has zero bins. 244 196 245 numBins = out->nums->n; 197 246 198 if (mask != NULL) { 199 for (i=0;i<in->n;i++) { 200 // Check if this pixel is masked, and if so, skip it. 201 if (!(mask->data.U8[i] & maskVal)) { 202 // Check if this pixel is below the minimum value, and if so 203 // count it, then skip it. 204 if (in->data.F32[i] < out->bounds->data.F32[0]) { 205 out->minNum++; 206 207 // Check if this pixel is above the maximum value, and if so 208 // count it, then skip it. 209 } else if (in->data.F32[i] > out->bounds->data.F32[numBins]) { 210 out->maxNum++; 211 } else { 212 // If this is a uniform histogram, determining the correct 213 // number is trivial. 214 if (out->uniform == true) { 215 binSize = out->bounds->data.F32[1] - out->bounds->data.F32[0]; 216 217 binNum = (int) ((in->data.F32[i] - out->bounds->data.F32[0]) / 218 binSize); 219 (out->nums->data.S32[binNum])++; 220 // If this is a non-uniform histogram, determining the correct 221 // bin number requires a bit more work. 222 } else { 223 // GUS: This is slow. Put a smarter algorithm here to 224 // find the correct bin number (bin search, probably) 225 for (j=0;j<(out->bounds->n)-1;j++) { 226 if ((out->bounds->data.S32[j] <= in->data.F32[i]) && 227 (in->data.F32[i] <= out->bounds->data.S32[j+1])) { 228 (out->nums->data.S32[j])++; 229 } 230 } 231 } 232 } 233 } 234 } 235 } else { 236 for (i=0;i<in->n;i++) { 247 for (i=0;i<in->n;i++) { 248 // Check if this pixel is masked, and if so, skip it. 249 if ((mask == NULL) || 250 ((mask != NULL) && (!(mask->data.U8[i] & maskVal)))) { 251 // Check if this pixel is below the minimum value, and if so 252 // count it, then skip it. 237 253 if (in->data.F32[i] < out->bounds->data.F32[0]) { 238 // Check if this pixel is below the minimum value, and if so239 // count it, then skip it.240 254 out->minNum++; 241 } else if (in->data.F32[i] > out->bounds->data.F32[numBins]) {242 255 // Check if this pixel is above the maximum value, and if so 243 256 // count it, then skip it. 257 } else if (in->data.F32[i] > out->bounds->data.F32[numBins]) { 244 258 out->maxNum++; 245 259 } else { … … 251 265 binNum = (int) ((in->data.F32[i] - out->bounds->data.F32[0]) / 252 266 binSize); 253 (out->nums->data.S32[binNum])++;254 255 267 // If this is a non-uniform histogram, determining the correct 256 268 // bin number requires a bit more work. … … 267 279 } 268 280 } 269 270 281 } 271 282 return(out); 272 283 } 273 284 274 void p_printVector(psVector *myVector, 275 psVector *maskVector, 276 unsigned int maskVal, 277 psStats *stats) 278 { 279 int i = 0; 285 /***************************************************************************** 286 p_psVectorPrint(myVector, maskVector, maskVal, stats): a private internal 287 function that simply prints a vector to STDOUT. Used primarily for 288 debugging. 289 *****************************************************************************/ 290 291 void p_psVectorPrint(psVector *myVector, 292 psVector *maskVector, 293 unsigned int maskVal, 294 psStats *stats) 295 { 296 int i = 0; // Loop index variable. 280 297 281 298 for (i=0;i<myVector->n;i++) { … … 291 308 ****************************************************************************** 292 309 ****************************************************************************** 293 MISC STATISTICAL FUNCTIONS 310 MISC PRIVATE STATISTICAL FUNCTIONS 311 312 NOTE: it is assumed that any call to these statistical functions will 313 have been preceded by a call to the psVectorStats() function. Various 314 sanity tests will only be performed in psVectorStats(). 315 Is the mask vector the same length as the data vector? 316 Is the mask vector of type PS_TYPE_U8? 317 Is the stats data structure NULL? 318 Is the in data structure NULL? 319 Is the in data structure of type PS_TYPE_F32? 294 320 ****************************************************************************** 295 321 ****************************************************************************** … … 298 324 299 325 /****************************************************************************** 300 ASSUMPTION: the mean is always calculated exactly. Robust means are never 301 calculated in this routine. 326 p_psVectorSampleMean(myVector, maskVector, maskVal, stats): calculates the 327 mean of the input vector. 328 Inputs 329 Returns 330 NULL 331 ASSUMPTION: the mean is always calculated exactly. Robust means are never 332 calculated in this routine. 302 333 *****************************************************************************/ 303 334 void p_psVectorSampleMean(const psVector *restrict myVector, … … 306 337 psStats *stats) 307 338 { 308 int i = 0; 309 float mean = 0.0; 310 int count = 0; 311 float rangeMin = 0.0; 312 float rangeMax = 0.0; 313 339 int i = 0; // Loop index variable 340 float mean = 0.0; // The mean 341 int count = 0; // # of points in this mean? 342 float rangeMin = 0.0; // Exclude data below this 343 float rangeMax = 0.0; // Exclude date above this 344 345 // If PS_STAT_USE_RANGE is requested, then we enter a slightly different 346 // loop. 314 347 if (stats->options & PS_STAT_USE_RANGE) { 315 348 rangeMin = stats->min; … … 317 350 if (maskVector != NULL) { 318 351 for (i=0;i<myVector->n;i++) { 352 // Check if the data is with the specified range 319 353 if (!(maskVal & maskVector->data.U8[i]) && 320 354 (rangeMin <= myVector->data.F32[i]) && … … 355 389 } 356 390 391 /****************************************************************************** 392 p_psVectorSampleMax(myVector, maskVector, maskVal, stats): calculates the 393 max of the input vector. 394 Inputs 395 myVector 396 maskVector 397 maskVal 398 stats 399 Returns 400 NULL 401 *****************************************************************************/ 357 402 void p_psVectorMax(const psVector *restrict myVector, 358 403 const psVector *restrict maskVector, … … 360 405 psStats *stats) 361 406 { 362 int i = 0; 363 float max = -MYMAXFLOAT; 364 float rangeMin = 0.0; 365 float rangeMax = 0.0; 366 407 int i = 0; // Loop index variable 408 float max = -MYMAXFLOAT; // The calculated maximum 409 float rangeMin = 0.0; // Exclude data below this 410 float rangeMax = 0.0; // Exclude date above this 411 412 // If PS_STAT_USE_RANGE is requested, then we enter a different loop. 367 413 if (stats->options & PS_STAT_USE_RANGE) { 368 414 rangeMin = stats->min; … … 408 454 } 409 455 456 /****************************************************************************** 457 p_psVectorSampleMin(myVector, maskVector, maskVal, stats): calculates the 458 minimum of the input vector. 459 Inputs 460 myVector 461 maskVector 462 maskVal 463 stats 464 Returns 465 NULL 466 *****************************************************************************/ 410 467 void p_psVectorMin(const psVector *restrict myVector, 411 468 const psVector *restrict maskVector, … … 413 470 psStats *stats) 414 471 { 415 int i = 0; 416 float min = MYMAXFLOAT; 417 float rangeMin = 0.0; 418 float rangeMax = 0.0; 472 int i = 0; // Loop index variable 473 float min = MYMAXFLOAT; // The calculated maximum 474 float rangeMin = 0.0; // Exclude data below this 475 float rangeMax = 0.0; // Exclude date above this 419 476 420 477 if (stats->options & PS_STAT_USE_RANGE) { … … 462 519 463 520 /****************************************************************************** 464 This routine calculates the number of non-masked pixels in the vector. 465 that fall within the min/max range, if given. 521 p_psVectorSampleMax(myVector, maskVector, maskVal, stats): calculates the 522 number of non-masked pixels in the vector. that fall within the min/max 523 range, if given. 524 Inputs 525 myVector 526 maskVector 527 maskVal 528 stats 529 Returns 530 NULL 466 531 *****************************************************************************/ 467 532 int p_psVectorNValues(const psVector *restrict myVector, … … 470 535 psStats *stats) 471 536 { 472 int i = 0; 473 int numData = 0; 474 float rangeMin = 0.0; 475 float rangeMax = 0.0; 537 int i = 0; // Loop index variable 538 int numData = 0; // The number of data points 539 float rangeMin = 0.0; // Exclude data below this 540 float rangeMax = 0.0; // Exclude date above this 476 541 477 542 if (stats->options & PS_STAT_USE_RANGE) { … … 512 577 513 578 579 /****************************************************************************** 580 p_psVectorSampleMedian(myVector, maskVector, maskVal, stats): calculates the 581 median of the input vector. 582 Inputs 583 myVector 584 maskVector 585 maskVal 586 stats 587 Returns 588 NULL 589 *****************************************************************************/ 514 590 void p_psVectorSampleMedian(const psVector *restrict myVector, 515 591 const psVector *restrict maskVector, … … 517 593 psStats *stats) 518 594 { 519 psVector *unsortedVector = NULL; 520 psVector *sortedVector = NULL; 521 int count = 0;522 int i = 0;523 int nValues = 0; 524 float rangeMin = 0.0; 525 float rangeMax = 0.0; 526 psStats *stats2 = NULL; 595 psVector *unsortedVector = NULL; // Temporary vector 596 psVector *sortedVector = NULL; // Temporary vector 597 int i = 0; // Loop index variable 598 int count = 0; // # of points in this mean? 599 int nValues = 0; // # of points in vector 600 float rangeMin = 0.0; // Exclude data below this 601 float rangeMax = 0.0; // Exclude date above this 602 psStats *stats2 = NULL; // Temporary stats structure 527 603 528 604 … … 531 607 532 608 if (myVector->n > stats->sampleLimit) { 609 psAbort(__func__, "Robust Statistic Algorithms have not yet been defined or implemented."); 610 533 611 // Calculate the robust quartiles. 534 612 stats2 = psStatsAlloc(PS_STAT_ROBUST_MEDIAN); … … 548 626 549 627 // Determine how many data points fit inside this min/max range 550 // and are not ma xed, IF the maskVector is not NULL>628 // and are not masked, IF the maskVector is not NULL> 551 629 nValues = p_psVectorNValues(myVector, maskVector, maskVal, stats); 552 630 … … 620 698 float sigma) 621 699 { 622 int i = 0; 623 int j = 0; 624 float tmpf = 0.0; 625 float gaussianCoefs[1 + (2 * GAUSS_WIDTH)]; 626 // The coefficients used in the histogram 627 // smoothing calculation. 700 int i = 0; // Loop index variable 701 int j = 0; // Loop index variable 702 float tmpf = 0.0; // Temporary variable 703 float gaussianCoefs[1 + (2 * GAUSS_WIDTH)]; // The Gaussian Coefficients 628 704 629 705 for(i=0;i<(1 + (2 * GAUSS_WIDTH));i++) { … … 631 707 // If sigma does not equal zero, then we use Gaussian smoothing. 632 708 #ifdef DARWIN 633 tmpf = (float) sqrt(2.0f * PI * sigma * sigma);709 tmpf = (float) sqrt(2.0f * M_PI * sigma * sigma); 634 710 #else 635 711 636 tmpf = sqrtf(2.0f * PI * sigma * sigma);712 tmpf = sqrtf(2.0f * M_PI * sigma * sigma); 637 713 #endif 638 714 639 715 gaussianCoefs[i] = (float) exp( (-((float) (i-GAUSS_WIDTH)) * 640 716 ((float) (i-GAUSS_WIDTH))) / 641 (2.0f * sigma * sigma)) / 642 tmpf; 717 (2.0f * sigma * sigma)) / tmpf; 643 718 } else { 644 719 /* If sigma equals zero (all pixels have the same value) 645 * the above code will divide by zero. Therefore, we instead646 * use boxcar smoothing.720 * the above code will divide by zero. Therefore, we don't need 721 * to smooth the data. 647 722 */ 648 gaussianCoefs[i] = 1.0f / (1.0f + (2.0f * (float) GAUSS_WIDTH));723 return; 649 724 } 650 725 } … … 662 737 663 738 /****************************************************************************** 664 p_psVectorSampleQuartiles() 665 This procedure calculates the upper and/or lower quartiles of the 666 data set. 667 739 p_psVectorSampleQuartiles(myVector, maskVector, maskVal, stats): calculates 740 the upper and/or lower quartiles of the input vector. 741 Inputs 742 myVector 743 maskVector 744 maskVal 745 stats 746 Returns 747 NULL 668 748 *****************************************************************************/ 669 749 void p_psVectorSampleQuartiles(const psVector *restrict myVector, … … 672 752 psStats *stats) 673 753 { 674 psVector *unsortedVector = NULL; 675 psVector *sortedVector = NULL; 676 int count = 0; 677 int ind = 0; 678 int i = 0; 679 int nValues = 0; 680 float rangeMin = 0.0; 681 float rangeMax = 0.0; 754 psVector *unsortedVector = NULL; // Temporary vector 755 psVector *sortedVector = NULL; // Temporary vector 756 int i = 0; // Loop index variable 757 int count = 0; // # of points in this mean? 758 int nValues = 0; // # data points 759 float rangeMin = 0.0; // Exclude data below this 760 float rangeMax = 0.0; // Exclude date above this 682 761 683 762 // Determine if the number of data points exceed a threshold which will 684 763 // cause to generate robust stats, as opposed to exact stats. 685 /* GUS: When IfA provides the algorithm, insert is here. 686 if (myVector->n > stats->sampleLimit) { 687 psStats *stats2 = NULL; 688 // Calculate the robust quartiles. 689 stats2 = psStatsAlloc(PS_STAT_ROBUST_QUARTILE); 690 p_psVectorRobustStats(myVector, maskVector, maskVal, stats2); 691 692 // Store the robust quartiles into the sample quartile members. 693 stats->sampleUQ = stats2->robustUQ; 694 stats->sampleLQ = stats2->robustLQ; 695 696 // Free temporary data buffers. 697 psStatsFree(stats2); 698 699 // Set the PS_STAT_ROBUST_FOR_SAMPLE bit in the stats structure. 700 stats->options = stats->options | PS_STAT_ROBUST_FOR_SAMPLE; 701 702 return; 703 } 704 */ 764 if (myVector->n > stats->sampleLimit) { 765 psAbort(__func__, "Robust Statistic Algorithms have not yet been defined or implemented."); 766 psStats *stats2 = NULL; 767 // Calculate the robust quartiles. 768 stats2 = psStatsAlloc(PS_STAT_ROBUST_QUARTILE); 769 p_psVectorRobustStats(myVector, maskVector, maskVal, stats2); 770 771 // Store the robust quartiles into the sample quartile members. 772 stats->sampleUQ = stats2->robustUQ; 773 stats->sampleLQ = stats2->robustLQ; 774 775 // Free temporary data buffers. 776 psStatsFree(stats2); 777 778 // Set the PS_STAT_ROBUST_FOR_SAMPLE bit in the stats structure. 779 stats->options = stats->options | PS_STAT_ROBUST_FOR_SAMPLE; 780 781 return; 782 } 705 783 706 784 // Determine how many data points fit inside this min/max range … … 757 835 758 836 // Calculate the quartile points exactly. 759 ind = 3 * (nValues / 4); 760 stats->sampleUQ = sortedVector->data.F32[ind]; 761 ind = (nValues / 4); 762 stats->sampleLQ = sortedVector->data.F32[ind]; 837 stats->sampleUQ = sortedVector->data.F32[3 * (nValues / 4)]; 838 stats->sampleLQ = sortedVector->data.F32[nValues / 4]; 763 839 764 840 // Free the temporary data structures. … … 770 846 771 847 /****************************************************************************** 772 p_psVectorRobustStats(): this procedure calculates a variety of robust 773 stat measures:848 p_psVectorRobustStats(myVector, maskVector, maskVal, stats): this procedure 849 calculates a variety of robust stat measures: 774 850 PS_STAT_ROBUST_MEAN 775 851 PS_STAT_ROBUST_MEDIAN … … 784 860 measures were calcualted in separate functiosn, then much of the initial 785 861 processing would be duplicated. 862 Inputs 863 myVector 864 maskVector 865 maskVal 866 stats 867 Returns 868 NULL 786 869 *****************************************************************************/ 787 870 void p_psVectorRobustStats(const psVector *restrict myVector, … … 791 874 { 792 875 psHistogram *robustHistogram = NULL; 793 float binSize = 0.0; 876 float binSize = 0.0; // Size of the histogram bins 794 877 float sigmaE = 0.0; 795 int LQBinNum = -1; 796 int UQBinNum = -1; 797 int i = 0; // Loop index variable.878 int LQBinNum = -1; // Bin num for lower quartile 879 int UQBinNum = -1; // Bin num for upper quartile 880 int i = 0; // Loop index variable 798 881 int maxBinNum = 0; 799 882 int maxBinCount = 0; 800 883 float dL = 0.0; 884 int numBins = 0; 801 885 802 886 // NOTE: The SDRS states that the sample quartiles must be used to … … 827 911 } 828 912 829 // Create the histogram structure. 913 // Create the histogram structure (yes, 2 is necessary, not 1). 914 numBins = 2 + (int) ((stats->max - stats->min) / binSize); 915 830 916 robustHistogram = psHistogramAlloc(stats->min, 831 917 stats->max, 832 1 + (int) ((stats->max - stats->min) / binSize)); 833 834 918 numBins); 835 919 // Populate the histogram array. 836 // GUS: fix this 837 // robustHistogram = psHistogramVector(robustHistogram, myVector); 838 // 920 psHistogramVector(robustHistogram, myVector, maskVector, maskVal); 839 921 840 922 // Smooth the histogram. … … 868 950 869 951 // Fit a Gaussian to the bins in the range MODE-dL to Mode+dL 870 // What algorithm should I use to do this? 871 872 // The resulting fit parameters are the robust mean, mean_r, and sigma 873 // What is the mean_r? 952 // GUS: This step is dependent on the functions in psMinimize.c being 953 // implemented. Currently, they are not. 874 954 875 955 if (stats->options & PS_STAT_ROBUST_MEAN) { … … 895 975 } 896 976 897 /***************************************************************************** 898 NOTE: This function assumes that p_psVectorMean() has already been called 899 and the correct value is stored in stats->sampleMean. 977 /****************************************************************************** 978 p_psVectorSampleStdev(myVector, maskVector, maskVal, stats): calculates the 979 stdev of the input vector. 980 Inputs 981 myVector 982 maskVector 983 maskVal 984 stats 985 Returns 986 NULL 900 987 901 NOTE: the mean is always calculated exactly. Robust means are never902 calculated in this routine.988 NOTE: the mean is always calculated exactly. Robust means are never 989 calculated in this routine. 903 990 *****************************************************************************/ 904 991 void p_psVectorSampleStdev(const psVector *restrict myVector, … … 907 994 psStats *stats) 908 995 { 909 int i = 0; 910 int countInt = 0; 911 float countFloat = 0.0; 912 float mean = 0.0; 913 float diff = 0.0; 914 float sumSquares = 0.0; 915 float sumDiffs = 0.0; 916 float rangeMin = 0.0; 917 float rangeMax = 0.0; 918 996 int i = 0; // Loop index variable 997 int countInt = 0; // # of data points being used 998 float countFloat = 0.0; // # of data points being used 999 float mean = 0.0; // The mean 1000 float diff = 0.0; // Used in calculating stdev 1001 float sumSquares = 0.0; // temporary variable 1002 float sumDiffs = 0.0; // temporary variable 1003 float rangeMin = 0.0; // Exclude data below this 1004 float rangeMax = 0.0; // Exclude date above this 1005 1006 // This procedure requires the mean. If it has not been already 1007 // calculated, then call p_psVectorSampleMean() 919 1008 if (0 != isnan(stats->sampleMean)) { 920 1009 p_psVectorSampleMean(myVector, maskVector, maskVal, stats); … … 979 1068 } 980 1069 1070 /****************************************************************************** 1071 p_psVectorClippedStats(myVector, maskVector, maskVal, stats): calculates the 1072 clipped stats (mean or stdev) of the input vector. 1073 1074 Inputs 1075 myVector 1076 maskVector 1077 maskVal 1078 stats 1079 Returns 1080 NULL 1081 *****************************************************************************/ 981 1082 void p_psVectorClippedStats(const psVector *restrict myVector, 982 1083 const psVector *restrict maskVector, … … 984 1085 psStats *stats) 985 1086 { 986 int i = 0; 987 int j = 0; 988 float clippedMean = 0.0; 989 float clippedStdev = 0.0; 990 psVector *tmpMask = NULL; 991 1087 int i = 0; // Loop index variable 1088 int j = 0; // Loop index variable 1089 float clippedMean = 0.0; // self-explanatory 1090 float clippedStdev = 0.0; // self-explanatory 1091 float oldStanMean = 0.0; // Temporary variable 1092 float oldStanStdev = 0.0; // Temporary variable 1093 psVector *tmpMask = NULL; // Temporary vector 1094 1095 // Endure that stats->clipIter is within the proper range. 992 1096 if (!((CLIPPED_NUM_ITER_LB <= stats->clipIter ) && 993 1097 (stats->clipIter <= CLIPPED_NUM_ITER_UB))) { … … 996 1100 } 997 1101 1102 // Endure that stats->clipSigma is within the proper range. 998 1103 if (!((CLIPPED_SIGMA_LB <= stats->clipSigma ) && 999 1104 (stats->clipSigma <= CLIPPED_SIGMA_UB))) { … … 1002 1107 } 1003 1108 1004 1109 // We allocate a temporary mask vector since during the iterative 1110 // steps that follow, we will be masking off additional data points. 1111 // However, we do no want to modify the original mask vector. 1005 1112 tmpMask = psVectorAlloc(myVector->n, PS_TYPE_U8); 1006 1113 tmpMask->n = myVector->n; 1007 1114 1115 // If we were called with a mask vector, then initialize the temporary 1116 // mask vector with those values. 1008 1117 if (maskVector != NULL) { 1009 1118 for (i=0;i<tmpMask->n;i++) { … … 1026 1135 clippedStdev = stats->sampleStdev; 1027 1136 1137 // Must save the old sampleMean and sampleStdev since the following code 1138 // block overwrites them. 1139 oldStanMean = stats->sampleMean; 1140 oldStanStdev = stats->sampleStdev; 1141 1028 1142 // 5. Repeat N times: 1029 1030 1143 for (i=0;i<stats->clipIter;i++) { 1031 // printf("p_psVectorClippedStats(): Iteration %d (%f %f)\n", i,1032 // clippedMean, clippedStdev);1033 1144 for (j=0;j<myVector->n;j++) { 1034 1145 // a) Exclude all values x_i for which |x_i - x| > K * stdev … … 1038 1149 } 1039 1150 // b) compute new mean and stdev 1040 // GUS: I should probably create a new struct here since the1041 // following calls will overwrite any old values in sampleMean.1042 1151 p_psVectorSampleMedian(myVector, tmpMask, maskVal, stats); 1043 1152 p_psVectorSampleStdev(myVector, tmpMask, maskVal, stats); … … 1050 1159 } 1051 1160 } 1161 stats->sampleMean = oldStanMean; 1162 stats->sampleStdev= oldStanStdev; 1052 1163 1053 1164 // 7. The last calcuated value of x is the cliped mean. … … 1066 1177 1067 1178 /****************************************************************************** 1179 psVectorStats(myVector, maskVector, maskVal, stats): this is the public API 1180 function which calls the above private stats functions based on what bits 1181 were set in stats->options. 1068 1182 1069 NOTE: The current strategy is to implement everything assuming that all 1070 input data is of type PS_TYPE_F32. Once the basic code is in place, 1071 we will macro-ize everything and add PS_TYPE_U16 and PS_TYPE_F64. 1183 Inputs 1184 myVector 1185 maskVector 1186 maskVal 1187 stats 1188 Returns 1189 The stats structure. 1072 1190 1191 NOTE: The current strategy is to implement everything assuming that all 1192 input data is of type PS_TYPE_F32. Once the basic code is in place, we will 1193 macro-ize everything and add PS_TYPE_U16 and PS_TYPE_F64. 1073 1194 *****************************************************************************/ 1074 1195 psStats *psVectorStats(psStats *stats, … … 1077 1198 unsigned int maskVal) 1078 1199 { 1200 // GUS: Verify that this is the correct action. 1079 1201 if (in == NULL) { 1080 1202 return(stats); … … 1084 1206 } 1085 1207 1208 // Ensure that the data is of type PS_TYPE_F32. Eventually, more data 1209 // types will be implemented. 1086 1210 if (in->type.type != PS_TYPE_F32) { 1087 1211 psAbort(__func__, … … 1090 1214 } 1091 1215 1216 // Ensure that the mask vector is of the proper size and type. 1092 1217 if (mask != NULL) { 1093 1218 if (in->n != mask->n) { … … 1124 1249 } 1125 1250 1251 // Since the various robust stats quantities share much computation, they 1252 // are grouped together in a single private function: 1253 // p_psVectorRobustStats() 1126 1254 if ((stats->options & PS_STAT_ROBUST_MEAN) || 1127 1255 (stats->options & PS_STAT_ROBUST_MEDIAN) || … … 1147 1275 } 1148 1276 1149 // OLD CODE: Should we check for an unknown option?1150 // default:1151 // psAbort(__func__, "Unknown options 0x%x.\n", stats->options);1152 1153 1277 return(stats); 1154 1278 } -
trunk/psLib/src/dataManip/psStats.h
r974 r1020 1 /** @file psStats.h 2 * \brief basic statistical operations 3 * @ingroup Stats 4 * 5 * This file will hold the definition of the histogram and stats data 6 * structures. It also contains prototypes for procedures which operate 7 * on those data structures. 8 * 9 * @author George Gusciora, MHPCC 10 * 11 * @version $Revision: 1.12 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-06-14 19:33:09 $ 13 * 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii 15 */ 1 16 #if !defined(PS_STATS_H) 2 17 #define PS_STATS_H 3 /****************************************************************************** 4 This file will histogram/statistical functions and data structures. 5 *****************************************************************************/ 6 /** \file psStats.h 7 * \brief basic statistical operations 8 * \ingroup Stats 9 */ 18 10 19 #include "psVector.h" 11 20 … … 36 45 37 46 38 /** This is the generic statistics structure */ 47 /** This is the generic statistics structure. It contails the data members 48 for the various statistic values. It contains the options member to 49 specifiy which statistics must be calculated. */ 39 50 typedef struct 40 51 { … … 74 85 ); 75 86 76 /** Constructor*/87 /** A constructor for the stats structure.*/ 77 88 psStats *psStatsAlloc(psStatsOptions options); ///< Statistics to measure 78 89 79 /** Destructor*/90 /** A destructor for the stats structure.*/ 80 91 void psStatsFree(psStats *restrict stats); ///< Stats structure to destroy 81 92 … … 83 94 Histogram functions and data structures. 84 95 *****************************************************************************/ 96 /** The basic histogram structure which contains bounds and bins. */ 85 97 typedef struct 86 98 { … … 111 123 /** Calculate a histogram \ingroup MathGroup **/ 112 124 psHistogram *psHistogramVector (psHistogram *out, ///< Histogram data 113 psVector *in, ///< Vector to analyse114 psVector *mask, ///< Mask dat for input vector125 const psVector *restrict in, ///< Vector to analyse 126 const psVector *restrict mask, ///< Mask dat for input vector 115 127 int maskVal); ///< Mask value 116 128 -
trunk/psLib/src/math/psPolynomial.c
r889 r1020 4 4 * routines. 5 5 * 6 * @author George Gusciora, MHPCC 6 * This file will hold the functions for allocated, freeing, and evaluating 7 * polynomials. It also contains a Gaussian functions. 7 8 * 8 * @version $Revision: 1.1 1$ $Name: not supported by cvs2svn $9 * @date $Date: 2004-06- 07 00:32:53$9 * @version $Revision: 1.12 $ $Name: not supported by cvs2svn $ 10 * @date $Date: 2004-06-14 19:32:42 $ 10 11 * 11 12 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 103 104 psPolynomial1D *psPolynomial1DAlloc(int n) 104 105 { 106 int i = 0; 105 107 psPolynomial1D *newPoly = NULL; 106 108 … … 110 112 newPoly->coeffErr = (float *) psAlloc(n * sizeof(float)); 111 113 newPoly->mask = (char *) psAlloc(n * sizeof(char)); 114 for (i=0;i<n;i++) { 115 newPoly->coeff[i] = 0.0; 116 newPoly->coeffErr[i] = 0.0; 117 newPoly->mask[i] = 0.0; 118 } 112 119 113 120 return(newPoly); … … 117 124 { 118 125 int x = 0; 126 int y = 0; 119 127 psPolynomial2D *newPoly = NULL; 120 128 … … 131 139 newPoly->mask[x] = (char *) psAlloc(nY * sizeof(char)); 132 140 } 133 141 for (x=0;x<nX;x++) { 142 for (y=0;y<nY;y++) { 143 newPoly->coeff[x][y] = 0.0; 144 newPoly->coeffErr[x][y] = 0.0; 145 newPoly->mask[x][y] = 0; 146 } 147 } 134 148 135 149 return(newPoly); … … 140 154 int x = 0; 141 155 int y = 0; 156 int z = 0; 142 157 psPolynomial3D *newPoly = NULL; 143 158 … … 160 175 } 161 176 } 177 for (x=0;x<nX;x++) { 178 for (y=0;y<nY;y++) { 179 for (z=0;z<nZ;z++) { 180 newPoly->coeff[x][y][z] = 0.0; 181 newPoly->coeffErr[x][y][z] = 0.0; 182 newPoly->mask[x][y][z] = 0; 183 } 184 } 185 } 162 186 163 187 return(newPoly); … … 169 193 int x = 0; 170 194 int y = 0; 195 int z = 0; 171 196 psPolynomial4D *newPoly = NULL; 172 197 … … 195 220 } 196 221 } 222 for (w=0;w<nW;w++) { 223 for (x=0;x<nX;x++) { 224 for (y=0;y<nY;y++) { 225 for (z=0;z<nZ;z++) { 226 newPoly->coeff[w][x][y][z] = 0.0; 227 newPoly->coeffErr[w][x][y][z] = 0.0; 228 newPoly->mask[w][x][y][z] = 0; 229 } 230 } 231 } 232 } 197 233 198 234 return(newPoly); … … 394 430 psDPolynomial1D *psDPolynomial1DAlloc(int n) 395 431 { 432 int i = 0; 396 433 psDPolynomial1D *newPoly = NULL; 397 434 … … 401 438 newPoly->coeffErr = (double *) psAlloc(n * sizeof(double)); 402 439 newPoly->mask = (char *) psAlloc(n * sizeof(char)); 440 for (i=0;i<n;i++) { 441 newPoly->coeff[i] = 0.0; 442 newPoly->coeffErr[i] = 0.0; 443 newPoly->mask[i] = 0.0; 444 } 403 445 404 446 return(newPoly); … … 408 450 { 409 451 int x = 0; 452 int y = 0; 410 453 psDPolynomial2D *newPoly = NULL; 411 454 … … 422 465 newPoly->mask[x] = (char *) psAlloc(nY * sizeof(char)); 423 466 } 467 for (x=0;x<nX;x++) { 468 for (y=0;y<nY;y++) { 469 newPoly->coeff[x][y] = 0.0; 470 newPoly->coeffErr[x][y] = 0.0; 471 newPoly->mask[x][y] = 0; 472 } 473 } 424 474 425 475 return(newPoly); … … 430 480 int x = 0; 431 481 int y = 0; 482 int z = 0; 432 483 psDPolynomial3D *newPoly = NULL; 433 484 … … 450 501 } 451 502 } 503 for (x=0;x<nX;x++) { 504 for (y=0;y<nY;y++) { 505 for (z=0;z<nZ;z++) { 506 newPoly->coeff[x][y][z] = 0.0; 507 newPoly->coeffErr[x][y][z] = 0.0; 508 newPoly->mask[x][y][z] = 0; 509 } 510 } 511 } 452 512 453 513 return(newPoly); … … 459 519 int x = 0; 460 520 int y = 0; 521 int z = 0; 461 522 psDPolynomial4D *newPoly = NULL; 462 523 … … 485 546 } 486 547 } 548 for (w=0;w<nW;w++) { 549 for (x=0;x<nX;x++) { 550 for (y=0;y<nY;y++) { 551 for (z=0;z<nZ;z++) { 552 newPoly->coeff[w][x][y][z] = 0.0; 553 newPoly->coeffErr[w][x][y][z] = 0.0; 554 newPoly->mask[w][x][y][z] = 0; 555 } 556 } 557 } 558 } 487 559 488 560 return(newPoly); -
trunk/psLib/src/math/psPolynomial.h
r974 r1020 1 /** @file psFunctions.h 2 * \brief Standard Mathematical Functions. 3 * \ingroup Stats 4 * 5 * This file will hold the prototypes for procedures which allocate, free, 6 * and evaluate various polynomials. Those polynomial structures are also 7 * defined here. 8 * 9 * @ingroup Stats 10 * 11 * @author Someone at IfA 12 * @author George Gusciora, MHPCC 13 * 14 * @version $Revision: 1.6 $ $Name: not supported by cvs2svn $ 15 * @date $Date: 2004-06-14 19:32:42 $ 16 * 17 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii 18 */ 19 1 20 #if !defined(PS_FUNCTIONS_H) 2 21 #define PS_FUNCTIONS_H 3 22 4 /** \file psFunctions.h5 * \brief Standard Mathematical Functions.6 * \ingroup Stats7 */8 23 9 24 /** \addtogroup Stats … … 23 38 24 39 25 psVector *psGaussianDev(float mean, 26 float sigma, 27 int Npts); 28 29 /*****************************************************************************/ 40 /** Produce a vector of random numbers from a Gaussian distribution with 41 the specified mean and sigma */ 42 psVector *psGaussianDev(float mean, ///< The mean of the Gaussian 43 float sigma, ///< The sigma of the Gaussian 44 int Npts); ///< The size of the vector 45 46 47 48 30 49 31 50 /** One-dimensional polynomial */ 32 51 typedef struct 33 52 { 34 int n; ///< Number of terms35 float *coeff; ///< Coefficients36 float *coeffErr; ///< Error in coefficients37 char *mask; ///< Coefficient mask53 int n; ///< Number of terms 54 float *coeff; ///< Coefficients 55 float *coeffErr; ///< Error in coefficients 56 char *mask; ///< Coefficient mask 38 57 } 39 58 psPolynomial1D; -
trunk/psLib/src/math/psSpline.c
r889 r1020 4 4 * routines. 5 5 * 6 * @author George Gusciora, MHPCC 6 * This file will hold the functions for allocated, freeing, and evaluating 7 * polynomials. It also contains a Gaussian functions. 7 8 * 8 * @version $Revision: 1.1 1$ $Name: not supported by cvs2svn $9 * @date $Date: 2004-06- 07 00:32:53$9 * @version $Revision: 1.12 $ $Name: not supported by cvs2svn $ 10 * @date $Date: 2004-06-14 19:32:42 $ 10 11 * 11 12 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 103 104 psPolynomial1D *psPolynomial1DAlloc(int n) 104 105 { 106 int i = 0; 105 107 psPolynomial1D *newPoly = NULL; 106 108 … … 110 112 newPoly->coeffErr = (float *) psAlloc(n * sizeof(float)); 111 113 newPoly->mask = (char *) psAlloc(n * sizeof(char)); 114 for (i=0;i<n;i++) { 115 newPoly->coeff[i] = 0.0; 116 newPoly->coeffErr[i] = 0.0; 117 newPoly->mask[i] = 0.0; 118 } 112 119 113 120 return(newPoly); … … 117 124 { 118 125 int x = 0; 126 int y = 0; 119 127 psPolynomial2D *newPoly = NULL; 120 128 … … 131 139 newPoly->mask[x] = (char *) psAlloc(nY * sizeof(char)); 132 140 } 133 141 for (x=0;x<nX;x++) { 142 for (y=0;y<nY;y++) { 143 newPoly->coeff[x][y] = 0.0; 144 newPoly->coeffErr[x][y] = 0.0; 145 newPoly->mask[x][y] = 0; 146 } 147 } 134 148 135 149 return(newPoly); … … 140 154 int x = 0; 141 155 int y = 0; 156 int z = 0; 142 157 psPolynomial3D *newPoly = NULL; 143 158 … … 160 175 } 161 176 } 177 for (x=0;x<nX;x++) { 178 for (y=0;y<nY;y++) { 179 for (z=0;z<nZ;z++) { 180 newPoly->coeff[x][y][z] = 0.0; 181 newPoly->coeffErr[x][y][z] = 0.0; 182 newPoly->mask[x][y][z] = 0; 183 } 184 } 185 } 162 186 163 187 return(newPoly); … … 169 193 int x = 0; 170 194 int y = 0; 195 int z = 0; 171 196 psPolynomial4D *newPoly = NULL; 172 197 … … 195 220 } 196 221 } 222 for (w=0;w<nW;w++) { 223 for (x=0;x<nX;x++) { 224 for (y=0;y<nY;y++) { 225 for (z=0;z<nZ;z++) { 226 newPoly->coeff[w][x][y][z] = 0.0; 227 newPoly->coeffErr[w][x][y][z] = 0.0; 228 newPoly->mask[w][x][y][z] = 0; 229 } 230 } 231 } 232 } 197 233 198 234 return(newPoly); … … 394 430 psDPolynomial1D *psDPolynomial1DAlloc(int n) 395 431 { 432 int i = 0; 396 433 psDPolynomial1D *newPoly = NULL; 397 434 … … 401 438 newPoly->coeffErr = (double *) psAlloc(n * sizeof(double)); 402 439 newPoly->mask = (char *) psAlloc(n * sizeof(char)); 440 for (i=0;i<n;i++) { 441 newPoly->coeff[i] = 0.0; 442 newPoly->coeffErr[i] = 0.0; 443 newPoly->mask[i] = 0.0; 444 } 403 445 404 446 return(newPoly); … … 408 450 { 409 451 int x = 0; 452 int y = 0; 410 453 psDPolynomial2D *newPoly = NULL; 411 454 … … 422 465 newPoly->mask[x] = (char *) psAlloc(nY * sizeof(char)); 423 466 } 467 for (x=0;x<nX;x++) { 468 for (y=0;y<nY;y++) { 469 newPoly->coeff[x][y] = 0.0; 470 newPoly->coeffErr[x][y] = 0.0; 471 newPoly->mask[x][y] = 0; 472 } 473 } 424 474 425 475 return(newPoly); … … 430 480 int x = 0; 431 481 int y = 0; 482 int z = 0; 432 483 psDPolynomial3D *newPoly = NULL; 433 484 … … 450 501 } 451 502 } 503 for (x=0;x<nX;x++) { 504 for (y=0;y<nY;y++) { 505 for (z=0;z<nZ;z++) { 506 newPoly->coeff[x][y][z] = 0.0; 507 newPoly->coeffErr[x][y][z] = 0.0; 508 newPoly->mask[x][y][z] = 0; 509 } 510 } 511 } 452 512 453 513 return(newPoly); … … 459 519 int x = 0; 460 520 int y = 0; 521 int z = 0; 461 522 psDPolynomial4D *newPoly = NULL; 462 523 … … 485 546 } 486 547 } 548 for (w=0;w<nW;w++) { 549 for (x=0;x<nX;x++) { 550 for (y=0;y<nY;y++) { 551 for (z=0;z<nZ;z++) { 552 newPoly->coeff[w][x][y][z] = 0.0; 553 newPoly->coeffErr[w][x][y][z] = 0.0; 554 newPoly->mask[w][x][y][z] = 0; 555 } 556 } 557 } 558 } 487 559 488 560 return(newPoly); -
trunk/psLib/src/math/psSpline.h
r974 r1020 1 /** @file psFunctions.h 2 * \brief Standard Mathematical Functions. 3 * \ingroup Stats 4 * 5 * This file will hold the prototypes for procedures which allocate, free, 6 * and evaluate various polynomials. Those polynomial structures are also 7 * defined here. 8 * 9 * @ingroup Stats 10 * 11 * @author Someone at IfA 12 * @author George Gusciora, MHPCC 13 * 14 * @version $Revision: 1.6 $ $Name: not supported by cvs2svn $ 15 * @date $Date: 2004-06-14 19:32:42 $ 16 * 17 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii 18 */ 19 1 20 #if !defined(PS_FUNCTIONS_H) 2 21 #define PS_FUNCTIONS_H 3 22 4 /** \file psFunctions.h5 * \brief Standard Mathematical Functions.6 * \ingroup Stats7 */8 23 9 24 /** \addtogroup Stats … … 23 38 24 39 25 psVector *psGaussianDev(float mean, 26 float sigma, 27 int Npts); 28 29 /*****************************************************************************/ 40 /** Produce a vector of random numbers from a Gaussian distribution with 41 the specified mean and sigma */ 42 psVector *psGaussianDev(float mean, ///< The mean of the Gaussian 43 float sigma, ///< The sigma of the Gaussian 44 int Npts); ///< The size of the vector 45 46 47 48 30 49 31 50 /** One-dimensional polynomial */ 32 51 typedef struct 33 52 { 34 int n; ///< Number of terms35 float *coeff; ///< Coefficients36 float *coeffErr; ///< Error in coefficients37 char *mask; ///< Coefficient mask53 int n; ///< Number of terms 54 float *coeff; ///< Coefficients 55 float *coeffErr; ///< Error in coefficients 56 char *mask; ///< Coefficient mask 38 57 } 39 58 psPolynomial1D; -
trunk/psLib/src/math/psStats.c
r978 r1020 15 15 16 16 #include "float.h" 17 #define ROBUST_SIZE_THRESHOLD 30000 // Vectors that are large than this17 #define DEFAULT_ROBUST_SIZE_THRESHOLD 30000 // Vectors that are large than this 18 18 // will use robust statistical methods. 19 #define GAUSS_WIDTH 20 // The width of the Gaussian or boxcar 20 // smoothing. 21 #define PI 3.141592653 19 #define GAUSS_WIDTH 20 // The width of the Gaussian or boxcar smoothing. 22 20 #define CLIPPED_NUM_ITER_LB 1 23 21 #define CLIPPED_NUM_ITER_UB 10 … … 26 24 #define true 1 27 25 #define false 0 28 #define MYMAXFLOAT 1e9926 #define MYMAXFLOAT HUGE 29 27 30 28 #ifndef DOXYGEN … … 48 46 newStruct->sampleUQ = NAN; 49 47 newStruct->sampleLQ = NAN; 50 newStruct->sampleLimit = ROBUST_SIZE_THRESHOLD;48 newStruct->sampleLimit = DEFAULT_ROBUST_SIZE_THRESHOLD; 51 49 newStruct->robustMean = NAN; 52 50 newStruct->robustMedian = NAN; … … 78 76 79 77 /****************************************************************************** 80 HISTOGRAM FUNCTIONS 78 psHistogramAlloc(lower, upper, n): allocate a uniform histogram structure 79 with the specifed upper and lower limits, and the specifed number of bins. 80 This routine will also set the bounds for each of the bins. 81 82 Input: 83 lower 84 upper 85 n 86 Returns: 87 The histogram structure 81 88 *****************************************************************************/ 82 89 psHistogram *psHistogramAlloc(float lower, … … 84 91 int n) 85 92 { 86 int i = 0; 87 psHistogram *newHist = NULL; 88 float binSize = 0.0; 89 93 int i = 0; // Loop index variable 94 psHistogram *newHist = NULL; // The new histogram structure 95 float binSize = 0.0; // The histogram bin size 96 97 // GUS: Verify that this is the correct action. 90 98 if (n == 0) { 91 psAbort(__func__, "psHistogram requested with 0 bins");99 return(NULL); 92 100 } 93 101 94 102 // GUS: Verify that this is the correct action. 95 103 if (lower > upper) { 96 // psAbort(__func__, "psHistogram requested with lower>upper");97 104 return(NULL); 98 105 } 99 106 107 // Allocate memory for the new histogram structure. If there are N 108 // bins, then there are N+1 bounds to those bins. 100 109 newHist = (psHistogram *) psAlloc(sizeof(psHistogram)); 101 110 newHist->bounds = psVectorAlloc(n+1, PS_TYPE_F32); 102 111 newHist->bounds->n = newHist->bounds->nalloc; 103 112 113 // Calculate the bounds for each bin. 104 114 binSize = (upper - lower) / (float) n; 105 115 for (i=0;i<n+1;i++) { 106 116 newHist->bounds->data.F32[i] = lower + (binSize * (float) i); 107 117 } 118 119 // Allocate the bins, and initialize them to zero. 108 120 newHist->nums = psVectorAlloc(n, PS_TYPE_S32); 109 121 newHist->nums->n = newHist->nums->nalloc; … … 111 123 newHist->nums->data.S32[i] = 0; 112 124 } 125 126 // Initialize the other members. 113 127 newHist->minNum = 0; 114 128 newHist->maxNum = 0; … … 118 132 } 119 133 120 // When this is called, the number of data elements in bounds 121 // is n. Therefore, the number of bins is n-1. 134 /****************************************************************************** 135 psHistogramAlloc(lower, upper, n): allocate a non-uniform histogram structure 136 with the specifed bounds. The number of elements in the bounds vector is n. 137 Therefore, the number of bins is n-1. 138 Input: 139 bounds 140 Returns: 141 The histogram structure 142 *****************************************************************************/ 122 143 psHistogram *psHistogramAllocGeneric(const psVector *restrict bounds) 123 144 { 124 psHistogram *newHist = NULL; 125 int i; 145 psHistogram *newHist = NULL; // The new histogram structure 146 int i; // Loop index variable 126 147 127 148 // GUS: Verify that this is the correct action. … … 131 152 } 132 153 154 // GUS: Verify that this is the correct action. 155 if (bounds->n <= 1) { 156 // psAbort(__func__, "psHistogram requested with NULL bounds"); 157 return(NULL); 158 } 159 160 // Allocate memory for the new histogram structure. 133 161 newHist = (psHistogram *) psAlloc(sizeof(psHistogram)); 134 162 newHist->bounds = psVectorAlloc(bounds->n, PS_TYPE_F32); … … 137 165 newHist->bounds->data.F32[i] = bounds->data.F32[i]; 138 166 } 167 168 // Allocate the bins, and initialize them to zero. If there are N bounds, 169 // then there are N-1 bins. 139 170 newHist->nums = psVectorAlloc((bounds->n)-1, PS_TYPE_S32); 140 171 newHist->nums->n = newHist->nums->nalloc; … … 143 174 } 144 175 176 // Initialize the other members. 145 177 newHist->minNum = 0; 146 178 newHist->maxNum = 0; … … 159 191 160 192 /***************************************************************************** 161 NOTE: Can we assume fixed size bins in the myHist data structure? 193 psHistogramVector(out, in, mask, maskVal): this procedure takes as input a 194 preallocated and initialized histogram structure. It fills the bins in that 195 histogram structure in accordance with the input data "in" and the, possibly 196 NULL, mask vector. 162 197 163 NOTE: This procedure assumes that the following has been already set 164 myHist->lower 165 myHist->upper 166 myHist->minVal 167 myHist->maxVal 168 This procedure sets 169 myHist->nums 170 myHist->minNum 171 myHist->maxNum 198 Inputs: 199 out 200 in 201 mask 202 maskVal 203 Returns: 204 The histogram structure "out". 172 205 *****************************************************************************/ 173 206 psHistogram *psHistogramVector(psHistogram *out, 174 psVector *in,175 psVector *mask,207 const psVector *restrict in, 208 const psVector *restrict mask, 176 209 int maskVal) 177 210 { 178 int i = 0; 179 int j = 0; 180 float binSize = 0.0; 181 int binNum = 0; 182 int numBins = 0; 211 int i = 0; // Loop index variable 212 int j = 0; // Loop index variable 213 float binSize = 0.0; // Histogram bin size 214 int binNum = 0; // A temporary bin number 215 int numBins = 0; // The total number of bins 183 216 184 217 // GUS: Verify that this is the correct action. 185 218 if (out == NULL) { 186 // psAbort(__func__, "psHistogram requested with NULL struct");187 219 return(NULL); 188 220 } … … 190 222 // GUS: Verify that this is the correct action. 191 223 if (in == NULL) { 192 // psAbort(__func__, "psHistogram requested with NULL struct");193 224 return(out); 194 225 } 195 226 227 if (in->type.type != PS_TYPE_F32) { 228 psAbort(__func__, 229 "Only data type PS_TYPE_F32 is currently supported (0x%x).", 230 in->type.type); 231 } 232 233 if (mask != NULL) { 234 if (in->n != mask->n) { 235 psAbort(__func__, 236 "Vector data and vector mask are of different sizes."); 237 } 238 if (mask->type.type != PS_TYPE_U8) { 239 psAbort(__func__, "Vector mask must be type PS_TYPE_U8"); 240 } 241 } 242 // GUS: determine the correct action for a variety of other cases: 243 // in vector has 0 elements, and histogram structure has zero bins. 244 196 245 numBins = out->nums->n; 197 246 198 if (mask != NULL) { 199 for (i=0;i<in->n;i++) { 200 // Check if this pixel is masked, and if so, skip it. 201 if (!(mask->data.U8[i] & maskVal)) { 202 // Check if this pixel is below the minimum value, and if so 203 // count it, then skip it. 204 if (in->data.F32[i] < out->bounds->data.F32[0]) { 205 out->minNum++; 206 207 // Check if this pixel is above the maximum value, and if so 208 // count it, then skip it. 209 } else if (in->data.F32[i] > out->bounds->data.F32[numBins]) { 210 out->maxNum++; 211 } else { 212 // If this is a uniform histogram, determining the correct 213 // number is trivial. 214 if (out->uniform == true) { 215 binSize = out->bounds->data.F32[1] - out->bounds->data.F32[0]; 216 217 binNum = (int) ((in->data.F32[i] - out->bounds->data.F32[0]) / 218 binSize); 219 (out->nums->data.S32[binNum])++; 220 // If this is a non-uniform histogram, determining the correct 221 // bin number requires a bit more work. 222 } else { 223 // GUS: This is slow. Put a smarter algorithm here to 224 // find the correct bin number (bin search, probably) 225 for (j=0;j<(out->bounds->n)-1;j++) { 226 if ((out->bounds->data.S32[j] <= in->data.F32[i]) && 227 (in->data.F32[i] <= out->bounds->data.S32[j+1])) { 228 (out->nums->data.S32[j])++; 229 } 230 } 231 } 232 } 233 } 234 } 235 } else { 236 for (i=0;i<in->n;i++) { 247 for (i=0;i<in->n;i++) { 248 // Check if this pixel is masked, and if so, skip it. 249 if ((mask == NULL) || 250 ((mask != NULL) && (!(mask->data.U8[i] & maskVal)))) { 251 // Check if this pixel is below the minimum value, and if so 252 // count it, then skip it. 237 253 if (in->data.F32[i] < out->bounds->data.F32[0]) { 238 // Check if this pixel is below the minimum value, and if so239 // count it, then skip it.240 254 out->minNum++; 241 } else if (in->data.F32[i] > out->bounds->data.F32[numBins]) {242 255 // Check if this pixel is above the maximum value, and if so 243 256 // count it, then skip it. 257 } else if (in->data.F32[i] > out->bounds->data.F32[numBins]) { 244 258 out->maxNum++; 245 259 } else { … … 251 265 binNum = (int) ((in->data.F32[i] - out->bounds->data.F32[0]) / 252 266 binSize); 253 (out->nums->data.S32[binNum])++;254 255 267 // If this is a non-uniform histogram, determining the correct 256 268 // bin number requires a bit more work. … … 267 279 } 268 280 } 269 270 281 } 271 282 return(out); 272 283 } 273 284 274 void p_printVector(psVector *myVector, 275 psVector *maskVector, 276 unsigned int maskVal, 277 psStats *stats) 278 { 279 int i = 0; 285 /***************************************************************************** 286 p_psVectorPrint(myVector, maskVector, maskVal, stats): a private internal 287 function that simply prints a vector to STDOUT. Used primarily for 288 debugging. 289 *****************************************************************************/ 290 291 void p_psVectorPrint(psVector *myVector, 292 psVector *maskVector, 293 unsigned int maskVal, 294 psStats *stats) 295 { 296 int i = 0; // Loop index variable. 280 297 281 298 for (i=0;i<myVector->n;i++) { … … 291 308 ****************************************************************************** 292 309 ****************************************************************************** 293 MISC STATISTICAL FUNCTIONS 310 MISC PRIVATE STATISTICAL FUNCTIONS 311 312 NOTE: it is assumed that any call to these statistical functions will 313 have been preceded by a call to the psVectorStats() function. Various 314 sanity tests will only be performed in psVectorStats(). 315 Is the mask vector the same length as the data vector? 316 Is the mask vector of type PS_TYPE_U8? 317 Is the stats data structure NULL? 318 Is the in data structure NULL? 319 Is the in data structure of type PS_TYPE_F32? 294 320 ****************************************************************************** 295 321 ****************************************************************************** … … 298 324 299 325 /****************************************************************************** 300 ASSUMPTION: the mean is always calculated exactly. Robust means are never 301 calculated in this routine. 326 p_psVectorSampleMean(myVector, maskVector, maskVal, stats): calculates the 327 mean of the input vector. 328 Inputs 329 Returns 330 NULL 331 ASSUMPTION: the mean is always calculated exactly. Robust means are never 332 calculated in this routine. 302 333 *****************************************************************************/ 303 334 void p_psVectorSampleMean(const psVector *restrict myVector, … … 306 337 psStats *stats) 307 338 { 308 int i = 0; 309 float mean = 0.0; 310 int count = 0; 311 float rangeMin = 0.0; 312 float rangeMax = 0.0; 313 339 int i = 0; // Loop index variable 340 float mean = 0.0; // The mean 341 int count = 0; // # of points in this mean? 342 float rangeMin = 0.0; // Exclude data below this 343 float rangeMax = 0.0; // Exclude date above this 344 345 // If PS_STAT_USE_RANGE is requested, then we enter a slightly different 346 // loop. 314 347 if (stats->options & PS_STAT_USE_RANGE) { 315 348 rangeMin = stats->min; … … 317 350 if (maskVector != NULL) { 318 351 for (i=0;i<myVector->n;i++) { 352 // Check if the data is with the specified range 319 353 if (!(maskVal & maskVector->data.U8[i]) && 320 354 (rangeMin <= myVector->data.F32[i]) && … … 355 389 } 356 390 391 /****************************************************************************** 392 p_psVectorSampleMax(myVector, maskVector, maskVal, stats): calculates the 393 max of the input vector. 394 Inputs 395 myVector 396 maskVector 397 maskVal 398 stats 399 Returns 400 NULL 401 *****************************************************************************/ 357 402 void p_psVectorMax(const psVector *restrict myVector, 358 403 const psVector *restrict maskVector, … … 360 405 psStats *stats) 361 406 { 362 int i = 0; 363 float max = -MYMAXFLOAT; 364 float rangeMin = 0.0; 365 float rangeMax = 0.0; 366 407 int i = 0; // Loop index variable 408 float max = -MYMAXFLOAT; // The calculated maximum 409 float rangeMin = 0.0; // Exclude data below this 410 float rangeMax = 0.0; // Exclude date above this 411 412 // If PS_STAT_USE_RANGE is requested, then we enter a different loop. 367 413 if (stats->options & PS_STAT_USE_RANGE) { 368 414 rangeMin = stats->min; … … 408 454 } 409 455 456 /****************************************************************************** 457 p_psVectorSampleMin(myVector, maskVector, maskVal, stats): calculates the 458 minimum of the input vector. 459 Inputs 460 myVector 461 maskVector 462 maskVal 463 stats 464 Returns 465 NULL 466 *****************************************************************************/ 410 467 void p_psVectorMin(const psVector *restrict myVector, 411 468 const psVector *restrict maskVector, … … 413 470 psStats *stats) 414 471 { 415 int i = 0; 416 float min = MYMAXFLOAT; 417 float rangeMin = 0.0; 418 float rangeMax = 0.0; 472 int i = 0; // Loop index variable 473 float min = MYMAXFLOAT; // The calculated maximum 474 float rangeMin = 0.0; // Exclude data below this 475 float rangeMax = 0.0; // Exclude date above this 419 476 420 477 if (stats->options & PS_STAT_USE_RANGE) { … … 462 519 463 520 /****************************************************************************** 464 This routine calculates the number of non-masked pixels in the vector. 465 that fall within the min/max range, if given. 521 p_psVectorSampleMax(myVector, maskVector, maskVal, stats): calculates the 522 number of non-masked pixels in the vector. that fall within the min/max 523 range, if given. 524 Inputs 525 myVector 526 maskVector 527 maskVal 528 stats 529 Returns 530 NULL 466 531 *****************************************************************************/ 467 532 int p_psVectorNValues(const psVector *restrict myVector, … … 470 535 psStats *stats) 471 536 { 472 int i = 0; 473 int numData = 0; 474 float rangeMin = 0.0; 475 float rangeMax = 0.0; 537 int i = 0; // Loop index variable 538 int numData = 0; // The number of data points 539 float rangeMin = 0.0; // Exclude data below this 540 float rangeMax = 0.0; // Exclude date above this 476 541 477 542 if (stats->options & PS_STAT_USE_RANGE) { … … 512 577 513 578 579 /****************************************************************************** 580 p_psVectorSampleMedian(myVector, maskVector, maskVal, stats): calculates the 581 median of the input vector. 582 Inputs 583 myVector 584 maskVector 585 maskVal 586 stats 587 Returns 588 NULL 589 *****************************************************************************/ 514 590 void p_psVectorSampleMedian(const psVector *restrict myVector, 515 591 const psVector *restrict maskVector, … … 517 593 psStats *stats) 518 594 { 519 psVector *unsortedVector = NULL; 520 psVector *sortedVector = NULL; 521 int count = 0;522 int i = 0;523 int nValues = 0; 524 float rangeMin = 0.0; 525 float rangeMax = 0.0; 526 psStats *stats2 = NULL; 595 psVector *unsortedVector = NULL; // Temporary vector 596 psVector *sortedVector = NULL; // Temporary vector 597 int i = 0; // Loop index variable 598 int count = 0; // # of points in this mean? 599 int nValues = 0; // # of points in vector 600 float rangeMin = 0.0; // Exclude data below this 601 float rangeMax = 0.0; // Exclude date above this 602 psStats *stats2 = NULL; // Temporary stats structure 527 603 528 604 … … 531 607 532 608 if (myVector->n > stats->sampleLimit) { 609 psAbort(__func__, "Robust Statistic Algorithms have not yet been defined or implemented."); 610 533 611 // Calculate the robust quartiles. 534 612 stats2 = psStatsAlloc(PS_STAT_ROBUST_MEDIAN); … … 548 626 549 627 // Determine how many data points fit inside this min/max range 550 // and are not ma xed, IF the maskVector is not NULL>628 // and are not masked, IF the maskVector is not NULL> 551 629 nValues = p_psVectorNValues(myVector, maskVector, maskVal, stats); 552 630 … … 620 698 float sigma) 621 699 { 622 int i = 0; 623 int j = 0; 624 float tmpf = 0.0; 625 float gaussianCoefs[1 + (2 * GAUSS_WIDTH)]; 626 // The coefficients used in the histogram 627 // smoothing calculation. 700 int i = 0; // Loop index variable 701 int j = 0; // Loop index variable 702 float tmpf = 0.0; // Temporary variable 703 float gaussianCoefs[1 + (2 * GAUSS_WIDTH)]; // The Gaussian Coefficients 628 704 629 705 for(i=0;i<(1 + (2 * GAUSS_WIDTH));i++) { … … 631 707 // If sigma does not equal zero, then we use Gaussian smoothing. 632 708 #ifdef DARWIN 633 tmpf = (float) sqrt(2.0f * PI * sigma * sigma);709 tmpf = (float) sqrt(2.0f * M_PI * sigma * sigma); 634 710 #else 635 711 636 tmpf = sqrtf(2.0f * PI * sigma * sigma);712 tmpf = sqrtf(2.0f * M_PI * sigma * sigma); 637 713 #endif 638 714 639 715 gaussianCoefs[i] = (float) exp( (-((float) (i-GAUSS_WIDTH)) * 640 716 ((float) (i-GAUSS_WIDTH))) / 641 (2.0f * sigma * sigma)) / 642 tmpf; 717 (2.0f * sigma * sigma)) / tmpf; 643 718 } else { 644 719 /* If sigma equals zero (all pixels have the same value) 645 * the above code will divide by zero. Therefore, we instead646 * use boxcar smoothing.720 * the above code will divide by zero. Therefore, we don't need 721 * to smooth the data. 647 722 */ 648 gaussianCoefs[i] = 1.0f / (1.0f + (2.0f * (float) GAUSS_WIDTH));723 return; 649 724 } 650 725 } … … 662 737 663 738 /****************************************************************************** 664 p_psVectorSampleQuartiles() 665 This procedure calculates the upper and/or lower quartiles of the 666 data set. 667 739 p_psVectorSampleQuartiles(myVector, maskVector, maskVal, stats): calculates 740 the upper and/or lower quartiles of the input vector. 741 Inputs 742 myVector 743 maskVector 744 maskVal 745 stats 746 Returns 747 NULL 668 748 *****************************************************************************/ 669 749 void p_psVectorSampleQuartiles(const psVector *restrict myVector, … … 672 752 psStats *stats) 673 753 { 674 psVector *unsortedVector = NULL; 675 psVector *sortedVector = NULL; 676 int count = 0; 677 int ind = 0; 678 int i = 0; 679 int nValues = 0; 680 float rangeMin = 0.0; 681 float rangeMax = 0.0; 754 psVector *unsortedVector = NULL; // Temporary vector 755 psVector *sortedVector = NULL; // Temporary vector 756 int i = 0; // Loop index variable 757 int count = 0; // # of points in this mean? 758 int nValues = 0; // # data points 759 float rangeMin = 0.0; // Exclude data below this 760 float rangeMax = 0.0; // Exclude date above this 682 761 683 762 // Determine if the number of data points exceed a threshold which will 684 763 // cause to generate robust stats, as opposed to exact stats. 685 /* GUS: When IfA provides the algorithm, insert is here. 686 if (myVector->n > stats->sampleLimit) { 687 psStats *stats2 = NULL; 688 // Calculate the robust quartiles. 689 stats2 = psStatsAlloc(PS_STAT_ROBUST_QUARTILE); 690 p_psVectorRobustStats(myVector, maskVector, maskVal, stats2); 691 692 // Store the robust quartiles into the sample quartile members. 693 stats->sampleUQ = stats2->robustUQ; 694 stats->sampleLQ = stats2->robustLQ; 695 696 // Free temporary data buffers. 697 psStatsFree(stats2); 698 699 // Set the PS_STAT_ROBUST_FOR_SAMPLE bit in the stats structure. 700 stats->options = stats->options | PS_STAT_ROBUST_FOR_SAMPLE; 701 702 return; 703 } 704 */ 764 if (myVector->n > stats->sampleLimit) { 765 psAbort(__func__, "Robust Statistic Algorithms have not yet been defined or implemented."); 766 psStats *stats2 = NULL; 767 // Calculate the robust quartiles. 768 stats2 = psStatsAlloc(PS_STAT_ROBUST_QUARTILE); 769 p_psVectorRobustStats(myVector, maskVector, maskVal, stats2); 770 771 // Store the robust quartiles into the sample quartile members. 772 stats->sampleUQ = stats2->robustUQ; 773 stats->sampleLQ = stats2->robustLQ; 774 775 // Free temporary data buffers. 776 psStatsFree(stats2); 777 778 // Set the PS_STAT_ROBUST_FOR_SAMPLE bit in the stats structure. 779 stats->options = stats->options | PS_STAT_ROBUST_FOR_SAMPLE; 780 781 return; 782 } 705 783 706 784 // Determine how many data points fit inside this min/max range … … 757 835 758 836 // Calculate the quartile points exactly. 759 ind = 3 * (nValues / 4); 760 stats->sampleUQ = sortedVector->data.F32[ind]; 761 ind = (nValues / 4); 762 stats->sampleLQ = sortedVector->data.F32[ind]; 837 stats->sampleUQ = sortedVector->data.F32[3 * (nValues / 4)]; 838 stats->sampleLQ = sortedVector->data.F32[nValues / 4]; 763 839 764 840 // Free the temporary data structures. … … 770 846 771 847 /****************************************************************************** 772 p_psVectorRobustStats(): this procedure calculates a variety of robust 773 stat measures:848 p_psVectorRobustStats(myVector, maskVector, maskVal, stats): this procedure 849 calculates a variety of robust stat measures: 774 850 PS_STAT_ROBUST_MEAN 775 851 PS_STAT_ROBUST_MEDIAN … … 784 860 measures were calcualted in separate functiosn, then much of the initial 785 861 processing would be duplicated. 862 Inputs 863 myVector 864 maskVector 865 maskVal 866 stats 867 Returns 868 NULL 786 869 *****************************************************************************/ 787 870 void p_psVectorRobustStats(const psVector *restrict myVector, … … 791 874 { 792 875 psHistogram *robustHistogram = NULL; 793 float binSize = 0.0; 876 float binSize = 0.0; // Size of the histogram bins 794 877 float sigmaE = 0.0; 795 int LQBinNum = -1; 796 int UQBinNum = -1; 797 int i = 0; // Loop index variable.878 int LQBinNum = -1; // Bin num for lower quartile 879 int UQBinNum = -1; // Bin num for upper quartile 880 int i = 0; // Loop index variable 798 881 int maxBinNum = 0; 799 882 int maxBinCount = 0; 800 883 float dL = 0.0; 884 int numBins = 0; 801 885 802 886 // NOTE: The SDRS states that the sample quartiles must be used to … … 827 911 } 828 912 829 // Create the histogram structure. 913 // Create the histogram structure (yes, 2 is necessary, not 1). 914 numBins = 2 + (int) ((stats->max - stats->min) / binSize); 915 830 916 robustHistogram = psHistogramAlloc(stats->min, 831 917 stats->max, 832 1 + (int) ((stats->max - stats->min) / binSize)); 833 834 918 numBins); 835 919 // Populate the histogram array. 836 // GUS: fix this 837 // robustHistogram = psHistogramVector(robustHistogram, myVector); 838 // 920 psHistogramVector(robustHistogram, myVector, maskVector, maskVal); 839 921 840 922 // Smooth the histogram. … … 868 950 869 951 // Fit a Gaussian to the bins in the range MODE-dL to Mode+dL 870 // What algorithm should I use to do this? 871 872 // The resulting fit parameters are the robust mean, mean_r, and sigma 873 // What is the mean_r? 952 // GUS: This step is dependent on the functions in psMinimize.c being 953 // implemented. Currently, they are not. 874 954 875 955 if (stats->options & PS_STAT_ROBUST_MEAN) { … … 895 975 } 896 976 897 /***************************************************************************** 898 NOTE: This function assumes that p_psVectorMean() has already been called 899 and the correct value is stored in stats->sampleMean. 977 /****************************************************************************** 978 p_psVectorSampleStdev(myVector, maskVector, maskVal, stats): calculates the 979 stdev of the input vector. 980 Inputs 981 myVector 982 maskVector 983 maskVal 984 stats 985 Returns 986 NULL 900 987 901 NOTE: the mean is always calculated exactly. Robust means are never902 calculated in this routine.988 NOTE: the mean is always calculated exactly. Robust means are never 989 calculated in this routine. 903 990 *****************************************************************************/ 904 991 void p_psVectorSampleStdev(const psVector *restrict myVector, … … 907 994 psStats *stats) 908 995 { 909 int i = 0; 910 int countInt = 0; 911 float countFloat = 0.0; 912 float mean = 0.0; 913 float diff = 0.0; 914 float sumSquares = 0.0; 915 float sumDiffs = 0.0; 916 float rangeMin = 0.0; 917 float rangeMax = 0.0; 918 996 int i = 0; // Loop index variable 997 int countInt = 0; // # of data points being used 998 float countFloat = 0.0; // # of data points being used 999 float mean = 0.0; // The mean 1000 float diff = 0.0; // Used in calculating stdev 1001 float sumSquares = 0.0; // temporary variable 1002 float sumDiffs = 0.0; // temporary variable 1003 float rangeMin = 0.0; // Exclude data below this 1004 float rangeMax = 0.0; // Exclude date above this 1005 1006 // This procedure requires the mean. If it has not been already 1007 // calculated, then call p_psVectorSampleMean() 919 1008 if (0 != isnan(stats->sampleMean)) { 920 1009 p_psVectorSampleMean(myVector, maskVector, maskVal, stats); … … 979 1068 } 980 1069 1070 /****************************************************************************** 1071 p_psVectorClippedStats(myVector, maskVector, maskVal, stats): calculates the 1072 clipped stats (mean or stdev) of the input vector. 1073 1074 Inputs 1075 myVector 1076 maskVector 1077 maskVal 1078 stats 1079 Returns 1080 NULL 1081 *****************************************************************************/ 981 1082 void p_psVectorClippedStats(const psVector *restrict myVector, 982 1083 const psVector *restrict maskVector, … … 984 1085 psStats *stats) 985 1086 { 986 int i = 0; 987 int j = 0; 988 float clippedMean = 0.0; 989 float clippedStdev = 0.0; 990 psVector *tmpMask = NULL; 991 1087 int i = 0; // Loop index variable 1088 int j = 0; // Loop index variable 1089 float clippedMean = 0.0; // self-explanatory 1090 float clippedStdev = 0.0; // self-explanatory 1091 float oldStanMean = 0.0; // Temporary variable 1092 float oldStanStdev = 0.0; // Temporary variable 1093 psVector *tmpMask = NULL; // Temporary vector 1094 1095 // Endure that stats->clipIter is within the proper range. 992 1096 if (!((CLIPPED_NUM_ITER_LB <= stats->clipIter ) && 993 1097 (stats->clipIter <= CLIPPED_NUM_ITER_UB))) { … … 996 1100 } 997 1101 1102 // Endure that stats->clipSigma is within the proper range. 998 1103 if (!((CLIPPED_SIGMA_LB <= stats->clipSigma ) && 999 1104 (stats->clipSigma <= CLIPPED_SIGMA_UB))) { … … 1002 1107 } 1003 1108 1004 1109 // We allocate a temporary mask vector since during the iterative 1110 // steps that follow, we will be masking off additional data points. 1111 // However, we do no want to modify the original mask vector. 1005 1112 tmpMask = psVectorAlloc(myVector->n, PS_TYPE_U8); 1006 1113 tmpMask->n = myVector->n; 1007 1114 1115 // If we were called with a mask vector, then initialize the temporary 1116 // mask vector with those values. 1008 1117 if (maskVector != NULL) { 1009 1118 for (i=0;i<tmpMask->n;i++) { … … 1026 1135 clippedStdev = stats->sampleStdev; 1027 1136 1137 // Must save the old sampleMean and sampleStdev since the following code 1138 // block overwrites them. 1139 oldStanMean = stats->sampleMean; 1140 oldStanStdev = stats->sampleStdev; 1141 1028 1142 // 5. Repeat N times: 1029 1030 1143 for (i=0;i<stats->clipIter;i++) { 1031 // printf("p_psVectorClippedStats(): Iteration %d (%f %f)\n", i,1032 // clippedMean, clippedStdev);1033 1144 for (j=0;j<myVector->n;j++) { 1034 1145 // a) Exclude all values x_i for which |x_i - x| > K * stdev … … 1038 1149 } 1039 1150 // b) compute new mean and stdev 1040 // GUS: I should probably create a new struct here since the1041 // following calls will overwrite any old values in sampleMean.1042 1151 p_psVectorSampleMedian(myVector, tmpMask, maskVal, stats); 1043 1152 p_psVectorSampleStdev(myVector, tmpMask, maskVal, stats); … … 1050 1159 } 1051 1160 } 1161 stats->sampleMean = oldStanMean; 1162 stats->sampleStdev= oldStanStdev; 1052 1163 1053 1164 // 7. The last calcuated value of x is the cliped mean. … … 1066 1177 1067 1178 /****************************************************************************** 1179 psVectorStats(myVector, maskVector, maskVal, stats): this is the public API 1180 function which calls the above private stats functions based on what bits 1181 were set in stats->options. 1068 1182 1069 NOTE: The current strategy is to implement everything assuming that all 1070 input data is of type PS_TYPE_F32. Once the basic code is in place, 1071 we will macro-ize everything and add PS_TYPE_U16 and PS_TYPE_F64. 1183 Inputs 1184 myVector 1185 maskVector 1186 maskVal 1187 stats 1188 Returns 1189 The stats structure. 1072 1190 1191 NOTE: The current strategy is to implement everything assuming that all 1192 input data is of type PS_TYPE_F32. Once the basic code is in place, we will 1193 macro-ize everything and add PS_TYPE_U16 and PS_TYPE_F64. 1073 1194 *****************************************************************************/ 1074 1195 psStats *psVectorStats(psStats *stats, … … 1077 1198 unsigned int maskVal) 1078 1199 { 1200 // GUS: Verify that this is the correct action. 1079 1201 if (in == NULL) { 1080 1202 return(stats); … … 1084 1206 } 1085 1207 1208 // Ensure that the data is of type PS_TYPE_F32. Eventually, more data 1209 // types will be implemented. 1086 1210 if (in->type.type != PS_TYPE_F32) { 1087 1211 psAbort(__func__, … … 1090 1214 } 1091 1215 1216 // Ensure that the mask vector is of the proper size and type. 1092 1217 if (mask != NULL) { 1093 1218 if (in->n != mask->n) { … … 1124 1249 } 1125 1250 1251 // Since the various robust stats quantities share much computation, they 1252 // are grouped together in a single private function: 1253 // p_psVectorRobustStats() 1126 1254 if ((stats->options & PS_STAT_ROBUST_MEAN) || 1127 1255 (stats->options & PS_STAT_ROBUST_MEDIAN) || … … 1147 1275 } 1148 1276 1149 // OLD CODE: Should we check for an unknown option?1150 // default:1151 // psAbort(__func__, "Unknown options 0x%x.\n", stats->options);1152 1153 1277 return(stats); 1154 1278 } -
trunk/psLib/src/math/psStats.h
r974 r1020 1 /** @file psStats.h 2 * \brief basic statistical operations 3 * @ingroup Stats 4 * 5 * This file will hold the definition of the histogram and stats data 6 * structures. It also contains prototypes for procedures which operate 7 * on those data structures. 8 * 9 * @author George Gusciora, MHPCC 10 * 11 * @version $Revision: 1.12 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-06-14 19:33:09 $ 13 * 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii 15 */ 1 16 #if !defined(PS_STATS_H) 2 17 #define PS_STATS_H 3 /****************************************************************************** 4 This file will histogram/statistical functions and data structures. 5 *****************************************************************************/ 6 /** \file psStats.h 7 * \brief basic statistical operations 8 * \ingroup Stats 9 */ 18 10 19 #include "psVector.h" 11 20 … … 36 45 37 46 38 /** This is the generic statistics structure */ 47 /** This is the generic statistics structure. It contails the data members 48 for the various statistic values. It contains the options member to 49 specifiy which statistics must be calculated. */ 39 50 typedef struct 40 51 { … … 74 85 ); 75 86 76 /** Constructor*/87 /** A constructor for the stats structure.*/ 77 88 psStats *psStatsAlloc(psStatsOptions options); ///< Statistics to measure 78 89 79 /** Destructor*/90 /** A destructor for the stats structure.*/ 80 91 void psStatsFree(psStats *restrict stats); ///< Stats structure to destroy 81 92 … … 83 94 Histogram functions and data structures. 84 95 *****************************************************************************/ 96 /** The basic histogram structure which contains bounds and bins. */ 85 97 typedef struct 86 98 { … … 111 123 /** Calculate a histogram \ingroup MathGroup **/ 112 124 psHistogram *psHistogramVector (psHistogram *out, ///< Histogram data 113 psVector *in, ///< Vector to analyse114 psVector *mask, ///< Mask dat for input vector125 const psVector *restrict in, ///< Vector to analyse 126 const psVector *restrict mask, ///< Mask dat for input vector 115 127 int maskVal); ///< Mask value 116 128
Note:
See TracChangeset
for help on using the changeset viewer.
