Changeset 30863
- Timestamp:
- Mar 10, 2011, 5:18:40 PM (15 years ago)
- Location:
- branches/eam_branches/ipp-20110213/psLib
- Files:
-
- 5 edited
-
src/math/psMinimizePolyFit.c (modified) (4 diffs)
-
src/math/psStats.c (modified) (19 diffs)
-
src/math/psStats.h (modified) (1 diff)
-
test/math/tap_psStats_Sample_01.c (modified) (4 diffs)
-
test/optime/tap_psStatsTiming.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20110213/psLib/src/math/psMinimizePolyFit.c
r24086 r30863 767 767 // XXX enforce consistency? 768 768 // XXX psStatsGetValue() probably has inverted precedence 769 psStatsOptions meanOption = stats->options & (PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_MEDIAN | PS_STAT_ROBUST_MEDIAN | PS_STAT_CLIPPED_MEAN | PS_STAT_FITTED_MEAN | PS_STAT_FITTED_MEAN _V2);770 psStatsOptions stdevOption = stats->options & (PS_STAT_SAMPLE_STDEV | PS_STAT_ROBUST_STDEV | PS_STAT_CLIPPED_STDEV | PS_STAT_FITTED_STDEV | PS_STAT_FITTED_STDEV _V2);769 psStatsOptions meanOption = stats->options & (PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_MEDIAN | PS_STAT_ROBUST_MEDIAN | PS_STAT_CLIPPED_MEAN | PS_STAT_FITTED_MEAN | PS_STAT_FITTED_MEAN); 770 psStatsOptions stdevOption = stats->options & (PS_STAT_SAMPLE_STDEV | PS_STAT_ROBUST_STDEV | PS_STAT_CLIPPED_STDEV | PS_STAT_FITTED_STDEV | PS_STAT_FITTED_STDEV); 771 771 if (!meanOption) { 772 772 psError(PS_ERR_UNKNOWN, true, "no valid mean stats option selected"); … … 1211 1211 // XXX enforce consistency? 1212 1212 // XXX psStatsGetValue() probably has inverted precedence 1213 psStatsOptions meanOption = stats->options & (PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_MEDIAN | PS_STAT_ROBUST_MEDIAN | PS_STAT_CLIPPED_MEAN | PS_STAT_FITTED_MEAN | PS_STAT_FITTED_MEAN _V2);1214 psStatsOptions stdevOption = stats->options & (PS_STAT_SAMPLE_STDEV | PS_STAT_ROBUST_STDEV | PS_STAT_CLIPPED_STDEV | PS_STAT_FITTED_STDEV | PS_STAT_FITTED_STDEV _V2);1213 psStatsOptions meanOption = stats->options & (PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_MEDIAN | PS_STAT_ROBUST_MEDIAN | PS_STAT_CLIPPED_MEAN | PS_STAT_FITTED_MEAN | PS_STAT_FITTED_MEAN); 1214 psStatsOptions stdevOption = stats->options & (PS_STAT_SAMPLE_STDEV | PS_STAT_ROBUST_STDEV | PS_STAT_CLIPPED_STDEV | PS_STAT_FITTED_STDEV | PS_STAT_FITTED_STDEV); 1215 1215 if (!meanOption) { 1216 1216 psError(PS_ERR_UNKNOWN, true, "no valid mean stats option selected"); … … 1621 1621 // XXX enforce consistency? 1622 1622 // XXX psStatsGetValue() probably has inverted precedence 1623 psStatsOptions meanOption = stats->options & (PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_MEDIAN | PS_STAT_ROBUST_MEDIAN | PS_STAT_CLIPPED_MEAN | PS_STAT_FITTED_MEAN | PS_STAT_FITTED_MEAN _V2);1624 psStatsOptions stdevOption = stats->options & (PS_STAT_SAMPLE_STDEV | PS_STAT_ROBUST_STDEV | PS_STAT_CLIPPED_STDEV | PS_STAT_FITTED_STDEV | PS_STAT_FITTED_STDEV _V2);1623 psStatsOptions meanOption = stats->options & (PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_MEDIAN | PS_STAT_ROBUST_MEDIAN | PS_STAT_CLIPPED_MEAN | PS_STAT_FITTED_MEAN | PS_STAT_FITTED_MEAN); 1624 psStatsOptions stdevOption = stats->options & (PS_STAT_SAMPLE_STDEV | PS_STAT_ROBUST_STDEV | PS_STAT_CLIPPED_STDEV | PS_STAT_FITTED_STDEV | PS_STAT_FITTED_STDEV); 1625 1625 if (!meanOption) { 1626 1626 psError(PS_ERR_UNKNOWN, true, "no valid mean stats option selected"); … … 2055 2055 // XXX enforce consistency? 2056 2056 // XXX psStatsGetValue() probably has inverted precedence 2057 psStatsOptions meanOption = stats->options & (PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_MEDIAN | PS_STAT_ROBUST_MEDIAN | PS_STAT_CLIPPED_MEAN | PS_STAT_FITTED_MEAN | PS_STAT_FITTED_MEAN _V2);2058 psStatsOptions stdevOption = stats->options & (PS_STAT_SAMPLE_STDEV | PS_STAT_ROBUST_STDEV | PS_STAT_CLIPPED_STDEV | PS_STAT_FITTED_STDEV | PS_STAT_FITTED_STDEV _V2);2057 psStatsOptions meanOption = stats->options & (PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_MEDIAN | PS_STAT_ROBUST_MEDIAN | PS_STAT_CLIPPED_MEAN | PS_STAT_FITTED_MEAN | PS_STAT_FITTED_MEAN); 2058 psStatsOptions stdevOption = stats->options & (PS_STAT_SAMPLE_STDEV | PS_STAT_ROBUST_STDEV | PS_STAT_CLIPPED_STDEV | PS_STAT_FITTED_STDEV | PS_STAT_FITTED_STDEV); 2059 2059 if (!meanOption) { 2060 2060 psError(PS_ERR_UNKNOWN, true, "no valid mean stats option selected"); -
branches/eam_branches/ipp-20110213/psLib/src/math/psStats.c
r30075 r30863 172 172 *****************************************************************************/ 173 173 174 // static prototypes:175 static psF32 minimizeLMChi2Gauss1D(psVector *deriv, const psVector *params, const psVector *coords);176 // static psF32 fitQuadraticSearchForYThenReturnX(const psVector *xVec, psVector *yVec, psS32 binNum, psF32 yVal);177 // static psF32 fitQuadraticSearchForYThenReturnXusingValues(const psVector *xVec, psVector *yVec, psS32 binNum, psF32 yVal);178 174 static psF32 fitQuadraticSearchForYThenReturnBin(const psVector *xVec, psVector *yVec, psS32 binNum, psF32 yVal); 179 175 … … 1087 1083 } 1088 1084 1089 /* 1090 * vectorFittedStats requires guess for fittedMean and fittedStdev 1091 * robustN50 should also be set 1092 */ 1085 /******************** 1086 * perform an asymmetric fit to the population. In development, this was called 1087 * "vectorFittedStats_v4" all versions of fitted stats now resolve to this function (only v4 1088 * has really been used) vectorFittedStats requires guess for fittedMean and fittedStdev 1089 * robustN50 should also be set gaussian fit is performed using 2D polynomial to ln(y) this 1090 * version follows the upper portion of the distribution until it passes 0.5*peak 1091 ********************/ 1093 1092 static bool vectorFittedStats (const psVector* myVector, 1094 const psVector* errors,1095 psVector* mask,1096 psVectorMaskType maskVal,1097 psStats* stats)1093 const psVector* errors, 1094 psVector* mask, 1095 psVectorMaskType maskVal, 1096 psStats* stats) 1098 1097 { 1099 1098 … … 1121 1120 stats->results |= PS_STAT_FITTED_MEAN; 1122 1121 stats->results |= PS_STAT_FITTED_STDEV; 1123 return true;1124 }1125 1126 float guessStdev = stats->robustStdev; // pass the guess sigma1127 float guessMean = stats->robustMedian; // pass the guess mean1128 1129 psTrace(TRACE, 6, "The guess mean is %f.\n", guessMean);1130 psTrace(TRACE, 6, "The guess stdev is %f.\n", guessStdev);1131 1132 bool done = false;1133 for (int iteration = 0; !done && (iteration < 2); iteration ++) {1134 psStats *statsMinMax = psStatsAlloc(PS_STAT_MIN | PS_STAT_MAX); // Statistics for min and max1135 1136 psF32 binSize = 1;1137 if (stats->options & PS_STAT_USE_BINSIZE) {1138 // Set initial bin size to the specified value.1139 binSize = stats->binsize;1140 psTrace(TRACE, 6, "Setting initial robust bin size to %.2f\n", binSize);1141 } else {1142 // construct a histogram with (sigma/10 < binsize < sigma)1143 // set roughly so that the lowest bins have about 2 cnts1144 // Nsmallest ~ N50 / (4*dN))1145 psF32 dN = PS_MAX (1, PS_MIN (10, stats->robustN50 / 8));1146 binSize = guessStdev / dN;1147 }1148 1149 // Determine the min/max of the vector (which prior outliers masked out)1150 int numValid = vectorMinMax(myVector, mask, maskVal, statsMinMax); // Number of values1151 float min = statsMinMax->min;1152 float max = statsMinMax->max;1153 if (numValid == 0 || isnan(min) || isnan(max)) {1154 psTrace(TRACE, 5, "Failed to calculate the min/max of the input vector.\n");1155 psFree(statsMinMax);1156 return true;1157 }1158 1159 // Calculate the number of bins.1160 // XXX can we calculate the binMin, binMax **before** building this histogram?1161 long numBins = (max - min) / binSize;1162 psTrace(TRACE, 6, "The new min/max values are (%f, %f).\n", min, max);1163 psTrace(TRACE, 6, "The new bin size is %f.\n", binSize);1164 psTrace(TRACE, 6, "The numBins is %ld\n", numBins);1165 1166 psHistogram *histogram = psHistogramAlloc(min, max, numBins); // A new histogram (without outliers)1167 if (!psVectorHistogram(histogram, myVector, errors, mask, maskVal)) {1168 // if psVectorHistogram returns false, we have a programming error1169 psError(PS_ERR_UNKNOWN, false, "Unable to generate histogram for fitted statistics.\n");1170 psFree(histogram);1171 psFree(statsMinMax);1172 return false;1173 }1174 if (psTraceGetLevel("psLib.math") >= 8) {1175 PS_VECTOR_PRINT_F32(histogram->nums);1176 }1177 1178 // Fit a Gaussian to the bins in the requested range about the guess mean1179 // min,max overrides clipSigma1180 psF32 maxFitSigma = 2.0;1181 if (isfinite(stats->clipSigma)) {1182 maxFitSigma = fabs(stats->clipSigma);1183 }1184 if (isfinite(stats->max)) {1185 maxFitSigma = fabs(stats->max);1186 }1187 1188 psF32 minFitSigma = 2.0;1189 if (isfinite(stats->clipSigma)) {1190 minFitSigma = fabs(stats->clipSigma);1191 }1192 if (isfinite(stats->min)) {1193 minFitSigma = fabs(stats->min);1194 }1195 1196 // select the min and max bins, saturating on the lower and upper end-points1197 long binMin, binMax;1198 PS_BIN_FOR_VALUE (binMin, histogram->bounds, guessMean - minFitSigma*guessStdev, 0);1199 PS_BIN_FOR_VALUE (binMax, histogram->bounds, guessMean + maxFitSigma*guessStdev, 0);1200 1201 // Generate the variables that will be used in the Gaussian fitting1202 // XXX EAM : we should test / guarantee that there are at least 3 (right?) bins1203 psVector *y = psVectorAlloc((1 + (binMax - binMin)), PS_TYPE_F32); // Vector of coordinates1204 psArray *x = psArrayAlloc((1 + (binMax - binMin))); // Array of ordinates1205 for (long i = binMin, j = 0; i <= binMax ; i++, j++) {1206 y->data.F32[j] = histogram->nums->data.F32[i];1207 psVector *ordinate = psVectorAlloc(1, PS_TYPE_F32); // The ordinate value1208 ordinate->data.F32[0] = PS_BIN_MIDPOINT(histogram, i);1209 x->data[j] = ordinate;1210 }1211 if (psTraceGetLevel("psLib.math") >= 8) {1212 // XXX: Print the x array somehow.1213 PS_VECTOR_PRINT_F32(y);1214 }1215 psTrace(TRACE, 6, "The clipped numBins is %ld\n", y->n);1216 psTrace(TRACE, 6, "The clipped min is %f (%ld)\n", PS_BIN_MIDPOINT(histogram, binMin), binMin);1217 psTrace(TRACE, 6, "The clipped max is %f (%ld)\n", PS_BIN_MIDPOINT(histogram, binMax), binMax);1218 1219 // Normalize y to [0.0:1.0] (since the psMinimizeLMChi2Gauss1D() functions is [0.0:1.0])1220 // XXX EAM : why not just fit the normalization as well??1221 p_psNormalizeVectorRange(y, 0.0, 1.0);1222 1223 // Fit a Gaussian to the data.1224 psMinimization *minimizer = psMinimizationAlloc(100, 0.01, 1.0); // The minimizer information1225 psVector *params = psVectorAlloc(2, PS_TYPE_F32); // Parameters for the Gaussian1226 // Initial guess for the mean (index 0) and var (index 1).1227 params->data.F32[0] = guessMean;1228 params->data.F32[1] = PS_SQR(guessStdev);1229 if (psTraceGetLevel("psLib.math") >= 8) {1230 PS_VECTOR_PRINT_F32(params);1231 PS_VECTOR_PRINT_F32(y);1232 }1233 1234 // psMinimizeLMChi2 can return false for bad data as well as for serious failures1235 if (!psMinimizeLMChi2(minimizer, NULL, params, NULL, x, y, NULL, minimizeLMChi2Gauss1D)) {1236 psError(PS_ERR_UNKNOWN, false, "Failed to fit a gaussian to the robust histogram.\n");1237 psFree(params);1238 psFree(minimizer);1239 psFree(x);1240 psFree(y);1241 psFree(histogram);1242 psFree(statsMinMax);1243 return true;1244 }1245 if (psTraceGetLevel("psLib.math") >= 8) {1246 PS_VECTOR_PRINT_F32(params);1247 }1248 1249 guessMean = params->data.F32[0];1250 guessStdev = sqrt(params->data.F32[1]);1251 if (guessStdev > 0.75*stats->robustStdev) {1252 done = true;1253 }1254 1255 // Clean up after fitting1256 psFree (params);1257 psFree (minimizer);1258 psFree (x);1259 psFree (y);1260 psFree (histogram);1261 psFree (statsMinMax);1262 }1263 1264 // The fitted mean is the Gaussian mean.1265 stats->fittedMean = guessMean;1266 psTrace(TRACE, 6, "The fitted mean is %f.\n", stats->fittedMean);1267 1268 // The fitted standard deviation1269 stats->fittedStdev = guessStdev;1270 psTrace(TRACE, 6, "The fitted stdev is %f.\n", stats->fittedStdev);1271 1272 stats->results |= PS_STAT_FITTED_MEAN;1273 stats->results |= PS_STAT_FITTED_STDEV;1274 1275 return true;1276 }1277 1278 1279 /********************1280 * vectorFittedStats_v2 requires guess for fittedMean and fittedStdev1281 * robustN50 should also be set1282 * gaussian fit is performed using 2D polynomial to ln(y)1283 ********************/1284 static bool vectorFittedStats_v2 (const psVector* myVector,1285 const psVector* errors,1286 psVector* mask,1287 psVectorMaskType maskVal,1288 psStats* stats)1289 {1290 1291 // This procedure requires the mean. If it has not been already1292 // calculated, then call vectorSampleMean()1293 if (!(stats->results & PS_STAT_ROBUST_MEDIAN)) {1294 if (!vectorRobustStats(myVector, errors, mask, maskVal, stats)) {1295 psError(PS_ERR_UNKNOWN, false, "failure to measure robust stats\n");1296 return false;1297 }1298 }1299 1300 // If the mean is NAN, then generate a warning and set the stdev to NAN.1301 if (isnan(stats->robustMedian)) {1302 stats->fittedMean = NAN;1303 stats->fittedStdev = NAN;1304 stats->results |= PS_STAT_FITTED_MEAN_V2;1305 stats->results |= PS_STAT_FITTED_STDEV_V2;1306 return true;1307 }1308 1309 if (stats->robustStdev <= FLT_EPSILON) {1310 stats->fittedMean = stats->robustMedian;1311 stats->fittedStdev = stats->robustStdev;1312 stats->results |= PS_STAT_FITTED_MEAN_V2;1313 stats->results |= PS_STAT_FITTED_STDEV_V2;1314 return true;1315 }1316 1317 float guessStdev = stats->robustStdev; // pass the guess sigma1318 float guessMean = stats->robustMedian; // pass the guess mean1319 1320 psTrace(TRACE, 6, "The ** starting ** guess mean is %f.\n", guessMean);1321 psTrace(TRACE, 6, "The ** starting ** guess stdev is %f.\n", guessStdev);1322 1323 bool done = false;1324 for (int iteration = 0; !done && (iteration < 2); iteration ++) {1325 psStats *statsMinMax = psStatsAlloc(PS_STAT_MIN | PS_STAT_MAX); // Statistics for min and max1326 1327 psF32 binSize = 1;1328 if (stats->options & PS_STAT_USE_BINSIZE) {1329 // Set initial bin size to the specified value.1330 binSize = stats->binsize;1331 psTrace(TRACE, 6, "Setting initial robust bin size to %.2f\n", binSize);1332 } else {1333 // construct a histogram with (sigma/10 < binsize < sigma)1334 // set roughly so that the lowest bins have about 2 cnts1335 // Nsmallest ~ N50 / (4*dN))1336 psF32 dN = PS_MAX (1, PS_MIN (10, stats->robustN50 / 8));1337 binSize = guessStdev / dN;1338 }1339 1340 // Determine the min/max of the vector (which prior outliers masked out)1341 int numValid = vectorMinMax(myVector, mask, maskVal, statsMinMax); // Number of values1342 float min = statsMinMax->min;1343 float max = statsMinMax->max;1344 if (numValid == 0 || isnan(min) || isnan(max)) {1345 COUNT_WARNING(10, 100, "Failed to calculate the min/max of the input vector.\n");1346 psFree(statsMinMax);1347 psTrace(TRACE, 4, "---- %s(false) end ----\n", __func__);1348 return true;1349 }1350 1351 // Calculate the number of bins.1352 // XXX can we calculate the binMin, binMax **before** building this histogram?1353 long numBins = (max - min) / binSize;1354 psTrace(TRACE, 6, "The new min/max values are (%f, %f).\n", min, max);1355 psTrace(TRACE, 6, "The new bin size is %f.\n", binSize);1356 psTrace(TRACE, 6, "The numBins is %ld\n", numBins);1357 1358 psHistogram *histogram = psHistogramAlloc(min, max, numBins); // A new histogram (without outliers)1359 if (!psVectorHistogram(histogram, myVector, errors, mask, maskVal)) {1360 psError(PS_ERR_UNKNOWN, false, "Unable to generate histogram for fitted statistcs v2.\n");1361 psFree(histogram);1362 psFree(statsMinMax);1363 return false;1364 }1365 if (psTraceGetLevel("psLib.math") >= 8) {1366 PS_VECTOR_PRINT_F32(histogram->nums);1367 }1368 1369 // Fit a Gaussian to the bins in the requested range about the guess mean1370 // min,max overrides clipSigma1371 psF32 maxFitSigma = 2.0;1372 if (isfinite(stats->clipSigma)) {1373 maxFitSigma = fabs(stats->clipSigma);1374 }1375 if (isfinite(stats->max)) {1376 maxFitSigma = fabs(stats->max);1377 }1378 1379 psF32 minFitSigma = 2.0;1380 if (isfinite(stats->clipSigma)) {1381 minFitSigma = fabs(stats->clipSigma);1382 }1383 if (isfinite(stats->min)) {1384 minFitSigma = fabs(stats->min);1385 }1386 1387 // select the min and max bins, saturating on the lower and upper end-points1388 long binMin, binMax;1389 PS_BIN_FOR_VALUE (binMin, histogram->bounds, guessMean - minFitSigma*guessStdev, 0);1390 PS_BIN_FOR_VALUE (binMax, histogram->bounds, guessMean + maxFitSigma*guessStdev, 0);1391 1392 // Generate the variables that will be used in the Gaussian fitting1393 // XXX EAM : we should test / guarantee that there are at least 3 (right?) bins1394 psVector *y = psVectorAllocEmpty((1 + (binMax - binMin)), PS_TYPE_F32); // Vector of coordinates1395 psVector *x = psVectorAllocEmpty((1 + (binMax - binMin)), PS_TYPE_F32); // Vector of ordinates1396 long j = 0;1397 for (long i = binMin; i <= binMax ; i++) {1398 if (histogram->nums->data.F32[i] <= 0.0)1399 continue;1400 x->data.F32[j] = PS_BIN_MIDPOINT(histogram, i);1401 y->data.F32[j] = log(histogram->nums->data.F32[i]);1402 // XXX note this is the natural log: expected distribution is A exp(-(x-xo)^2/2sigma^2)1403 j++;1404 }1405 y->n = x->n = j;1406 if (psTraceGetLevel("psLib.math") >= 8) {1407 // XXX: Print the x array somehow.1408 PS_VECTOR_PRINT_F32(y);1409 }1410 psTrace(TRACE, 6, "The clipped numBins is %ld\n", y->n);1411 psTrace(TRACE, 6, "The clipped min is %f (%ld)\n", PS_BIN_MIDPOINT(histogram, binMin), binMin);1412 psTrace(TRACE, 6, "The clipped max is %f (%ld)\n", PS_BIN_MIDPOINT(histogram, binMax), binMax);1413 1414 // fit 2nd order polynomial to ln(y) = -(x-xo)^2/2sigma^21415 psPolynomial1D *poly = psPolynomial1DAlloc(PS_POLYNOMIAL_ORD, 2);1416 1417 // XXX how can we protect against some extreme outliers? the robust histogram1418 // should have already dealt with those, but we are again sensitive to them...1419 // psStats *fitStats = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV);1420 // fitStats->clipIter = 3.0;1421 // fitStats->clipSigma = 3.0;1422 // psVector *fitMask = psVectorAlloc(y->n, PS_TYPE_VECTOR_MASK);1423 // psVectorInit (fitMask, 0);1424 1425 // XXX not sure if these should result in errors or not...1426 if (!psVectorFitPolynomial1D (poly, NULL, 0, y, NULL, x)) {1427 psError(PS_ERR_UNKNOWN, false, "Failed to fit a gaussian to the robust histogram.\n");1428 psFree(x);1429 psFree(y);1430 psFree(poly);1431 psFree(histogram);1432 psFree(statsMinMax);1433 psTrace(TRACE, 4, "---- %s(false) end ----\n", __func__);1434 return false;1435 }1436 1437 if (poly->coeff[2] >= 0.0) {1438 psTrace(TRACE, 6, "Parabolic fit results: %f + %f x + %f x^2\n", poly->coeff[0], poly->coeff[1], poly->coeff[2]);1439 psError(PS_ERR_UNKNOWN, false, "fit did not converge\n");1440 psFree(x);1441 psFree(y);1442 psFree(poly);1443 psFree(histogram);1444 psFree(statsMinMax);1445 psTrace(TRACE, 4, "---- %s(false) end ----\n", __func__);1446 return false;1447 }1448 1449 guessStdev = sqrt(-0.5/poly->coeff[2]);1450 guessMean = poly->coeff[1]*PS_SQR(guessStdev);1451 if (guessStdev > 0.75*stats->robustStdev) {1452 done = true;1453 } else {1454 psTrace(TRACE, 6, "Parabolic fit results: %f + %f x + %f x^2\n",1455 poly->coeff[0], poly->coeff[1], poly->coeff[2]);1456 psTrace(TRACE, 6, "The new guess mean is %f.\n", guessMean);1457 psTrace(TRACE, 6, "The new guess stdev is %f.\n", guessStdev);1458 }1459 1460 // Clean up after fitting1461 psFree (x);1462 psFree (y);1463 psFree (poly);1464 // psFree (fitStats);1465 // psFree (fitMask);1466 psFree (histogram);1467 psFree (statsMinMax);1468 }1469 1470 // The fitted mean is the Gaussian mean.1471 stats->fittedMean = guessMean;1472 psTrace(TRACE, 6, "The fitted mean is %f.\n", stats->fittedMean);1473 1474 // The fitted standard deviation1475 stats->fittedStdev = guessStdev;1476 psTrace(TRACE, 6, "The fitted stdev is %f.\n", stats->fittedStdev);1477 1478 stats->results |= PS_STAT_FITTED_MEAN_V2;1479 stats->results |= PS_STAT_FITTED_STDEV_V2;1480 1481 return true;1482 }1483 1484 /********************1485 * perform an asymmetric fit to the population1486 * vectorFittedStats_v3 requires guess for fittedMean and fittedStdev1487 * robustN50 should also be set1488 * gaussian fit is performed using 2D polynomial to ln(y)1489 ********************/1490 static bool vectorFittedStats_v3 (const psVector* myVector,1491 const psVector* errors,1492 psVector* mask,1493 psVectorMaskType maskVal,1494 psStats* stats)1495 {1496 1497 // This procedure requires the mean. If it has not been already1498 // calculated, then call vectorSampleMean()1499 if (!(stats->results & PS_STAT_ROBUST_MEDIAN)) {1500 if (!vectorRobustStats(myVector, errors, mask, maskVal, stats)) {1501 psError(PS_ERR_UNKNOWN, false, "failure to measure robust stats\n");1502 return false;1503 }1504 }1505 1506 // If the mean is NAN, then generate a warning and set the stdev to NAN.1507 if (isnan(stats->robustMedian)) {1508 stats->fittedMean = NAN;1509 stats->fittedStdev = NAN;1510 stats->results |= PS_STAT_FITTED_MEAN_V3;1511 stats->results |= PS_STAT_FITTED_STDEV_V3;1512 return true;1513 }1514 1515 if (stats->robustStdev <= FLT_EPSILON) {1516 stats->fittedMean = stats->robustMedian;1517 stats->fittedStdev = stats->robustStdev;1518 stats->results |= PS_STAT_FITTED_MEAN_V3;1519 stats->results |= PS_STAT_FITTED_STDEV_V3;1520 1122 return true; 1521 1123 } … … 1551 1153 COUNT_WARNING(10, 100, "Failed to calculate the min/max of the input vector.\n"); 1552 1154 psFree(statsMinMax); 1553 psTrace(TRACE, 4, "---- %s(false) end ----\n", __func__);1554 return true;1555 }1556 1557 // Calculate the number of bins.1558 // XXX can we calculate the binMin, binMax **before** building this histogram?1559 long numBins = (max - min) / binSize;1560 psTrace(TRACE, 6, "The new min/max values are (%f, %f).\n", min, max);1561 psTrace(TRACE, 6, "The new bin size is %f.\n", binSize);1562 psTrace(TRACE, 6, "The numBins is %ld\n", numBins);1563 1564 psHistogram *histogram = psHistogramAlloc(min, max, numBins); // A new histogram (without outliers)1565 if (!psVectorHistogram(histogram, myVector, errors, mask, maskVal)) {1566 psError(PS_ERR_UNKNOWN, false, "Unable to generate histogram for fitted statistics v3.\n");1567 psFree(histogram);1568 psFree(statsMinMax);1569 return false;1570 }1571 if (psTraceGetLevel("psLib.math") >= 8) {1572 PS_VECTOR_PRINT_F32(histogram->nums);1573 }1574 1575 // now fit a Gaussian to the upper and lower halves about the peak independently1576 1577 // set the full-range upper and lower limits1578 psF32 maxFitSigma = 2.0;1579 if (isfinite(stats->clipSigma)) {1580 maxFitSigma = fabs(stats->clipSigma);1581 }1582 if (isfinite(stats->max)) {1583 maxFitSigma = fabs(stats->max);1584 }1585 1586 psF32 minFitSigma = 2.0;1587 if (isfinite(stats->clipSigma)) {1588 minFitSigma = fabs(stats->clipSigma);1589 }1590 if (isfinite(stats->min)) {1591 minFitSigma = fabs(stats->min);1592 }1593 1594 // select the min and max bins, saturating on the lower and upper end-points1595 long binMin, binMax;1596 PS_BIN_FOR_VALUE (binMin, histogram->bounds, guessMean - minFitSigma*guessStdev, 0);1597 PS_BIN_FOR_VALUE (binMax, histogram->bounds, guessMean + maxFitSigma*guessStdev, 0);1598 if (binMin == binMax) {1599 COUNT_WARNING(10, 100, "Failed to calculate the min/max of the input vector.\n");1600 psFree(statsMinMax);1601 return true;1602 }1603 1604 // search for mode (peak of histogram within range mean-2sigma - mean+2sigma1605 long binPeak = binMin;1606 float valPeak = histogram->nums->data.F32[binPeak];1607 for (int i = binMin; i < binMax; i++) {1608 if (histogram->nums->data.F32[i] > valPeak) {1609 binPeak = i;1610 valPeak = histogram->nums->data.F32[binPeak];1611 }1612 psTrace (TRACE, 6, "(%f = %.0f) ", histogram->bounds->data.F32[i], histogram->nums->data.F32[i]);1613 }1614 psTrace (TRACE, 6, "\n");1615 1616 // assume a reasonably well-defined gaussian-like population; run from peak out until val < 0.25*peak1617 1618 psTrace(TRACE, 6, "The clipped numBins is %ld\n", binMax - binMin);1619 psTrace(TRACE, 6, "The clipped min is %f (%ld)\n",1620 PS_BIN_MIDPOINT(histogram, binMin), binMin);1621 psTrace(TRACE, 6, "The clipped max is %f (%ld)\n",1622 PS_BIN_MIDPOINT(histogram, binMax - 1), binMax - 1);1623 psTrace(TRACE, 6, "The clipped peak is %f (%ld)\n",1624 PS_BIN_MIDPOINT(histogram, binPeak), binPeak);1625 psTrace(TRACE, 6, "The clipped peak value is %f\n", histogram->nums->data.F32[binPeak]);1626 1627 {1628 // fit the lower half of the distribution1629 // run down until we drop below 0.25*valPeak1630 long binS = binMin;1631 long binE = PS_MIN (binPeak + 3, binMax);1632 for (int i = binPeak-3; i >= binMin; i--) {1633 if (histogram->nums->data.F32[i] < 0.25*valPeak) {1634 binS = i;1635 break;1636 }1637 }1638 psTrace(TRACE, 6, "Lower bound for lower half: %f (%ld)\n",1639 PS_BIN_MIDPOINT(histogram, binS), binS);1640 psTrace(TRACE, 6, "Upper bound for lower half: %f (%ld)\n",1641 PS_BIN_MIDPOINT(histogram, binE), binE);1642 1643 psVector *y = psVectorAllocEmpty(binE - binS, PS_TYPE_F32); // Vector of coordinates1644 psVector *x = psVectorAllocEmpty(binE - binS, PS_TYPE_F32); // Vector of ordinates1645 long j = 0;1646 for (long i = binS; i < binE; i++) {1647 if (histogram->nums->data.F32[i] <= 0.0)1648 continue;1649 x->data.F32[j] = PS_BIN_MIDPOINT(histogram, i);1650 // note this is the natural log: expected distribution is A exp(-(x-xo)^2/2sigma^2)1651 y->data.F32[j] = log(histogram->nums->data.F32[i]);1652 j++;1653 }1654 y->n = x->n = j;1655 1656 // fit 2nd order polynomial to ln(y) = -(x-xo)^2/2sigma^21657 psPolynomial1D *poly = psPolynomial1DAlloc(PS_POLYNOMIAL_ORD, 2);1658 bool status = psVectorFitPolynomial1D (poly, NULL, 0, y, NULL, x);1659 psFree(x);1660 psFree(y);1661 1662 if (!status) {1663 psError(PS_ERR_UNKNOWN, false, "Failed to fit a gaussian to the robust histogram.\n");1664 psFree(poly);1665 psFree(histogram);1666 psFree(statsMinMax);1667 psTrace(TRACE, 4, "---- %s(false) end ----\n", __func__);1668 return false;1669 }1670 1671 if (poly->coeff[2] >= 0.0) {1672 psTrace(TRACE, 6, "Failed parabolic fit: %f + %f x + %f x^2\n",1673 poly->coeff[0], poly->coeff[1], poly->coeff[2]);1674 psFree(poly);1675 psFree(histogram);1676 psFree(statsMinMax);1677 1678 // sometimes, the guessStdev is much too large. in this case, the entire real population1679 // tends to be found in a single bin. make one attempt to recover by dropping the guessStdev1680 // down by a jump and trying again1681 if (iteration == 0) {1682 guessStdev = 0.25*guessStdev;1683 psTrace(TRACE, 6, "*** retry, new stdev is %f.\n", guessStdev);1684 continue;1685 }1686 1687 psError(PS_ERR_UNKNOWN, false, "fit did not converge\n");1688 psTrace(TRACE, 4, "---- %s(false) end ----\n", __func__);1689 return false;1690 }1691 1692 // calculate lower mean & stdev from parabolic fit -- use this as the result1693 guessStdev = sqrt(-0.5/poly->coeff[2]);1694 guessMean = poly->coeff[1]*PS_SQR(guessStdev);1695 if (guessStdev > 0.75*stats->robustStdev) {1696 done = true;1697 }1698 psTrace(TRACE, 6, "Parabolic Lower fit results: %f + %f x + %f x^2\n",1699 poly->coeff[0], poly->coeff[1], poly->coeff[2]);1700 psTrace(TRACE, 6, "The lower mean is %f.\n", guessMean);1701 psTrace(TRACE, 6, "The lower stdev is %f.\n", guessStdev);1702 1703 psFree(poly);1704 }1705 1706 // for test, measure the same result for the upper section1707 {1708 // fit the upper half of the distribution1709 // run up until we drop below 0.25*valPeak1710 long binS = PS_MAX (binPeak - 3, 0);1711 long binE = binMax;1712 for (int i = binPeak+3; i < binMax; i++) {1713 if (histogram->nums->data.F32[i] < 0.25*valPeak) {1714 binE = i;1715 break;1716 }1717 }1718 psTrace(TRACE, 6, "Lower bound for upper half: %f (%ld)\n",1719 PS_BIN_MIDPOINT(histogram, binS), binS);1720 psTrace(TRACE, 6, "Upper bound for upper half: %f (%ld)\n",1721 PS_BIN_MIDPOINT(histogram, binE), binE);1722 1723 psVector *y = psVectorAllocEmpty(binE - binS, PS_TYPE_F32); // Vector of coordinates1724 psVector *x = psVectorAllocEmpty(binE - binS, PS_TYPE_F32); // Vector of ordinates1725 long j = 0;1726 for (long i = binS; i < binE; i++) {1727 if (histogram->nums->data.F32[i] <= 0.0)1728 continue;1729 x->data.F32[j] = PS_BIN_MIDPOINT(histogram, i);1730 // note this is the natural log: expected distribution is A exp(-(x-xo)^2/2sigma^2)1731 y->data.F32[j] = log(histogram->nums->data.F32[i]);1732 j++;1733 }1734 y->n = x->n = j;1735 1736 // fit 2nd order polynomial to ln(y) = -(x-xo)^2/2sigma^21737 psPolynomial1D *poly = psPolynomial1DAlloc(PS_POLYNOMIAL_ORD, 2);1738 bool status = psVectorFitPolynomial1D (poly, NULL, 0, y, NULL, x);1739 psFree(x);1740 psFree(y);1741 1742 if (!status) {1743 psError(PS_ERR_UNKNOWN, false, "Failed to fit a gaussian to the robust histogram.\n");1744 psFree(poly);1745 psFree(histogram);1746 psFree(statsMinMax);1747 psTrace(TRACE, 4, "---- %s(false) end ----\n", __func__);1748 return false;1749 }1750 1751 // calculate upper mean & stdev from parabolic fit -- ignore this value1752 float upperStdev = sqrt(-0.5/poly->coeff[2]);1753 float upperMean = poly->coeff[1]*PS_SQR(upperStdev);1754 #ifndef PS_NO_TRACE1755 psTrace(TRACE, 6, "Parabolic Upper fit results: %f + %f x + %f x^2\n",1756 poly->coeff[0], poly->coeff[1], poly->coeff[2]);1757 psTrace(TRACE, 6, "The upper mean is %f.\n", upperMean);1758 psTrace(TRACE, 6, "The upper stdev is %f.\n", upperStdev);1759 #endif1760 1761 // if the resulting value is outside of the range binMin - binMax, use the upper value1762 if (done && (guessMean > PS_BIN_MIDPOINT(histogram, binMax - 1))) {1763 guessMean = upperMean;1764 guessStdev = upperStdev;1765 }1766 1767 psFree (poly);1768 }1769 1770 // Clean up after fitting1771 psFree (histogram);1772 psFree (statsMinMax);1773 }1774 1775 // The fitted mean is the Gaussian mean.1776 stats->fittedMean = guessMean;1777 psTrace(TRACE, 6, "The fitted mean is %f.\n", stats->fittedMean);1778 1779 // The fitted standard deviation1780 stats->fittedStdev = guessStdev;1781 psTrace(TRACE, 6, "The fitted stdev is %f.\n", stats->fittedStdev);1782 1783 stats->results |= PS_STAT_FITTED_MEAN_V3;1784 stats->results |= PS_STAT_FITTED_STDEV_V3;1785 1786 return true;1787 }1788 1789 /********************1790 * perform an asymmetric fit to the population1791 * vectorFittedStats_v4 requires guess for fittedMean and fittedStdev1792 * robustN50 should also be set1793 * gaussian fit is performed using 2D polynomial to ln(y)1794 * this version follows the upper portion of the distribution until it passes 0.5*peak1795 ********************/1796 static bool vectorFittedStats_v4 (const psVector* myVector,1797 const psVector* errors,1798 psVector* mask,1799 psVectorMaskType maskVal,1800 psStats* stats)1801 {1802 1803 // This procedure requires the mean. If it has not been already1804 // calculated, then call vectorSampleMean()1805 if (!(stats->results & PS_STAT_ROBUST_MEDIAN)) {1806 if (!vectorRobustStats(myVector, errors, mask, maskVal, stats)) {1807 psError(PS_ERR_UNKNOWN, false, "failure to measure robust stats\n");1808 return false;1809 }1810 }1811 1812 // If the mean is NAN, then generate a warning and set the stdev to NAN.1813 if (isnan(stats->robustMedian)) {1814 stats->fittedMean = NAN;1815 stats->fittedStdev = NAN;1816 stats->results |= PS_STAT_FITTED_MEAN_V4;1817 stats->results |= PS_STAT_FITTED_STDEV_V4;1818 return true;1819 }1820 1821 if (stats->robustStdev <= FLT_EPSILON) {1822 stats->fittedMean = stats->robustMedian;1823 stats->fittedStdev = stats->robustStdev;1824 stats->results |= PS_STAT_FITTED_MEAN_V4;1825 stats->results |= PS_STAT_FITTED_STDEV_V4;1826 return true;1827 }1828 1829 float guessStdev = stats->robustStdev; // pass the guess sigma1830 float guessMean = stats->robustMedian; // pass the guess mean1831 1832 psTrace(TRACE, 6, "The ** starting ** guess mean is %f.\n", guessMean);1833 psTrace(TRACE, 6, "The ** starting ** guess stdev is %f.\n", guessStdev);1834 1835 bool done = false;1836 for (int iteration = 0; !done && (iteration < 2); iteration ++) {1837 psStats *statsMinMax = psStatsAlloc(PS_STAT_MIN | PS_STAT_MAX); // Statistics for min and max1838 1839 psF32 binSize = 1;1840 if (stats->options & PS_STAT_USE_BINSIZE) {1841 // Set initial bin size to the specified value.1842 binSize = stats->binsize;1843 psTrace(TRACE, 6, "Setting initial robust bin size to %.2f\n", binSize);1844 } else {1845 // construct a histogram with (sigma/2 < binsize < sigma)1846 // set roughly so that the lowest bins have about 2 cnts1847 // Nsmallest ~ N50 / (4*dN))1848 psF32 dN = PS_MAX (1, PS_MIN (4, stats->robustN50 / 8));1849 binSize = guessStdev / dN;1850 }1851 1852 // Determine the min/max of the vector (which prior outliers masked out)1853 int numValid = vectorMinMax(myVector, mask, maskVal, statsMinMax); // Number of values1854 float min = statsMinMax->min;1855 float max = statsMinMax->max;1856 if (numValid == 0 || isnan(min) || isnan(max)) {1857 COUNT_WARNING(10, 100, "Failed to calculate the min/max of the input vector.\n");1858 psFree(statsMinMax);1859 1155 goto escape; 1860 1156 } … … 1865 1161 stats->fittedMean = min; 1866 1162 stats->fittedStdev = 0.0; 1867 stats->results |= PS_STAT_FITTED_MEAN _V4;1868 stats->results |= PS_STAT_FITTED_STDEV _V4;1163 stats->results |= PS_STAT_FITTED_MEAN; 1164 stats->results |= PS_STAT_FITTED_STDEV; 1869 1165 return true; 1870 1166 } … … 1934 1230 // assume a reasonably well-defined gaussian-like population; run from peak out until val < 0.25*peak 1935 1231 1232 float clippedMean = PS_BIN_MIDPOINT(histogram, binPeak); 1233 1936 1234 psTrace(TRACE, 6, "The clipped numBins is %ld\n", binMax - binMin); 1937 1235 psTrace(TRACE, 6, "The clipped min is %f (%ld)\n", PS_BIN_MIDPOINT(histogram, binMin), binMin); 1938 psTrace(TRACE, 6, "The clipped max is %f (%ld)\n", 1939 PS_BIN_MIDPOINT(histogram, binMax - 1), binMax - 1); 1940 psTrace(TRACE, 6, "The clipped peak is %f (%ld)\n", PS_BIN_MIDPOINT(histogram, binPeak), binPeak); 1236 psTrace(TRACE, 6, "The clipped max is %f (%ld)\n", PS_BIN_MIDPOINT(histogram, binMax - 1), binMax - 1); 1237 psTrace(TRACE, 6, "The clipped peak is %f (%ld)\n", clippedMean, binPeak); 1941 1238 psTrace(TRACE, 6, "The clipped peak value is %f\n", histogram->nums->data.F32[binPeak]); 1942 1239 1240 float lowfitMean = NAN; 1241 float lowfitStdev = NAN; 1943 1242 { 1944 1243 // fit the lower half of the distribution … … 2014 1313 2015 1314 // calculate lower mean & stdev from parabolic fit -- use this as the result 2016 guessStdev = sqrt(-0.5/poly->coeff[2]); 2017 guessMean = poly->coeff[1]*PS_SQR(guessStdev); 2018 if (guessStdev > 0.75*stats->robustStdev) { 2019 done = true; 2020 } 2021 psTrace(TRACE, 6, "Parabolic Lower fit results: %f + %f x + %f x^2\n", 2022 poly->coeff[0], poly->coeff[1], poly->coeff[2]); 2023 psTrace(TRACE, 6, "The lower mean is %f.\n", guessMean); 2024 psTrace(TRACE, 6, "The lower stdev is %f.\n", guessStdev); 1315 lowfitStdev = sqrt(-0.5/poly->coeff[2]); 1316 lowfitMean = poly->coeff[1]*PS_SQR(lowfitStdev); 1317 1318 psTrace(TRACE, 6, "Parabolic Lower fit results: %f + %f x + %f x^2\n", poly->coeff[0], poly->coeff[1], poly->coeff[2]); 1319 psTrace(TRACE, 6, "The lower mean is %f.\n", lowfitMean); 1320 psTrace(TRACE, 6, "The lower stdev is %f.\n", lowfitStdev); 2025 1321 2026 1322 psFree(poly); 2027 1323 } 2028 1324 2029 // if we converge on a solution outside the range binMin - binMax, use a more conservative range 2030 float minValue = PS_BIN_MIDPOINT(histogram, binMin);2031 float maxValue = PS_BIN_MIDPOINT(histogram, binMax - 1);2032 2033 if (done && ((guessMean < minValue) || (guessMean > maxValue))) { 2034 psTrace(TRACE, 6, "Inconsistent result, re-trying the fit\n"); 2035 1325 float fullfitMean = NAN; 1326 float fullfitStdev = NAN; 1327 float minValueSym = NAN; 1328 float maxValueSym = NAN; 1329 1330 // try the full fit as well: 1331 { 2036 1332 // fit a symmetric distribution 2037 1333 // run up until we drop below 0.15*valPeak … … 2085 1381 2086 1382 // calculate upper mean & stdev from parabolic fit -- ignore this value 2087 guessStdev = sqrt(-0.5/poly->coeff[2]);2088 guessMean = poly->coeff[1]*PS_SQR(guessStdev);1383 fullfitStdev = sqrt(-0.5/poly->coeff[2]); 1384 fullfitMean = poly->coeff[1]*PS_SQR(fullfitStdev); 2089 1385 #ifndef PS_NO_TRACE 2090 psTrace(TRACE, 6, "Parabolic Symmetric fit results: %f + %f x + %f x^2\n", 2091 poly->coeff[0], poly->coeff[1], poly->coeff[2]); 2092 psTrace(TRACE, 6, "The symmetric mean is %f.\n", guessMean); 2093 psTrace(TRACE, 6, "The symmetric stdev is %f.\n", guessStdev); 1386 psTrace(TRACE, 6, "Parabolic Symmetric fit results: %f + %f x + %f x^2\n", poly->coeff[0], poly->coeff[1], poly->coeff[2]); 1387 psTrace(TRACE, 6, "The symmetric mean is %f.\n", fullfitMean); 1388 psTrace(TRACE, 6, "The symmetric stdev is %f.\n", fullfitStdev); 2094 1389 #endif 2095 1390 2096 1391 // if we converge on a solution outside the range binMin - binMax, use a more conservative range 2097 floatminValueSym = PS_BIN_MIDPOINT(histogram, binS);2098 floatmaxValueSym = PS_BIN_MIDPOINT(histogram, binE - 1);1392 minValueSym = PS_BIN_MIDPOINT(histogram, binS); 1393 maxValueSym = PS_BIN_MIDPOINT(histogram, binE - 1); 2099 1394 2100 1395 // saturate on min or max value 2101 if ( guessMean < minValueSym) {2102 guessMean = minValueSym;1396 if (fullfitMean < minValueSym) { 1397 fullfitMean = minValueSym; 2103 1398 psTrace(TRACE, 6, "The symmetric mean is out of bounds, saturating to %f.\n", guessMean); 2104 1399 } 2105 1400 2106 1401 // saturate on min or max value 2107 if ( guessMean > maxValueSym) {2108 guessMean = maxValueSym;1402 if (fullfitMean > maxValueSym) { 1403 fullfitMean = maxValueSym; 2109 1404 psTrace(TRACE, 6, "The symmetric mean is out of bounds, saturating to %f.\n", guessMean); 2110 1405 } … … 2112 1407 psFree (poly); 2113 1408 } 1409 1410 // we now have the fullfit and the lowfit mean and stdev values 1411 // accept the fullfit unless minValueSym < lowfitMean < fullfitMean 1412 1413 if (isfinite(lowfitMean) && isfinite(lowfitStdev) && (lowfitMean < fullfitMean) && (lowfitMean > minValueSym)) { 1414 guessMean = lowfitMean; 1415 guessStdev = lowfitStdev; 1416 } else { 1417 guessMean = fullfitMean; 1418 guessStdev = fullfitStdev; 1419 } 1420 1421 if (!isfinite(guessMean) || !isfinite(guessStdev)) { 1422 guessMean = stats->robustMedian; 1423 guessStdev = stats->robustStdev; 1424 } 1425 1426 if (guessStdev > 0.75*stats->robustStdev) { 1427 done = true; 1428 } 2114 1429 2115 1430 // Clean up after fitting … … 2126 1441 psTrace(TRACE, 6, "The fitted stdev is %f.\n", stats->fittedStdev); 2127 1442 2128 stats->results |= PS_STAT_FITTED_MEAN _V4;2129 stats->results |= PS_STAT_FITTED_STDEV _V4;1443 stats->results |= PS_STAT_FITTED_MEAN; 1444 stats->results |= PS_STAT_FITTED_STDEV; 2130 1445 2131 1446 return true; … … 2134 1449 stats->fittedMean = NAN; 2135 1450 stats->fittedStdev = NAN; 2136 stats->results |= PS_STAT_FITTED_MEAN _V4;2137 stats->results |= PS_STAT_FITTED_STDEV _V4;1451 stats->results |= PS_STAT_FITTED_MEAN; 1452 stats->results |= PS_STAT_FITTED_STDEV; 2138 1453 2139 1454 return true; … … 2442 1757 2443 1758 // ************************************************************************ 2444 if (stats->options & (PS_STAT_FITTED_MEAN_V2 | PS_STAT_FITTED_STDEV_V2)) {2445 if (stats->options & (PS_STAT_FITTED_MEAN | PS_STAT_FITTED_STDEV)) {2446 psAbort("you may not specify both FITTED_MEAN and FITTED_MEAN_V2");2447 }2448 if (!vectorFittedStats_v2(inF32, errorsF32, maskVector, maskVal, stats)) {2449 psError(PS_ERR_UNKNOWN, false, _("Failed to calculate fitted statistics"));2450 status &= false;2451 }2452 }2453 2454 // ************************************************************************2455 if (stats->options & (PS_STAT_FITTED_MEAN_V3 | PS_STAT_FITTED_STDEV_V3)) {2456 if (stats->options & (PS_STAT_FITTED_MEAN | PS_STAT_FITTED_STDEV)) {2457 psAbort("you may not specify both FITTED_MEAN and FITTED_MEAN_V3");2458 }2459 if (!vectorFittedStats_v3(inF32, errorsF32, maskVector, maskVal, stats)) {2460 psError(PS_ERR_UNKNOWN, false, _("Failed to calculate fitted statistics"));2461 status &= false;2462 }2463 }2464 2465 // ************************************************************************2466 if (stats->options & (PS_STAT_FITTED_MEAN_V4 | PS_STAT_FITTED_STDEV_V4)) {2467 if (stats->options & (PS_STAT_FITTED_MEAN | PS_STAT_FITTED_STDEV)) {2468 psAbort("you may not specify both FITTED_MEAN and FITTED_MEAN_V4");2469 }2470 if (!vectorFittedStats_v4(inF32, errorsF32, maskVector, maskVal, stats)) {2471 psError(PS_ERR_UNKNOWN, false, _("Failed to calculate fitted statistics"));2472 status &= false;2473 }2474 }2475 2476 // ************************************************************************2477 1759 if ((stats->options & PS_STAT_CLIPPED_MEAN) || (stats->options & PS_STAT_CLIPPED_STDEV)) { 2478 1760 if (!vectorClippedStats(inF32, errorsF32, maskVector, maskVal, stats)) { … … 2513 1795 READ_STAT("ROBUST_STDEV", PS_STAT_ROBUST_STDEV); 2514 1796 READ_STAT("ROBUST_QUARTILE", PS_STAT_ROBUST_QUARTILE); 2515 READ_STAT("FITTED", PS_STAT_FITTED_MEAN);2516 READ_STAT("FITTED_MEAN", PS_STAT_FITTED_MEAN);2517 READ_STAT("FITTED_STDEV", PS_STAT_FITTED_STDEV);2518 READ_STAT("FITTED_V2", PS_STAT_FITTED_MEAN _V2);2519 READ_STAT("FITTED_MEAN_V2", PS_STAT_FITTED_MEAN _V2);2520 READ_STAT("FITTED_STDEV_V2", PS_STAT_FITTED_STDEV _V2);2521 READ_STAT("FITTED_V3", PS_STAT_FITTED_MEAN _V3);2522 READ_STAT("FITTED_MEAN_V3", PS_STAT_FITTED_MEAN _V3);2523 READ_STAT("FITTED_STDEV_V3", PS_STAT_FITTED_STDEV _V3);2524 READ_STAT("FITTED_V4", PS_STAT_FITTED_MEAN _V4);2525 READ_STAT("FITTED_MEAN_V4", PS_STAT_FITTED_MEAN _V4);2526 READ_STAT("FITTED_STDEV_V4", PS_STAT_FITTED_STDEV _V4);1797 READ_STAT("FITTED", PS_STAT_FITTED_MEAN); 1798 READ_STAT("FITTED_MEAN", PS_STAT_FITTED_MEAN); 1799 READ_STAT("FITTED_STDEV", PS_STAT_FITTED_STDEV); 1800 READ_STAT("FITTED_V2", PS_STAT_FITTED_MEAN); 1801 READ_STAT("FITTED_MEAN_V2", PS_STAT_FITTED_MEAN); 1802 READ_STAT("FITTED_STDEV_V2", PS_STAT_FITTED_STDEV); 1803 READ_STAT("FITTED_V3", PS_STAT_FITTED_MEAN); 1804 READ_STAT("FITTED_MEAN_V3", PS_STAT_FITTED_MEAN); 1805 READ_STAT("FITTED_STDEV_V3", PS_STAT_FITTED_STDEV); 1806 READ_STAT("FITTED_V4", PS_STAT_FITTED_MEAN); 1807 READ_STAT("FITTED_MEAN_V4", PS_STAT_FITTED_MEAN); 1808 READ_STAT("FITTED_STDEV_V4", PS_STAT_FITTED_STDEV); 2527 1809 READ_STAT("CLIPPED", PS_STAT_CLIPPED_MEAN); 2528 1810 READ_STAT("CLIPPED_MEAN", PS_STAT_CLIPPED_MEAN); … … 2554 1836 WRITE_STAT("FITTED_MEAN", PS_STAT_FITTED_MEAN); 2555 1837 WRITE_STAT("FITTED_STDEV", PS_STAT_FITTED_STDEV); 2556 WRITE_STAT("FITTED_MEAN_V2", PS_STAT_FITTED_MEAN_V2);2557 WRITE_STAT("FITTED_STDEV_V2", PS_STAT_FITTED_STDEV_V2);2558 WRITE_STAT("FITTED_MEAN_V3", PS_STAT_FITTED_MEAN_V3);2559 WRITE_STAT("FITTED_STDEV_V3", PS_STAT_FITTED_STDEV_V3);2560 WRITE_STAT("FITTED_MEAN_V4", PS_STAT_FITTED_MEAN_V4);2561 WRITE_STAT("FITTED_STDEV_V4", PS_STAT_FITTED_STDEV_V4);2562 1838 WRITE_STAT("CLIPPED_MEAN", PS_STAT_CLIPPED_MEAN); 2563 1839 WRITE_STAT("CLIPPED_STDEV", PS_STAT_CLIPPED_STDEV); … … 2610 1886 case PS_STAT_FITTED_MEAN: 2611 1887 case PS_STAT_FITTED_STDEV: 2612 case PS_STAT_FITTED_MEAN_V2:2613 case PS_STAT_FITTED_STDEV_V2:2614 case PS_STAT_FITTED_MEAN_V3:2615 case PS_STAT_FITTED_STDEV_V3:2616 case PS_STAT_FITTED_MEAN_V4:2617 case PS_STAT_FITTED_STDEV_V4:2618 1888 case PS_STAT_CLIPPED_MEAN: 2619 1889 case PS_STAT_CLIPPED_STDEV: … … 2631 1901 { 2632 1902 return options & (PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_MEDIAN | PS_STAT_ROBUST_MEDIAN | 2633 PS_STAT_CLIPPED_MEAN | PS_STAT_FITTED_MEAN | PS_STAT_FITTED_MEAN_V2 | 2634 PS_STAT_FITTED_MEAN_V3 | PS_STAT_FITTED_MEAN_V4); 1903 PS_STAT_CLIPPED_MEAN | PS_STAT_FITTED_MEAN); 2635 1904 } 2636 1905 … … 2638 1907 { 2639 1908 return options & (PS_STAT_SAMPLE_STDEV | PS_STAT_ROBUST_STDEV | PS_STAT_CLIPPED_STDEV | 2640 PS_STAT_FITTED_STDEV | PS_STAT_FITTED_STDEV_V2 | PS_STAT_FITTED_STDEV_V3 | 2641 PS_STAT_FITTED_STDEV_V4); 1909 PS_STAT_FITTED_STDEV); 2642 1910 } 2643 1911 … … 2665 1933 case PS_STAT_FITTED_STDEV: 2666 1934 return stats->fittedStdev; 2667 case PS_STAT_FITTED_MEAN_V2:2668 return stats->fittedMean;2669 case PS_STAT_FITTED_STDEV_V2:2670 return stats->fittedStdev;2671 case PS_STAT_FITTED_MEAN_V3:2672 return stats->fittedMean;2673 case PS_STAT_FITTED_STDEV_V3:2674 return stats->fittedStdev;2675 case PS_STAT_FITTED_MEAN_V4:2676 return stats->fittedMean;2677 case PS_STAT_FITTED_STDEV_V4:2678 return stats->fittedStdev;2679 1935 case PS_STAT_CLIPPED_MEAN: 2680 1936 return stats->clippedMean; … … 3115 2371 return tmpFloat; 3116 2372 } 3117 3118 /******************************************************************************3119 NOTE: We assume unnormalized gaussians.3120 *****************************************************************************/3121 static psF32 minimizeLMChi2Gauss1D(psVector *deriv,3122 const psVector *params,3123 const psVector *coords3124 )3125 {3126 psTrace(TRACE, 4, "---- %s() begin ----\n", __func__);3127 PS_ASSERT_VECTOR_NON_NULL(params, NAN);3128 PS_ASSERT_VECTOR_SIZE(params, (long)2, NAN);3129 PS_ASSERT_VECTOR_TYPE(params, PS_TYPE_F32, NAN);3130 PS_ASSERT_VECTOR_NON_NULL(coords, NAN);3131 PS_ASSERT_VECTOR_SIZE(coords, (long)1, NAN);3132 PS_ASSERT_VECTOR_TYPE(coords, PS_TYPE_F32, NAN);3133 3134 psF32 x = coords->data.F32[0];3135 psF32 mean = params->data.F32[0];3136 psF32 var = params->data.F32[1];3137 psF32 dx = (x - mean);3138 3139 psF32 gauss = exp (-0.5*PS_SQR(dx)/var);3140 if (deriv) {3141 PS_ASSERT_VECTOR_SIZE(deriv, (long)2, NAN);3142 PS_ASSERT_VECTOR_TYPE(deriv, PS_TYPE_F32, NAN);3143 psF32 tmp = dx * gauss;3144 deriv->data.F32[0] = tmp / var;3145 deriv->data.F32[1] = tmp * dx / (var * var);3146 }3147 3148 3149 psTrace(TRACE, 4, "---- %s() end ----\n", __func__);3150 return gauss;3151 } -
branches/eam_branches/ipp-20110213/psLib/src/math/psStats.h
r21183 r30863 43 43 PS_STAT_FITTED_MEAN = 0x001000, ///< Fitted Mean 44 44 PS_STAT_FITTED_STDEV = 0x002000, ///< Fitted Standard Deviation 45 PS_STAT_FITTED_MEAN_V2 = 0x004000, ///< Fitted Mean46 PS_STAT_FITTED_STDEV_V2 = 0x008000, ///< Fitted Standard Deviation47 PS_STAT_FITTED_MEAN_V3 = 0x010000, ///< Fitted Mean48 PS_STAT_FITTED_STDEV_V3 = 0x020000, ///< Fitted Standard Deviation49 45 PS_STAT_CLIPPED_MEAN = 0x040000, ///< Clipped Mean 50 46 PS_STAT_CLIPPED_STDEV = 0x080000, ///< Clipped Standard Deviation 51 47 PS_STAT_USE_RANGE = 0x100000, ///< Range 52 48 PS_STAT_USE_BINSIZE = 0x200000, ///< Binsize 53 PS_STAT_FITTED_MEAN_V4 = 0x400000, ///< Fitted Mean54 PS_STAT_FITTED_STDEV_V4 = 0x800000, ///< Fitted Standard Deviation55 49 } psStatsOptions; 56 50 -
branches/eam_branches/ipp-20110213/psLib/test/math/tap_psStats_Sample_01.c
r30077 r30863 586 586 psFree (stats); 587 587 588 stats = psStatsAlloc (PS_STAT_FITTED_MEAN _V2 | PS_STAT_FITTED_STDEV_V2| PS_STAT_USE_BINSIZE);588 stats = psStatsAlloc (PS_STAT_FITTED_MEAN | PS_STAT_FITTED_STDEV | PS_STAT_USE_BINSIZE); 589 589 stats->binsize = 1.0; 590 590 psVectorStats (stats, y, NULL, NULL, 1); … … 622 622 psFree (stats); 623 623 624 stats = psStatsAlloc (PS_STAT_FITTED_MEAN _V2 | PS_STAT_FITTED_STDEV_V2| PS_STAT_USE_BINSIZE);624 stats = psStatsAlloc (PS_STAT_FITTED_MEAN | PS_STAT_FITTED_STDEV | PS_STAT_USE_BINSIZE); 625 625 stats->binsize = 1.0; 626 626 psVectorStats (stats, y, NULL, NULL, 1); … … 657 657 psFree (stats); 658 658 659 stats = psStatsAlloc (PS_STAT_FITTED_MEAN _V2 | PS_STAT_FITTED_STDEV_V2| PS_STAT_USE_BINSIZE);659 stats = psStatsAlloc (PS_STAT_FITTED_MEAN | PS_STAT_FITTED_STDEV | PS_STAT_USE_BINSIZE); 660 660 stats->binsize = 1.0; 661 661 psVectorStats (stats, y, NULL, NULL, 1); … … 694 694 psFree (stats); 695 695 696 stats = psStatsAlloc (PS_STAT_FITTED_MEAN _V2 | PS_STAT_FITTED_STDEV_V2| PS_STAT_USE_BINSIZE);696 stats = psStatsAlloc (PS_STAT_FITTED_MEAN | PS_STAT_FITTED_STDEV | PS_STAT_USE_BINSIZE); 697 697 stats->binsize = 1.0; 698 698 psVectorStats (stats, y, NULL, NULL, 1); -
branches/eam_branches/ipp-20110213/psLib/test/optime/tap_psStatsTiming.c
r24572 r30863 678 678 psMemId id = psMemGetId(); 679 679 680 psStats *stats = psStatsAlloc (PS_STAT_FITTED_MEAN _V2 | PS_STAT_FITTED_STDEV_V2);680 psStats *stats = psStatsAlloc (PS_STAT_FITTED_MEAN | PS_STAT_FITTED_STDEV); 681 681 psVector *rnd2 = psVectorAlloc (1000, PS_TYPE_F32); 682 682 for (int i = 0; i < rnd2->n; i++) … … 702 702 psMemId id = psMemGetId(); 703 703 704 psStats *stats = psStatsAlloc (PS_STAT_FITTED_MEAN _V2 | PS_STAT_FITTED_STDEV_V2);704 psStats *stats = psStatsAlloc (PS_STAT_FITTED_MEAN | PS_STAT_FITTED_STDEV); 705 705 psVector *rnd2 = psVectorAlloc (3000, PS_TYPE_F32); 706 706 for (int i = 0; i < rnd2->n; i++) … … 725 725 psMemId id = psMemGetId(); 726 726 727 psStats *stats = psStatsAlloc (PS_STAT_FITTED_MEAN _V2 | PS_STAT_FITTED_STDEV_V2);727 psStats *stats = psStatsAlloc (PS_STAT_FITTED_MEAN | PS_STAT_FITTED_STDEV); 728 728 psVector *rnd2 = psVectorAlloc (10000, PS_TYPE_F32); 729 729 for (int i = 0; i < rnd2->n; i++) … … 790 790 psMemId id = psMemGetId(); 791 791 792 psStats *stats = psStatsAlloc (PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_STDEV | PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV | PS_STAT_FITTED_MEAN _V2 | PS_STAT_FITTED_STDEV_V2);792 psStats *stats = psStatsAlloc (PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_STDEV | PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV | PS_STAT_FITTED_MEAN | PS_STAT_FITTED_STDEV); 793 793 psVector *sample = psVectorAlloc (1000, PS_TYPE_F32); 794 794 psVector *robust = psVectorAlloc (1000, PS_TYPE_F32);
Note:
See TracChangeset
for help on using the changeset viewer.
