Changeset 1071 for trunk/psLib/src/math/psStats.c
- Timestamp:
- Jun 23, 2004, 10:45:16 AM (22 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/math/psStats.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/math/psStats.c
r1057 r1071 847 847 848 848 /****************************************************************************** 849 p_psVectorSampleStdev(myVector, maskVector, maskVal, stats): calculates the 850 stdev of the input vector. 851 Inputs 852 myVector 853 maskVector 854 maskVal 855 stats 856 Returns 857 NULL 858 859 NOTE: the mean is always calculated exactly. Robust means are never 860 calculated in this routine. 861 *****************************************************************************/ 862 void p_psVectorSampleStdev(const psVector *restrict myVector, 863 const psVector *restrict maskVector, 864 unsigned int maskVal, 865 psStats *stats) 866 { 867 int i = 0; // Loop index variable 868 int countInt = 0; // # of data points being used 869 float countFloat = 0.0; // # of data points being used 870 float mean = 0.0; // The mean 871 float diff = 0.0; // Used in calculating stdev 872 float sumSquares = 0.0; // temporary variable 873 float sumDiffs = 0.0; // temporary variable 874 float rangeMin = 0.0; // Exclude data below this 875 float rangeMax = 0.0; // Exclude date above this 876 877 // This procedure requires the mean. If it has not been already 878 // calculated, then call p_psVectorSampleMean() 879 if (0 != isnan(stats->sampleMean)) { 880 p_psVectorSampleMean(myVector, maskVector, maskVal, stats); 881 } 882 mean = stats->sampleMean; 883 884 if (stats->options & PS_STAT_USE_RANGE) { 885 if (maskVector != NULL) { 886 for (i=0;i<myVector->n;i++) { 887 if (!(maskVal & maskVector->data.U8[i]) && 888 (rangeMin <= myVector->data.F32[i]) && 889 (myVector->data.F32[i] <= rangeMax)) { 890 diff = myVector->data.F32[i] - mean; 891 sumSquares+= (diff * diff); 892 sumDiffs+= diff; 893 countInt++; 894 } 895 } 896 } else { 897 for (i=0;i<myVector->n;i++) { 898 if ((rangeMin <= myVector->data.F32[i]) && 899 (myVector->data.F32[i] <= rangeMax)) { 900 diff = myVector->data.F32[i] - mean; 901 sumSquares+= (diff * diff); 902 sumDiffs+= diff; 903 countInt++; 904 } 905 } 906 countInt = myVector->n; 907 } 908 } else { 909 if (maskVector != NULL) { 910 for (i=0;i<myVector->n;i++) { 911 if (!(maskVal & maskVector->data.U8[i])) { 912 diff = myVector->data.F32[i] - mean; 913 sumSquares+= (diff * diff); 914 sumDiffs+= diff; 915 countInt++; 916 } 917 } 918 } else { 919 for (i=0;i<myVector->n;i++) { 920 diff = myVector->data.F32[i] - mean; 921 sumSquares+= (diff * diff); 922 sumDiffs+= diff; 923 countInt++; 924 } 925 countInt = myVector->n; 926 } 927 } 928 countFloat = (float) countInt; 929 930 #ifdef DARWIN 931 932 stats->sampleStdev = (float) sqrt( (sumSquares-(sumDiffs * 933 sumDiffs/countFloat))/ (countFloat-1)); 934 #else 935 936 stats->sampleStdev = sqrtf( (sumSquares-(sumDiffs * 937 sumDiffs/countFloat))/ (countFloat-1)); 938 #endif 939 } 940 941 /****************************************************************************** 942 p_psVectorClippedStats(myVector, maskVector, maskVal, stats): calculates the 943 clipped stats (mean or stdev) of the input vector. 944 945 Inputs 946 myVector 947 maskVector 948 maskVal 949 stats 950 Returns 951 NULL 952 *****************************************************************************/ 953 void p_psVectorClippedStats(const psVector *restrict myVector, 954 const psVector *restrict maskVector, 955 unsigned int maskVal, 956 psStats *stats) 957 { 958 int i = 0; // Loop index variable 959 int j = 0; // Loop index variable 960 float clippedMean = 0.0; // self-explanatory 961 float clippedStdev = 0.0; // self-explanatory 962 float oldStanMean = 0.0; // Temporary variable 963 float oldStanStdev = 0.0; // Temporary variable 964 psVector *tmpMask = NULL; // Temporary vector 965 966 // Endure that stats->clipIter is within the proper range. 967 if (!((CLIPPED_NUM_ITER_LB <= stats->clipIter ) && 968 (stats->clipIter <= CLIPPED_NUM_ITER_UB))) { 969 psAbort(__func__, "Unallowed value for clipIter (%d).\n", 970 stats->clipIter); 971 } 972 973 // Endure that stats->clipSigma is within the proper range. 974 if (!((CLIPPED_SIGMA_LB <= stats->clipSigma ) && 975 (stats->clipSigma <= CLIPPED_SIGMA_UB))) { 976 psAbort(__func__, "Unallowed value for clipSigma (%f).\n", 977 stats->clipSigma); 978 } 979 980 // We allocate a temporary mask vector since during the iterative 981 // steps that follow, we will be masking off additional data points. 982 // However, we do no want to modify the original mask vector. 983 tmpMask = psVectorAlloc(myVector->n, PS_TYPE_U8); 984 tmpMask->n = myVector->n; 985 986 // If we were called with a mask vector, then initialize the temporary 987 // mask vector with those values. 988 if (maskVector != NULL) { 989 for (i=0;i<tmpMask->n;i++) { 990 tmpMask->data.U8[i] = maskVector->data.U8[i]; 991 } 992 } 993 994 // 1. Compute the sample median. 995 // NOTE: This seems odd. Verify with IfA that we want to calculate the 996 // median here, not the mean. 997 p_psVectorSampleMedian(myVector, maskVector, maskVal, stats); 998 999 // 2. Compute the sample standard deviation. 1000 p_psVectorSampleStdev(myVector, maskVector, maskVal, stats); 1001 1002 // 3. Use the sample median as the first estimator of the mean X. 1003 clippedMean = stats->sampleMean; 1004 1005 // 4. Use the sample stdev as the first estimator of the mean stdev. 1006 clippedStdev = stats->sampleStdev; 1007 1008 // Must save the old sampleMean and sampleStdev since the following code 1009 // block overwrites them. 1010 oldStanMean = stats->sampleMean; 1011 oldStanStdev = stats->sampleStdev; 1012 1013 // 5. Repeat N times: 1014 for (i=0;i<stats->clipIter;i++) { 1015 for (j=0;j<myVector->n;j++) { 1016 // a) Exclude all values x_i for which |x_i - x| > K * stdev 1017 if (fabs(myVector->data.F32[j] - clippedMean) > 1018 (stats->clipSigma * clippedStdev)) { 1019 tmpMask->data.U8[i] = 0xff; 1020 } 1021 // b) compute new mean and stdev 1022 p_psVectorSampleMedian(myVector, tmpMask, maskVal, stats); 1023 p_psVectorSampleStdev(myVector, tmpMask, maskVal, stats); 1024 1025 // c) Use the new mean for x 1026 clippedMean = stats->sampleMean; 1027 1028 // d) Use the new stdev for stdev 1029 clippedStdev = stats->sampleStdev; 1030 } 1031 } 1032 stats->sampleMean = oldStanMean; 1033 stats->sampleStdev= oldStanStdev; 1034 1035 // 7. The last calcuated value of x is the cliped mean. 1036 if (stats->options & PS_STAT_CLIPPED_MEAN) { 1037 stats->clippedMean = clippedMean; 1038 } 1039 1040 // 8. The last calcuated value of stdev is the cliped stdev. 1041 if (stats->options & PS_STAT_CLIPPED_STDEV) { 1042 stats->clippedStdev = clippedStdev; 1043 } 1044 1045 psVectorFree(tmpMask); 1046 } 1047 1048 1049 /****************************************************************************** 849 1050 p_psVectorRobustStats(myVector, maskVector, maskVal, stats): this procedure 850 1051 calculates a variety of robust stat measures: … … 884 1085 float dL = 0.0; 885 1086 int numBins = 0; 1087 psStats *tmpStats = psStatsAlloc(PS_STAT_CLIPPED_STDEV|PS_STAT_CLIPPED_MEAN); 886 1088 887 1089 // NOTE: The SDRS states that the sample quartiles must be used to … … 890 1092 // size of the data set. We should consult with IfA to ensure that this 891 1093 // is really required. 892 893 if (isnan(stats->sampleUQ) ||1094 /* 1095 if (isnan(stats->sampleUQ) || 894 1096 isnan(stats->sampleLQ)) { 895 stats->options = stats->options | PS_STAT_SAMPLE_QUARTILE;896 p_psVectorSampleQuartiles(myVector,897 maskVector,898 maskVal,899 stats);900 }901 1097 stats->options = stats->options | PS_STAT_SAMPLE_QUARTILE; 1098 p_psVectorSampleQuartiles(myVector, 1099 maskVector, 1100 maskVal, 1101 stats); 1102 } 1103 */ 902 1104 // Compute the initial bin size of the robust histogram. 903 sigmaE = (stats->sampleUQ - stats->sampleLQ) / 1.34f; 904 binSize = sigmaE / 10.0f; 1105 p_psVectorClippedStats(myVector, maskVector, maskVal, tmpStats); 1106 binSize = stats->clippedStdev / 10.0f; 1107 1108 // If stats->clippedStdev == 0.0, then all data elements have the same 1109 // value. Therefore, we can set the appropiate results and return. 1110 if (fabs(binSize) <= FLT_EPSILON) { 1111 if (stats->options & PS_STAT_ROBUST_MEAN) { 1112 stats->robustMean = stats->clippedMean; 1113 } 1114 if (stats->options & PS_STAT_ROBUST_MEDIAN) { 1115 stats->robustMedian = stats->clippedMean; 1116 } 1117 if (stats->options & PS_STAT_ROBUST_MODE) { 1118 stats->robustMode = stats->clippedMean; 1119 } 1120 if (stats->options & PS_STAT_ROBUST_STDEV) { 1121 stats->robustStdev = 0.0; 1122 } 1123 if (stats->options & PS_STAT_ROBUST_QUARTILE) { 1124 stats->robustUQ = stats->clippedMean; 1125 stats->robustLQ = stats->clippedMean; 1126 } 1127 psStatsFree(tmpStats); 1128 psHistogramFree(robustHistogram); 1129 return; 1130 } 905 1131 906 1132 // Detemine minimum and maximum values in the data vector. … … 912 1138 } 913 1139 914 // Create the histogram structure (yes, 2 is necessary, not 1). 1140 // Create the histogram structure (yes, 2 is necessary, not 1). Also, 1141 // if we get here, we know that binSize != 0.0. 915 1142 numBins = 2 + (int) ((stats->max - stats->min) / binSize); 916 1143 … … 973 1200 stats->robustNfit = 0.0; 974 1201 stats->robustN50 = 0.0; 1202 psStatsFree(tmpStats); 975 1203 psHistogramFree(robustHistogram); 976 }977 978 /******************************************************************************979 p_psVectorSampleStdev(myVector, maskVector, maskVal, stats): calculates the980 stdev of the input vector.981 Inputs982 myVector983 maskVector984 maskVal985 stats986 Returns987 NULL988 989 NOTE: the mean is always calculated exactly. Robust means are never990 calculated in this routine.991 *****************************************************************************/992 void p_psVectorSampleStdev(const psVector *restrict myVector,993 const psVector *restrict maskVector,994 unsigned int maskVal,995 psStats *stats)996 {997 int i = 0; // Loop index variable998 int countInt = 0; // # of data points being used999 float countFloat = 0.0; // # of data points being used1000 float mean = 0.0; // The mean1001 float diff = 0.0; // Used in calculating stdev1002 float sumSquares = 0.0; // temporary variable1003 float sumDiffs = 0.0; // temporary variable1004 float rangeMin = 0.0; // Exclude data below this1005 float rangeMax = 0.0; // Exclude date above this1006 1007 // This procedure requires the mean. If it has not been already1008 // calculated, then call p_psVectorSampleMean()1009 if (0 != isnan(stats->sampleMean)) {1010 p_psVectorSampleMean(myVector, maskVector, maskVal, stats);1011 }1012 mean = stats->sampleMean;1013 1014 if (stats->options & PS_STAT_USE_RANGE) {1015 if (maskVector != NULL) {1016 for (i=0;i<myVector->n;i++) {1017 if (!(maskVal & maskVector->data.U8[i]) &&1018 (rangeMin <= myVector->data.F32[i]) &&1019 (myVector->data.F32[i] <= rangeMax)) {1020 diff = myVector->data.F32[i] - mean;1021 sumSquares+= (diff * diff);1022 sumDiffs+= diff;1023 countInt++;1024 }1025 }1026 } else {1027 for (i=0;i<myVector->n;i++) {1028 if ((rangeMin <= myVector->data.F32[i]) &&1029 (myVector->data.F32[i] <= rangeMax)) {1030 diff = myVector->data.F32[i] - mean;1031 sumSquares+= (diff * diff);1032 sumDiffs+= diff;1033 countInt++;1034 }1035 }1036 countInt = myVector->n;1037 }1038 } else {1039 if (maskVector != NULL) {1040 for (i=0;i<myVector->n;i++) {1041 if (!(maskVal & maskVector->data.U8[i])) {1042 diff = myVector->data.F32[i] - mean;1043 sumSquares+= (diff * diff);1044 sumDiffs+= diff;1045 countInt++;1046 }1047 }1048 } else {1049 for (i=0;i<myVector->n;i++) {1050 diff = myVector->data.F32[i] - mean;1051 sumSquares+= (diff * diff);1052 sumDiffs+= diff;1053 countInt++;1054 }1055 countInt = myVector->n;1056 }1057 }1058 countFloat = (float) countInt;1059 1060 #ifdef DARWIN1061 1062 stats->sampleStdev = (float) sqrt( (sumSquares-(sumDiffs *1063 sumDiffs/countFloat))/ (countFloat-1));1064 #else1065 1066 stats->sampleStdev = sqrtf( (sumSquares-(sumDiffs *1067 sumDiffs/countFloat))/ (countFloat-1));1068 #endif1069 }1070 1071 /******************************************************************************1072 p_psVectorClippedStats(myVector, maskVector, maskVal, stats): calculates the1073 clipped stats (mean or stdev) of the input vector.1074 1075 Inputs1076 myVector1077 maskVector1078 maskVal1079 stats1080 Returns1081 NULL1082 *****************************************************************************/1083 void p_psVectorClippedStats(const psVector *restrict myVector,1084 const psVector *restrict maskVector,1085 unsigned int maskVal,1086 psStats *stats)1087 {1088 int i = 0; // Loop index variable1089 int j = 0; // Loop index variable1090 float clippedMean = 0.0; // self-explanatory1091 float clippedStdev = 0.0; // self-explanatory1092 float oldStanMean = 0.0; // Temporary variable1093 float oldStanStdev = 0.0; // Temporary variable1094 psVector *tmpMask = NULL; // Temporary vector1095 1096 // Endure that stats->clipIter is within the proper range.1097 if (!((CLIPPED_NUM_ITER_LB <= stats->clipIter ) &&1098 (stats->clipIter <= CLIPPED_NUM_ITER_UB))) {1099 psAbort(__func__, "Unallowed value for clipIter (%d).\n",1100 stats->clipIter);1101 }1102 1103 // Endure that stats->clipSigma is within the proper range.1104 if (!((CLIPPED_SIGMA_LB <= stats->clipSigma ) &&1105 (stats->clipSigma <= CLIPPED_SIGMA_UB))) {1106 psAbort(__func__, "Unallowed value for clipSigma (%f).\n",1107 stats->clipSigma);1108 }1109 1110 // We allocate a temporary mask vector since during the iterative1111 // steps that follow, we will be masking off additional data points.1112 // However, we do no want to modify the original mask vector.1113 tmpMask = psVectorAlloc(myVector->n, PS_TYPE_U8);1114 tmpMask->n = myVector->n;1115 1116 // If we were called with a mask vector, then initialize the temporary1117 // mask vector with those values.1118 if (maskVector != NULL) {1119 for (i=0;i<tmpMask->n;i++) {1120 tmpMask->data.U8[i] = maskVector->data.U8[i];1121 }1122 }1123 1124 // 1. Compute the sample median.1125 // NOTE: This seems odd. Verify with IfA that we want to calculate the1126 // median here, not the mean.1127 p_psVectorSampleMedian(myVector, maskVector, maskVal, stats);1128 1129 // 2. Compute the sample standard deviation.1130 p_psVectorSampleStdev(myVector, maskVector, maskVal, stats);1131 1132 // 3. Use the sample median as the first estimator of the mean X.1133 clippedMean = stats->sampleMean;1134 1135 // 4. Use the sample stdev as the first estimator of the mean stdev.1136 clippedStdev = stats->sampleStdev;1137 1138 // Must save the old sampleMean and sampleStdev since the following code1139 // block overwrites them.1140 oldStanMean = stats->sampleMean;1141 oldStanStdev = stats->sampleStdev;1142 1143 // 5. Repeat N times:1144 for (i=0;i<stats->clipIter;i++) {1145 for (j=0;j<myVector->n;j++) {1146 // a) Exclude all values x_i for which |x_i - x| > K * stdev1147 if (fabs(myVector->data.F32[j] - clippedMean) >1148 (stats->clipSigma * clippedStdev)) {1149 tmpMask->data.U8[i] = 0xff;1150 }1151 // b) compute new mean and stdev1152 p_psVectorSampleMedian(myVector, tmpMask, maskVal, stats);1153 p_psVectorSampleStdev(myVector, tmpMask, maskVal, stats);1154 1155 // c) Use the new mean for x1156 clippedMean = stats->sampleMean;1157 1158 // d) Use the new stdev for stdev1159 clippedStdev = stats->sampleStdev;1160 }1161 }1162 stats->sampleMean = oldStanMean;1163 stats->sampleStdev= oldStanStdev;1164 1165 // 7. The last calcuated value of x is the cliped mean.1166 if (stats->options & PS_STAT_CLIPPED_MEAN) {1167 stats->clippedMean = clippedMean;1168 }1169 1170 // 8. The last calcuated value of stdev is the cliped stdev.1171 if (stats->options & PS_STAT_CLIPPED_STDEV) {1172 stats->clippedStdev = clippedStdev;1173 }1174 1175 psVectorFree(tmpMask);1176 1204 } 1177 1205
Note:
See TracChangeset
for help on using the changeset viewer.
