Changeset 6322 for trunk/psLib/src/math/psStats.c
- Timestamp:
- Feb 3, 2006, 12:05:22 PM (20 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/math/psStats.c (modified) (16 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/math/psStats.c
r6315 r6322 16 16 * use ->min and ->max (PS_STAT_USE_RANGE) 17 17 * 18 * @version $Revision: 1.16 6$ $Name: not supported by cvs2svn $19 * @date $Date: 2006-02-03 01:30:14$18 * @version $Revision: 1.167 $ $Name: not supported by cvs2svn $ 19 * @date $Date: 2006-02-03 22:05:22 $ 20 20 * 21 21 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 303 303 max of the input vector. If there was a problem with the max calculation, 304 304 this routine sets stats->max to NAN. 305 306 XXX: Do we need to factor errors into it?307 305 *****************************************************************************/ 308 306 psS32 p_psVectorMax(const psVector* myVector, … … 549 547 median of the input vector. Returns true on success (including if there were 550 548 no valid input vector elements). 551 552 XXX: Use static vectors for sort arrays.553 549 *****************************************************************************/ 554 550 bool p_psVectorSampleMedian(const psVector* myVector, … … 783 779 { 784 780 psTrace(__func__, 4, "---- %s() begin ----\n", __func__); 785 psVector* unsortedVector = NULL; // Temporary vector786 psVector* sortedVector = NULL; // Temporary vector787 psS32 i = 0; // Loop index variable788 psS32 count = 0; // # of points in this mean.789 psS32 nValues = 0; // # data points781 psVector* unsortedVector = NULL; 782 psVector* sortedVector = NULL; 783 psS32 i = 0; 784 psS32 count = 0; 785 psS32 nValues = 0; 790 786 791 787 // Determine how many data points fit inside this min/max range 792 // and are not ma xed, IFthe maskVector is not NULL.788 // and are not masked, if the maskVector is not NULL. 793 789 nValues = p_psVectorNValues(myVector, maskVector, maskVal, stats); 794 790 … … 796 792 unsortedVector = psVectorAlloc(nValues, PS_TYPE_F32); 797 793 798 // Determine if we must only use data points within a min/max range.799 794 if (stats->options & PS_STAT_USE_RANGE) { 800 795 // Store all non-masked data points within the min/max range … … 1001 996 psTrace(__func__, 4, "---- %s() begin ----\n", __func__); 1002 997 psTrace(__func__, 4, "Trace level is %d\n", psTraceGetLevel(__func__)); 1003 psF32 clippedMean = 0.0; // self-explanatory1004 psF32 clippedStdev = 0.0; // self-explanatory1005 psVector* tmpMask = NULL; // Temporary vector for masks during iterations.1006 static psStats *statsTmp = NULL; // Temporary psStats struct.1007 psS32 rc = 0; // Return code.998 psF32 clippedMean = 0.0; 999 psF32 clippedStdev = 0.0; 1000 psVector* tmpMask = NULL; 1001 static psStats *statsTmp = NULL; 1002 psS32 rc = 0; 1008 1003 1009 1004 // Ensure that stats->clipIter is within the proper range. … … 1189 1184 parameter). 1190 1185 1191 XXX: After you fit the polynomial, solve for X analytically.1192 1193 XXX: the vectors do not have to be the same length. Must insert the proper1194 tests to ensure that binNum is within acceptable ranges for both vectors.1195 1196 XXX: This currently assumes that the three points are monotonically increasing1197 or decreasing: so, it works for the cumulative histogram vectors, but not for1198 arbitrary vectors. We should probably test that condition.1199 1186 *****************************************************************************/ 1200 1187 psF32 fitQuadraticSearchForYThenReturnX( … … 1221 1208 psVector *x = psVectorAlloc(3, PS_TYPE_F64); 1222 1209 psVector *y = psVectorAlloc(3, PS_TYPE_F64); 1223 psVector *yErr = psVectorAlloc(3, PS_TYPE_F64);1224 1225 1210 psF32 tmpFloat = 0.0f; 1226 1211 1227 if ((binNum > 0) && (binNum < (yVec->n - 2))) {1212 if ((binNum >= 1) && (binNum < (yVec->n - 2)) && (binNum < (xVec->n - 2))) { 1228 1213 // The general case. We have all three points. 1229 1214 x->data.F64[0] = (psF64) (0.5 * (xVec->data.F32[binNum - 1] + xVec->data.F32[binNum])); … … 1234 1219 y->data.F64[2] = yVec->data.F32[binNum + 1]; 1235 1220 psTrace(__func__, 6, "x vec (orig) is (%f %f %f %f)\n", xVec->data.F32[binNum - 1], 1236 xVec->data.F32[binNum], 1237 xVec->data.F32[binNum+1], 1238 xVec->data.F32[binNum+2]); 1239 psTrace(__func__, 6, "x vec is (%f %f %f)\n", x->data.F64[0], x->data.F64[1], x->data.F64[2]); 1240 psTrace(__func__, 6, "y vec is (%f %f %f)\n", y->data.F64[0], y->data.F64[1], y->data.F64[2]); 1221 xVec->data.F32[binNum], xVec->data.F32[binNum+1], xVec->data.F32[binNum+2]); 1222 psTrace(__func__, 6, "x data is (%f %f %f)\n", x->data.F64[0], x->data.F64[1], x->data.F64[2]); 1223 psTrace(__func__, 6, "y data is (%f %f %f)\n", y->data.F64[0], y->data.F64[1], y->data.F64[2]); 1241 1224 1242 1225 // … … 1246 1229 // so that the following checks are not necessary. 1247 1230 // 1248 if (y->data.F64[0] < y->data.F64[1]) { 1249 if (!(y->data.F64[1] <= y->data.F64[2])) { 1250 psError(PS_ERR_UNKNOWN, true, "This routine must be called with montically increasing or decreasing data points.\n"); 1251 psFree(x); 1252 psFree(y); 1253 psFree(yErr); 1254 psTrace(__func__, 5, "---- %s(NAN) end ----\n", __func__); 1255 return(NAN); 1256 } 1257 // Ensure that yVal is within the range of the bins we are using. 1258 if (!((y->data.F64[0] <= yVal) && (yVal <= y->data.F64[2]))) { 1259 psError(PS_ERR_BAD_PARAMETER_VALUE, true, 1260 PS_ERRORTEXT_psStats_YVAL_OUT_OF_RANGE, 1261 (psF64)yVal, y->data.F64[2], y->data.F64[0]); 1262 } 1263 } else if (y->data.F64[0] > y->data.F64[1]) { 1264 if (!(y->data.F64[1] >= y->data.F64[2])) { 1265 psError(PS_ERR_UNKNOWN, true, "This routine must be called with montically increasing or decreasing data points.\n"); 1266 psFree(x); 1267 psFree(y); 1268 psFree(yErr); 1269 psTrace(__func__, 5, "---- %s(NAN) end ----\n", __func__); 1270 return(NAN); 1271 } 1272 // Ensure that yVal is within the range of the bins we are using. 1273 if (!((y->data.F64[2] <= yVal) && (yVal <= y->data.F64[0]))) { 1274 psError(PS_ERR_BAD_PARAMETER_VALUE, true, 1275 PS_ERRORTEXT_psStats_YVAL_OUT_OF_RANGE, 1276 (psF64)yVal, y->data.F64[2], y->data.F64[0]); 1277 } 1278 } 1279 1280 yErr->data.F64[0] = 1.0; 1281 yErr->data.F64[1] = 1.0; 1282 yErr->data.F64[2] = 1.0; 1231 if (! (((y->data.F64[0] <= yVal) && (yVal <= y->data.F64[2])) || 1232 ((y->data.F64[2] <= yVal) && (yVal <= y->data.F64[0]))) ) { 1233 psError(PS_ERR_BAD_PARAMETER_VALUE, true, 1234 PS_ERRORTEXT_psStats_YVAL_OUT_OF_RANGE, 1235 (psF64)yVal, y->data.F64[0], y->data.F64[2]); 1236 } 1237 1238 if (((y->data.F64[0] < y->data.F64[1]) && !(y->data.F64[1] <= y->data.F64[2])) || 1239 ((y->data.F64[0] > y->data.F64[1]) && !(y->data.F64[1] >= y->data.F64[2]))) { 1240 psError(PS_ERR_UNKNOWN, true, "This routine must be called with monotonically increasing or decreasing data points.\n"); 1241 psFree(x); 1242 psFree(y); 1243 psTrace(__func__, 5, "---- %s() end ----\n", __func__); 1244 return(NAN); 1245 } 1283 1246 1284 1247 // Determine the coefficients of the polynomial. 1285 1248 psPolynomial1D *myPoly = psPolynomial1DAlloc(PS_POLYNOMIAL_ORD, 2); 1286 myPoly = psVectorFitPolynomial1D(myPoly, NULL, 0, y, yErr, x);1249 myPoly = psVectorFitPolynomial1D(myPoly, NULL, 0, y, NULL, x); 1287 1250 if (myPoly == NULL) { 1288 psError(PS_ERR_UNEXPECTED_NULL, 1289 false, 1251 psError(PS_ERR_UNEXPECTED_NULL, false, 1290 1252 PS_ERRORTEXT_psStats_STATS_FIT_QUADRATIC_POLYNOMIAL_1D_FIT); 1291 1253 psFree(x); 1292 1254 psFree(y); 1293 psFree(yErr);1294 1255 psTrace(__func__, 5, "---- %s(NAN) end ----\n", __func__); 1295 1256 return(NAN); … … 1309 1270 if (isnan(tmpFloat)) { 1310 1271 psError(PS_ERR_UNEXPECTED_NULL, 1311 false, 1312 PS_ERRORTEXT_psStats_STATS_FIT_QUADRATIC_POLY_MEDIAN); 1272 false, PS_ERRORTEXT_psStats_STATS_FIT_QUADRATIC_POLY_MEDIAN); 1313 1273 psFree(x); 1314 1274 psFree(y); 1315 psFree(yErr);1316 1275 psTrace(__func__, 5, "---- %s(NAN) end ----\n", __func__); 1317 1276 return(NAN); 1318 1277 } 1319 1320 1278 } else { 1321 // The special case where we have two points only at the beginning of 1322 // the vectors x and y. 1279 // These are special cases where the bin is at the beginning or end of the vector. 1323 1280 if (binNum == 0) { 1281 // We have two points only at the beginning of the vectors x and y. 1324 1282 tmpFloat = 0.5 * (xVec->data.F32[binNum] + 1325 1283 xVec->data.F32[binNum + 1]); … … 1339 1297 psFree(x); 1340 1298 psFree(y); 1341 psFree(yErr);1342 1299 1343 1300 psTrace(__func__, 5, "---- %s(%f) end ----\n", __func__, tmpFloat); … … 1542 1499 // ADD: Step 3. 1543 1500 // Interpolate to the exact 50% position: this is the robust histogram median. 1544 // XXX: Check return codes.1545 1501 // 1546 1502 stats->robustMedian = fitQuadraticSearchForYThenReturnX( … … 1549 1505 binMedian, 1550 1506 totalDataPoints/2.0); 1507 if (isnan(stats->robustMedian)) { 1508 psError(PS_ERR_UNKNOWN, false, "Failed to fit a quadratic and calculate the 50-percent position.\n"); 1509 psFree(tmpStatsMinMax); 1510 psFree(robustHistogram); 1511 psFree(cumulativeRobustHistogram); 1512 psFree(tmpMaskVec); 1513 psTrace(__func__, 4, "---- %s(1) end ----\n", __func__); 1514 return(1); 1515 } 1551 1516 psTrace(__func__, 6, "Current robust median is %f\n", stats->robustMedian); 1552 1517 … … 2324 2289 binNum = (psS32)((inF32->data.F32[i] - out->bounds->data.F32[0]) / binSize); 2325 2290 if (errorsF32 != NULL) { 2326 // XXX: Check return codes. 2327 UpdateHistogramBins(binNum, out, 2328 inF32->data.F32[i], 2329 errorsF32->data.F32[i]); 2291 psS32 rc = UpdateHistogramBins(binNum, out, inF32->data.F32[i], 2292 errorsF32->data.F32[i]); 2293 if (rc < 0) { 2294 psLogMsg(__func__, PS_LOG_WARN, "WARNING: Failed to update the histogram bins with the errors vector.\n"); 2295 } 2330 2296 } else { 2331 2297 // XXX: This if-statement really shouldn't be necessary. … … 2348 2314 } else { 2349 2315 if (errorsF32 != NULL) { 2350 // XXX: Check return codes. 2351 UpdateHistogramBins(binNum, out, 2352 inF32->data.F32[i], 2353 errors->data.F32[i]); 2316 psS32 rc = UpdateHistogramBins(binNum, out, 2317 inF32->data.F32[i], 2318 errors->data.F32[i]); 2319 if (rc < 0) { 2320 psLogMsg(__func__, PS_LOG_WARN, "WARNING: Failed to update the histogram bins with the errors vector.\n"); 2321 } 2354 2322 } else { 2355 2323 (out->nums->data.F32[binNum])+= 1.0;
Note:
See TracChangeset
for help on using the changeset viewer.
