Changeset 2778 for trunk/psLib/src/math/psStats.c
- Timestamp:
- Dec 21, 2004, 10:42:07 AM (22 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/math/psStats.c (modified) (26 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/math/psStats.c
r2762 r2778 9 9 * @author GLG, MHPCC 10 10 * 11 * @version $Revision: 1.10 4$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-12-2 0 21:39:42$11 * @version $Revision: 1.105 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-12-21 20:42:07 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 146 146 *****************************************************************************/ 147 147 int p_psVectorSampleMean(const psVector* restrict myVector, 148 const psVector* restrict errors, 148 149 const psVector* restrict maskVector, 149 150 psU32 maskVal, … … 156 157 // If PS_STAT_USE_RANGE is requested, then we enter a slightly different 157 158 // loop. 158 if (stats->options & PS_STAT_USE_RANGE) { 159 if (maskVector != NULL) { 160 for (i = 0; i < myVector->n; i++) { 161 // Check if the data is with the specified range 162 if (!(maskVal & maskVector->data.U8[i]) && 163 (stats->min <= myVector->data.F32[i]) && 164 (myVector->data.F32[i] <= stats->max)) { 159 if (errors == NULL) { 160 if (stats->options & PS_STAT_USE_RANGE) { 161 if (maskVector != NULL) { 162 for (i = 0; i < myVector->n; i++) { 163 // Check if the data is with the specified range 164 if (!(maskVal & maskVector->data.U8[i]) && 165 (stats->min <= myVector->data.F32[i]) && 166 (myVector->data.F32[i] <= stats->max)) { 167 mean += myVector->data.F32[i]; 168 count++; 169 } 170 } 171 if (count != 0) { 172 mean /= (float)count; 173 } else { 174 mean = NAN; 175 } 176 177 } else { 178 for (i = 0; i < myVector->n; i++) { 179 if ((stats->min <= myVector->data.F32[i]) && 180 (myVector->data.F32[i] <= stats->max)) { 181 mean += myVector->data.F32[i]; 182 count++; 183 } 184 } 185 if (count != 0) { 186 mean /= (float)count; 187 } else { 188 mean = NAN; 189 } 190 } 191 } else { 192 if (maskVector != NULL) { 193 for (i = 0; i < myVector->n; i++) { 194 if (!(maskVal & maskVector->data.U8[i])) { 195 mean += myVector->data.F32[i]; 196 count++; 197 } 198 } 199 if (count != 0) { 200 mean /= (float)count; 201 } else { 202 mean = NAN; 203 } 204 } else { 205 for (i = 0; i < myVector->n; i++) { 165 206 mean += myVector->data.F32[i]; 166 count++; 167 } 168 } 169 if (count != 0) { 170 mean /= (float)count; 207 } 208 mean /= (float)myVector->n; 209 } 210 } 211 } else { 212 psF32 errorDivisor = 0.0; 213 if (stats->options & PS_STAT_USE_RANGE) { 214 if (maskVector != NULL) { 215 for (i = 0; i < myVector->n; i++) { 216 // Check if the data is with the specified range 217 if (!(maskVal & maskVector->data.U8[i]) && 218 (stats->min <= myVector->data.F32[i]) && 219 (myVector->data.F32[i] <= stats->max)) { 220 mean += myVector->data.F32[i]/errors->data.F32[i]; 221 errorDivisor+= (1.0 / errors->data.F32[i]); 222 count++; 223 } 224 } 225 if (count != 0) { 226 mean /= errorDivisor; 227 } else { 228 mean = NAN; 229 } 230 171 231 } else { 172 mean = NAN; 173 } 174 175 } else { 176 for (i = 0; i < myVector->n; i++) { 177 if ((stats->min <= myVector->data.F32[i]) && 178 (myVector->data.F32[i] <= stats->max)) { 179 mean += myVector->data.F32[i]; 180 count++; 181 } 182 } 183 if (count != 0) { 184 mean /= (float)count; 232 for (i = 0; i < myVector->n; i++) { 233 if ((stats->min <= myVector->data.F32[i]) && 234 (myVector->data.F32[i] <= stats->max)) { 235 mean += myVector->data.F32[i]/errors->data.F32[i]; 236 errorDivisor+= (1.0 / errors->data.F32[i]); 237 count++; 238 } 239 } 240 if (count != 0) { 241 mean /= errorDivisor; 242 } else { 243 mean = NAN; 244 } 245 } 246 } else { 247 if (maskVector != NULL) { 248 for (i = 0; i < myVector->n; i++) { 249 if (!(maskVal & maskVector->data.U8[i])) { 250 mean += myVector->data.F32[i]/errors->data.F32[i]; 251 errorDivisor+= (1.0 / errors->data.F32[i]); 252 count++; 253 } 254 } 255 if (count != 0) { 256 mean /= errorDivisor; 257 } else { 258 mean = NAN; 259 } 185 260 } else { 186 mean = NAN; 187 } 188 } 189 } else { 190 if (maskVector != NULL) { 191 for (i = 0; i < myVector->n; i++) { 192 if (!(maskVal & maskVector->data.U8[i])) { 193 mean += myVector->data.F32[i]; 194 count++; 195 } 196 } 197 if (count != 0) { 198 mean /= (float)count; 199 } else { 200 mean = NAN; 201 } 202 } else { 203 for (i = 0; i < myVector->n; i++) { 204 mean += myVector->data.F32[i]; 205 } 206 mean /= (float)myVector->n; 261 for (i = 0; i < myVector->n; i++) { 262 mean += myVector->data.F32[i]/errors->data.F32[i]; 263 errorDivisor+= (1.0 / errors->data.F32[i]); 264 } 265 mean /= errorDivisor; 266 } 207 267 } 208 268 } … … 349 409 /****************************************************************************** 350 410 p_psVectorNValues(myVector, maskVector, maskVal, stats): This routine returns 351 "true" if the inputPsVector as 1 or more valid elements (a valid element is an352 unmasked element within the specifi ned min/max range). Otherwise, return411 "true" if the inputPsVector has 1 or more valid elements (a valid element is an 412 unmasked element within the specified min/max range). Otherwise, return 353 413 "false". 354 414 *****************************************************************************/ … … 447 507 median of the input vector. Returns true on success (including if there were 448 508 no valid input vector elements). 509 510 XXX: Use static vectors for sort arrays. 449 511 *****************************************************************************/ 450 512 bool p_psVectorSampleMedian(const psVector* restrict myVector, … … 522 584 } 523 585 524 // Calculate the median exactly. 586 // Calculate the median exactly. Use the average if the number of samples 587 // is even. 525 588 if (0 == (nValues % 2)) { 526 589 stats->sampleMedian = 0.5 * (sortedVector->data.F32[(nValues / 2) - 1] + … … 723 786 724 787 *****************************************************************************/ 725 void p_psVectorSampleStdev(const psVector* restrict myVector, 726 const psVector* restrict maskVector, 727 psU32 maskVal, 728 psStats* stats) 788 void p_psVectorSampleStdevOLD(const psVector* restrict myVector, 789 const psVector* restrict errors, 790 const psVector* restrict maskVector, 791 psU32 maskVal, 792 psStats* stats) 729 793 { 730 794 psS32 i = 0; // Loop index variable … … 739 803 // calculated, then call p_psVectorSampleMean() 740 804 if (0 != isnan(stats->sampleMean)) { 741 p_psVectorSampleMean(myVector, maskVector, maskVal, stats);805 p_psVectorSampleMean(myVector, errors, maskVector, maskVal, stats); 742 806 } 743 807 // If the mean is NAN, then generate a warning and set the stdev to NAN. … … 801 865 } else { 802 866 countFloat = (float)countInt; 803 #ifdef DARWIN 804 805 stats->sampleStdev = (float)sqrt((sumSquares - 806 (sumDiffs * sumDiffs / countFloat)) / (countFloat - 1)); 807 #else 808 809 stats->sampleStdev = sqrtf((sumSquares - 810 (sumDiffs * sumDiffs / countFloat)) / (countFloat - 1)); 811 #endif 812 813 } 814 } 815 867 stats->sampleStdev = PS_SQRT_F32((sumSquares - (sumDiffs * sumDiffs / countFloat)) / (countFloat - 1)); 868 } 869 } 816 870 /****************************************************************************** 817 p_psVectorClippedStats(myVector, maskVector, maskVal, stats): calculates the 871 p_psVectorSampleStdev(myVector, maskVector, maskVal, stats): calculates the 872 stdev of the input vector. 873 Inputs 874 myVector 875 maskVector 876 maskVal 877 stats 878 Returns 879 NULL 880 881 *****************************************************************************/ 882 void p_psVectorSampleStdev(const psVector* restrict myVector, 883 const psVector* restrict errors, 884 const psVector* restrict maskVector, 885 psU32 maskVal, 886 psStats* stats) 887 { 888 psS32 i = 0; // Loop index variable 889 psS32 countInt = 0; // # of data points being used 890 float countFloat = 0.0; // # of data points being used 891 float mean = 0.0; // The mean 892 float diff = 0.0; // Used in calculating stdev 893 float sumSquares = 0.0; // temporary variable 894 float sumDiffs = 0.0; // temporary variable 895 // psF32 sum1; 896 // psF32 sum2; 897 psF32 errorDivisor; 898 899 // This procedure requires the mean. If it has not been already 900 // calculated, then call p_psVectorSampleMean() 901 if (0 != isnan(stats->sampleMean)) { 902 p_psVectorSampleMean(myVector, errors, maskVector, maskVal, stats); 903 } 904 // If the mean is NAN, then generate a warning and set the stdev to NAN. 905 if (0 != isnan(stats->sampleMean)) { 906 stats->sampleStdev = NAN; 907 psLogMsg(__func__, PS_LOG_WARN, "WARNING: p_psVectorSampleStdev(): p_psVectorSampleMean() reported a NAN mean.\n"); 908 return; 909 } 910 911 mean = stats->sampleMean; 912 if (stats->options & PS_STAT_USE_RANGE) { 913 if (maskVector != NULL) { 914 for (i = 0; i < myVector->n; i++) { 915 if (!(maskVal & maskVector->data.U8[i]) && 916 (stats->min <= myVector->data.F32[i]) && 917 (myVector->data.F32[i] <= stats->max)) { 918 diff = myVector->data.F32[i] - mean; 919 sumSquares += (diff * diff); 920 sumDiffs += diff; 921 countInt++; 922 errorDivisor+= (1.0 / PS_SQR(errors->data.F32[i])); 923 } 924 } 925 } else { 926 for (i = 0; i < myVector->n; i++) { 927 if ((stats->min <= myVector->data.F32[i]) && 928 (myVector->data.F32[i] <= stats->max)) { 929 diff = myVector->data.F32[i] - mean; 930 sumSquares += (diff * diff); 931 sumDiffs += diff; 932 countInt++; 933 errorDivisor+= (1.0 / PS_SQR(errors->data.F32[i])); 934 } 935 } 936 countInt = myVector->n; 937 } 938 } else { 939 if (maskVector != NULL) { 940 for (i = 0; i < myVector->n; i++) { 941 if (!(maskVal & maskVector->data.U8[i])) { 942 diff = myVector->data.F32[i] - mean; 943 sumSquares += (diff * diff); 944 sumDiffs += diff; 945 countInt++; 946 errorDivisor+= (1.0 / PS_SQR(errors->data.F32[i])); 947 } 948 } 949 } else { 950 for (i = 0; i < myVector->n; i++) { 951 diff = myVector->data.F32[i] - mean; 952 sumSquares += (diff * diff); 953 sumDiffs += diff; 954 countInt++; 955 } 956 countInt = myVector->n; 957 errorDivisor+= (1.0 / PS_SQR(errors->data.F32[i])); 958 } 959 } 960 961 if (countInt == 0) { 962 stats->sampleStdev = NAN; 963 psLogMsg(__func__, PS_LOG_WARN, "WARNING: p_psVectorSampleStdev(): no valid psVector elements (%d). Setting stats->sampleStdev = NAN.\n", countInt); 964 } else if (countInt == 1) { 965 stats->sampleStdev = 0.0; 966 psLogMsg(__func__, PS_LOG_WARN, "WARNING: p_psVectorSampleStdev(): only one valid psVector elements (%d). Setting stats->sampleStdev = 0.0.\n", countInt); 967 } else { 968 // XXX: The ADD specifies this as the definition of the standard 969 // deviation if the errors are known. Verify this with IfA: none of 970 // the data points in the vector are used. Verify that the masks and 971 // data ranges are used correctly. 972 if (errors != NULL) { 973 stats->sampleStdev = (1.0 / PS_SQRT_F32(errorDivisor)); 974 } else { 975 countFloat = (float)countInt; 976 stats->sampleStdev = PS_SQRT_F32((sumSquares - (sumDiffs * sumDiffs / countFloat)) / (countFloat - 1)); 977 978 } 979 } 980 } 981 982 /****************************************************************************** 983 p_psVectorClippedStats(myVector, errors, maskVector, maskVal, stats): calculates the 818 984 clipped stats (mean or stdev) of the input vector. 819 985 … … 829 995 *****************************************************************************/ 830 996 int p_psVectorClippedStats(const psVector* restrict myVector, 997 const psVector* restrict errors, 831 998 const psVector* restrict maskVector, 832 999 psU32 maskVal, … … 873 1040 874 1041 // 2. Compute the sample standard deviation. 875 p_psVectorSampleStdev(myVector, maskVector, maskVal, stats);1042 p_psVectorSampleStdev(myVector, errors, maskVector, maskVal, stats); 876 1043 if (isnan(stats->sampleStdev)) { 877 1044 psLogMsg(__func__, PS_LOG_WARN, "Call to p_psVectorSampleStdev returned NAN\n"); … … 894 1061 // 5. Repeat N times: 895 1062 for (i = 0; i < stats->clipIter; i++) { 896 for (j = 0; j < myVector->n; j++) { 897 // a) Exclude all values x_i for which |x_i - x| > K * stdev 898 if (fabs(myVector->data.F32[j] - clippedMean) > (stats->clipSigma * clippedStdev)) { 899 tmpMask->data.U8[i] = 0xff; 1063 // a) Exclude all values x_i for which |x_i - x| > K * stdev 1064 if (errors != NULL) { 1065 for (j = 0; j < myVector->n; j++) { 1066 if (fabs(myVector->data.F32[j] - clippedMean) > (stats->clipSigma * errors->data.F32[j])) { 1067 tmpMask->data.U8[i] = 0xff; 1068 } 1069 } 1070 } else { 1071 for (j = 0; j < myVector->n; j++) { 1072 if (fabs(myVector->data.F32[j] - clippedMean) > (stats->clipSigma * clippedStdev)) { 1073 tmpMask->data.U8[i] = 0xff; 1074 } 900 1075 } 901 1076 } 902 1077 903 1078 // b) compute new mean and stdev 904 p_psVectorSampleMean(myVector, tmpMask, maskVal, stats);905 p_psVectorSampleStdev(myVector, tmpMask, maskVal, stats);1079 p_psVectorSampleMean(myVector, errors, tmpMask, maskVal, stats); 1080 p_psVectorSampleStdev(myVector, errors, tmpMask, maskVal, stats); 906 1081 907 1082 // If the new mean and stdev are not NAN, then we use them. … … 1242 1417 *****************************************************************************/ 1243 1418 int p_psVectorRobustStats(const psVector* restrict myVector, 1419 const psVector* restrict errors, 1244 1420 const psVector* restrict maskVector, 1245 1421 psU32 maskVal, … … 1274 1450 // by computing the clipped standard deviation of the vector, and dividing 1275 1451 // that by 10.0; 1276 int rc = p_psVectorClippedStats(myVector, maskVector, maskVal, tmpStats); 1452 //XXX: add errors 1453 int rc = p_psVectorClippedStats(myVector, NULL, maskVector, maskVal, tmpStats); 1277 1454 if (rc != 0) { 1278 1455 psError(PS_ERR_UNEXPECTED_NULL, … … 1333 1510 1334 1511 // Populate the histogram array. 1335 psVectorHistogram(robustHistogram, myVector, maskVector, maskVal);1512 psVectorHistogram(robustHistogram, myVector, errors, maskVector, maskVal); 1336 1513 1337 1514 // Smooth the histogram, Gaussian-style. … … 1416 1593 } 1417 1594 } 1418 myStdev = sqrt((sumSquares - (sumDiffs * sumDiffs / countFloat)) / (countFloat - 1));1595 myStdev = PS_SQRT_F32((sumSquares - (sumDiffs * sumDiffs / countFloat)) / (countFloat - 1)); 1419 1596 1420 1597 // Using the above (myMean, myStdev) as initial estimates, we fit a … … 1674 1851 1675 1852 /***************************************************************************** 1676 psVectorHistogram(out, in, mask, maskVal): this procedure takes as input a1677 preallocated and initialized histogram structure. It fills the bins in that 1678 histogram structure in accordance with the input data "in" and the, possibly 1679 NULL, mask vector.1853 psVectorHistogram(out, in, errors, mask, maskVal): this procedure takes as 1854 input a preallocated and initialized histogram structure. It fills the bins 1855 in that histogram structure in accordance with the input data "in" and the, 1856 possibly NULL, mask vector. 1680 1857 1681 1858 Inputs: … … 1686 1863 Returns: 1687 1864 The histogram structure "out". 1865 1866 XXX: Waiting for direction on how to use the errors parameter. 1688 1867 *****************************************************************************/ 1689 1868 psHistogram* psVectorHistogram(psHistogram* out, 1690 1869 const psVector* restrict in, 1870 const psVector* restrict errors, 1691 1871 const psVector* restrict mask, 1692 1872 psU32 maskVal) … … 1700 1880 PS_VECTOR_CHECK_SIZE_EQUAL(in, mask, NULL); 1701 1881 PS_VECTOR_CHECK_TYPE(mask, PS_TYPE_U8, NULL); 1882 } 1883 if (errors != NULL) { 1884 PS_VECTOR_CHECK_SIZE_EQUAL(in, errors, NULL); 1885 PS_VECTOR_CHECK_TYPE(errors, in->type.type, NULL); 1702 1886 } 1703 1887 … … 1828 2012 psStats* psVectorStats(psStats* stats, 1829 2013 psVector* in, 2014 psVector* errors, 1830 2015 psVector* mask, 1831 2016 psU32 maskVal) … … 1837 2022 PS_VECTOR_CHECK_TYPE(mask, PS_TYPE_U8, stats); 1838 2023 } 2024 if (errors != NULL) { 2025 PS_VECTOR_CHECK_SIZE_EQUAL(errors, in, stats); 2026 PS_VECTOR_CHECK_TYPE(errors, in->type.type, stats); 2027 } 2028 1839 2029 psVector* inF32; 1840 psS32 mustFreeTmp = 1; 2030 psVector* errorsF32; 2031 psS32 mustFreeVectorIn = 1; 2032 psS32 mustFreeVectorErrors = 1; 1841 2033 1842 2034 inF32 = p_psConvertToF32((psVector *) in); 1843 2035 if (inF32 == NULL) { 1844 2036 inF32 = in; 1845 mustFreeTmp = 0; 2037 mustFreeVectorIn = 0; 2038 } 2039 errorsF32 = p_psConvertToF32((psVector *) errors); 2040 if (errorsF32 == NULL) { 2041 errorsF32 = errors; 2042 mustFreeVectorErrors = 0; 1846 2043 } 1847 2044 … … 1852 2049 // ************************************************************************ 1853 2050 if (stats->options & PS_STAT_SAMPLE_MEAN) { 1854 if (0 != p_psVectorSampleMean(inF32, mask, maskVal, stats)) {2051 if (0 != p_psVectorSampleMean(inF32, errorsF32, mask, maskVal, stats)) { 1855 2052 psLogMsg(__func__, PS_LOG_WARN, 1856 2053 "WARNING: psVectorStats(): p_psVectorSampleMean() returned an error.\n"); … … 1866 2063 // ************************************************************************ 1867 2064 if (stats->options & PS_STAT_SAMPLE_STDEV) { 1868 if (0 != p_psVectorSampleMean(inF32, mask, maskVal, stats)) {2065 if (0 != p_psVectorSampleMean(inF32, errorsF32, mask, maskVal, stats)) { 1869 2066 psLogMsg(__func__, PS_LOG_WARN, 1870 2067 "WARNING: psVectorStats(): p_psVectorSampleMean() returned an error.\n"); 1871 2068 } 1872 p_psVectorSampleStdev(inF32, mask, maskVal, stats);2069 p_psVectorSampleStdev(inF32, errorsF32, mask, maskVal, stats); 1873 2070 } 1874 2071 // ************************************************************************ … … 1887 2084 (stats->options & PS_STAT_ROBUST_STDEV) || 1888 2085 (stats->options & PS_STAT_ROBUST_QUARTILE)) { 1889 if (0 != p_psVectorRobustStats(inF32, mask, maskVal, stats)) {2086 if (0 != p_psVectorRobustStats(inF32, errorsF32, mask, maskVal, stats)) { 1890 2087 psError(PS_ERR_UNKNOWN, false, 1891 2088 PS_ERRORTEXT_psStats_STATS_FAILED); … … 1894 2091 } 1895 2092 2093 // XXX: Different conditions for return -1 and -2? 1896 2094 if ((stats->options & PS_STAT_CLIPPED_MEAN) || (stats->options & PS_STAT_CLIPPED_STDEV)) { 1897 if (-1 == p_psVectorClippedStats(inF32, mask, maskVal, stats)) {2095 if (-1 > p_psVectorClippedStats(inF32, errorsF32, mask, maskVal, stats)) { 1898 2096 psError(PS_ERR_UNKNOWN, false, 1899 "Failed to calculate clipped statistics for input psVector. ");2097 "Failed to calculate clipped statistics for input psVector.\n"); 1900 2098 stats->clippedMean = NAN; 1901 2099 stats->clippedStdev = NAN; 1902 } else if (-2 == p_psVectorClippedStats(inF32, mask, maskVal, stats)) {2100 } else if (-2 == p_psVectorClippedStats(inF32, errorsF32, mask, maskVal, stats)) { 1903 2101 psLogMsg(__func__, PS_LOG_WARN, "Failed to calculate clipped statistics for input psVector."); 1904 2102 stats->clippedMean = NAN; … … 1925 2123 } 1926 2124 1927 if (mustFree Tmp== 1) {2125 if (mustFreeVectorIn == 1) { 1928 2126 psFree(inF32); 1929 2127 } 2128 if (mustFreeVectorErrors == 1) { 2129 psFree(errorsF32); 2130 } 1930 2131 return (stats); 1931 2132 }
Note:
See TracChangeset
for help on using the changeset viewer.
