Changeset 889 for trunk/psLib/src/math/psStats.c
- Timestamp:
- Jun 6, 2004, 2:32:53 PM (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
r831 r889 85 85 float binSize = 0.0; 86 86 87 if (n == 0) { 88 psAbort(__func__, "psHistogram requested with 0 bins"); 89 } 90 87 91 newHist = (psHistogram *) psAlloc(sizeof(psHistogram)); 88 92 newHist->bounds = psVectorAlloc(n+1, PS_TYPE_F32); 93 newHist->bounds->n = newHist->bounds->nalloc; 94 89 95 binSize = (upper - lower) / (float) n; 90 96 for (i=0;i<n+1;i++) { … … 92 98 } 93 99 newHist->nums = psVectorAlloc(n, PS_TYPE_S32); 100 newHist->nums->n = newHist->nums->nalloc; 101 for (i=0;i<newHist->nums->n;i++) { 102 newHist->nums->data.S32[i] = 0; 103 } 94 104 newHist->minNum = 0; 95 105 newHist->maxNum = 0; … … 99 109 } 100 110 101 111 // When this is called, the number of data elements in bounds 112 // is n. Therefore, the number of bins is n-1. 102 113 psHistogram *psHistogramAllocGeneric(const psVector *restrict bounds) 103 114 { … … 107 118 newHist = (psHistogram *) psAlloc(sizeof(psHistogram)); 108 119 newHist->bounds = psVectorAlloc(bounds->n, PS_TYPE_F32); 120 newHist->bounds->n = newHist->bounds->nalloc; 109 121 for (i=0;i<bounds->n;i++) { 110 122 newHist->bounds->data.F32[i] = bounds->data.F32[i]; 111 123 } 112 124 newHist->nums = psVectorAlloc((bounds->n)-1, PS_TYPE_S32); 125 newHist->nums->n = newHist->nums->nalloc; 126 for (i=0;i<newHist->nums->n;i++) { 127 newHist->nums->data.S32[i] = 0; 128 } 113 129 114 130 newHist->minNum = 0; … … 119 135 } 120 136 121 void psHistogramFree(psHistogram *restrict myHist) 122 { 137 void psHistogramFree(psHistogram *myHist) 138 { 139 psVectorFree(myHist->bounds); 140 psVectorFree(myHist->nums); 123 141 psFree(myHist); 124 142 } … … 150 168 151 169 numBins = out->nums->n; 152 for (i=0;i<in->n;i++) { 153 // Check if this pixel is masked, and if so, skip it. 154 if (!(mask->data.S32[i] & maskVal)) { 155 // Check if this pixel is below the minimum value, and if so 156 // count it, then skip it. 170 171 if (mask != NULL) { 172 for (i=0;i<in->n;i++) { 173 // Check if this pixel is masked, and if so, skip it. 174 if (!(mask->data.U8[i] & maskVal)) { 175 // Check if this pixel is below the minimum value, and if so 176 // count it, then skip it. 177 if (in->data.F32[i] < out->bounds->data.F32[0]) { 178 out->minNum++; 179 180 // Check if this pixel is above the maximum value, and if so 181 // count it, then skip it. 182 } else if (in->data.F32[i] > out->bounds->data.F32[numBins]) { 183 out->maxNum++; 184 } else { 185 // If this is a uniform histogram, determining the correct 186 // number is trivial. 187 if (out->uniform == true) { 188 binSize = out->bounds->data.F32[1] - out->bounds->data.F32[0]; 189 190 binNum = (int) ((in->data.F32[i] - out->bounds->data.F32[0]) / 191 binSize); 192 (out->nums->data.S32[binNum])++; 193 // If this is a non-uniform histogram, determining the correct 194 // bin number requires a bit more work. 195 } else { 196 // GUS: This is slow. Put a smarter algorithm here to 197 // find the correct bin number (bin search, probably) 198 for (j=0;j<(out->bounds->n)-1;j++) { 199 if ((out->bounds->data.S32[j] <= in->data.F32[i]) && 200 (in->data.F32[i] <= out->bounds->data.S32[j+1])) { 201 (out->nums->data.S32[j])++; 202 } 203 } 204 } 205 } 206 } 207 } 208 } else { 209 for (i=0;i<in->n;i++) { 157 210 if (in->data.F32[i] < out->bounds->data.F32[0]) { 211 // Check if this pixel is below the minimum value, and if so 212 // count it, then skip it. 158 213 out->minNum++; 159 214 } else if (in->data.F32[i] > out->bounds->data.F32[numBins]) { 160 215 // Check if this pixel is above the maximum value, and if so 161 216 // count it, then skip it. 162 } else if (in->data.F32[i] > out->bounds->data.F32[numBins]) {163 217 out->maxNum++; 164 218 } else { … … 171 225 binSize); 172 226 (out->nums->data.S32[binNum])++; 227 173 228 // If this is a non-uniform histogram, determining the correct 174 229 // bin number requires a bit more work. … … 185 240 } 186 241 } 242 187 243 } 188 244 return(out); … … 471 527 unsortedVector = psVectorAlloc(nValues, PS_TYPE_F32); 472 528 unsortedVector->n = unsortedVector->nalloc; 529 473 530 sortedVector = psVectorAlloc(nValues, PS_TYPE_F32); 474 531 sortedVector->n = sortedVector->nalloc; … … 494 551 if ((rangeMin <= myVector->data.F32[i]) && 495 552 (myVector->data.F32[i] <= rangeMax)) { 496 unsortedVector->data.F32[count++] = m askVector->data.F32[i];553 unsortedVector->data.F32[count++] = myVector->data.F32[i]; 497 554 } 498 555 } … … 504 561 for (i=0;i<myVector->n;i++) { 505 562 if (!(maskVal & maskVector->data.U8[i])) { 506 unsortedVector->data.F32[count++] = m askVector->data.F32[i];507 } 508 } 509 } else { 510 for (i=0;i<myVector->n;i++) { 511 unsortedVector->data.F32[i] = m askVector->data.F32[i];563 unsortedVector->data.F32[count++] = myVector->data.F32[i]; 564 } 565 } 566 } else { 567 for (i=0;i<myVector->n;i++) { 568 unsortedVector->data.F32[i] = myVector->data.F32[i]; 512 569 } 513 570 } … … 596 653 float rangeMin = 0.0; 597 654 float rangeMax = 0.0; 598 psStats *stats2 = NULL;599 655 600 656 // Determine if the number of data points exceed a threshold which will 601 657 // cause to generate robust stats, as opposed to exact stats. 602 if (myVector->n > stats->sampleLimit) { 603 // Calculate the robust quartiles. 604 stats2 = psStatsAlloc(PS_STAT_ROBUST_QUARTILE); 605 p_psVectorRobustStats(myVector, maskVector, maskVal, stats2); 606 607 // Store the robust quartiles into the sample quartile members. 608 stats->sampleUQ = stats2->robustUQ; 609 stats->sampleLQ = stats2->robustLQ; 610 611 // Free temporary data buffers. 612 psStatsFree(stats2); 613 614 // Set the PS_STAT_ROBUST_FOR_SAMPLE bit in the stats structure. 615 stats->options = stats->options | PS_STAT_ROBUST_FOR_SAMPLE; 616 617 return; 618 } 658 /* GUS: When IfA provides the algorithm, insert is here. 659 if (myVector->n > stats->sampleLimit) { 660 psStats *stats2 = NULL; 661 // Calculate the robust quartiles. 662 stats2 = psStatsAlloc(PS_STAT_ROBUST_QUARTILE); 663 p_psVectorRobustStats(myVector, maskVector, maskVal, stats2); 664 665 // Store the robust quartiles into the sample quartile members. 666 stats->sampleUQ = stats2->robustUQ; 667 stats->sampleLQ = stats2->robustLQ; 668 669 // Free temporary data buffers. 670 psStatsFree(stats2); 671 672 // Set the PS_STAT_ROBUST_FOR_SAMPLE bit in the stats structure. 673 stats->options = stats->options | PS_STAT_ROBUST_FOR_SAMPLE; 674 675 return; 676 } 677 */ 619 678 620 679 // Determine how many data points fit inside this min/max range … … 640 699 (rangeMin <= myVector->data.F32[i]) && 641 700 (myVector->data.F32[i] <= rangeMax)) { 642 unsortedVector->data.F32[count++] = m askVector->data.F32[i];701 unsortedVector->data.F32[count++] = myVector->data.F32[i]; 643 702 } 644 703 } … … 647 706 if ((rangeMin <= myVector->data.F32[i]) && 648 707 (myVector->data.F32[i] <= rangeMax)) { 649 unsortedVector->data.F32[count++] = m askVector->data.F32[i];708 unsortedVector->data.F32[count++] = myVector->data.F32[i]; 650 709 } 651 710 } … … 657 716 for (i=0;i<myVector->n;i++) { 658 717 if (!(maskVal & maskVector->data.U8[i])) { 659 unsortedVector->data.F32[count++] = m askVector->data.F32[i];660 } 661 } 662 } else { 663 for (i=0;i<myVector->n;i++) { 664 unsortedVector->data.F32[i] = m askVector->data.F32[i];718 unsortedVector->data.F32[count++] = myVector->data.F32[i]; 719 } 720 } 721 } else { 722 for (i=0;i<myVector->n;i++) { 723 unsortedVector->data.F32[i] = myVector->data.F32[i]; 665 724 } 666 725 } … … 679 738 psVectorFree(unsortedVector); 680 739 psVectorFree(sortedVector); 740 // GUS: This is the 681 741 } 682 742 … … 691 751 PS_STAT_ROBUST_QUARTILE 692 752 I have included all that computation in a single function, as opposed to 693 breaking it across several functions for one primary reason: the all753 breaking it across several functions for one primary reason: they all 694 754 require the same basic initial processing steps (calculate the histogram, 695 755 etc.) however there is no currently defined means, in the SDRS, to … … 719 779 // is really required. 720 780 721 if (0.0 == stats->sampleUQ) { 722 723 // GUS: fix this 724 // stats->options = stats->options | PS_STAT_SAMPLE_UQ; 781 if (isnan(stats->sampleUQ) || 782 isnan(stats->sampleLQ)) { 783 stats->options = stats->options | PS_STAT_SAMPLE_QUARTILE; 725 784 p_psVectorSampleQuartiles(myVector, 726 785 maskVector, … … 729 788 } 730 789 731 if (isnan(stats->sampleLQ)) {732 // GUS: fix this733 // stats->options = stats->options | PS_STAT_SAMPLE_LQ;734 p_psVectorSampleQuartiles(myVector,735 maskVector,736 maskVal,737 stats);738 }739 740 790 // Compute the initial bin size of the robust histogram. 741 791 sigmaE = (stats->sampleUQ - stats->sampleLQ) / 1.34f; … … 753 803 robustHistogram = psHistogramAlloc(stats->min, 754 804 stats->max, 755 binSize); 756 // Populate the histogram arrat. 805 1 + (int) ((stats->max - stats->min) / binSize)); 806 807 808 // Populate the histogram array. 757 809 // GUS: fix this 758 810 // robustHistogram = psHistogramVector(robustHistogram, myVector); … … 811 863 stats->robustLQ = 0.0; 812 864 } 865 stats->robustNfit = 0.0; 866 stats->robustN50 = 0.0; 867 psHistogramFree(robustHistogram); 813 868 } 814 869 … … 836 891 837 892 if (0 != isnan(stats->sampleMean)) { 838 p sAbort(__func__, "stats->sampleMean == NAN");893 p_psVectorSampleMean(myVector, maskVector, maskVal, stats); 839 894 } 840 895 mean = stats->sampleMean; … … 920 975 } 921 976 922 tmpMask = psVectorAlloc(myVector->nalloc, maskVector->type.type); 923 924 tmpMask->n = maskVector->n; 925 for (i=0;i<tmpMask->n;i++) { 926 tmpMask->data.U8[i] = maskVector->data.U8[i]; 977 978 tmpMask = psVectorAlloc(myVector->n, PS_TYPE_U8); 979 tmpMask->n = myVector->n; 980 981 if (maskVector != NULL) { 982 for (i=0;i<tmpMask->n;i++) { 983 tmpMask->data.U8[i] = maskVector->data.U8[i]; 984 } 927 985 } 928 986 929 987 // 1. Compute the sample median. 988 // GUS: This seems odd. Verify with IfA that we want to calculate the 989 // median here, not the mean. 930 990 p_psVectorSampleMedian(myVector, maskVector, maskVal, stats); 931 991 … … 942 1002 943 1003 for (i=0;i<stats->clipIter;i++) { 1004 // printf("p_psVectorClippedStats(): Iteration %d (%f %f)\n", i, 1005 // clippedMean, clippedStdev); 944 1006 for (j=0;j<myVector->n;j++) { 945 1007 // a) Exclude all values x_i for which |x_i - x| > K * stdev 946 if ( fabs(myVector->data.F32[j] - clippedMean) >1008 if (fabs(myVector->data.F32[j] - clippedMean) > 947 1009 (stats->clipSigma * clippedStdev)) { 948 1010 tmpMask->data.U8[i] = 0xff; … … 994 1056 if (in->type.type != PS_TYPE_F32) { 995 1057 psAbort(__func__, 996 "Only data type PS_TYPE_F32 is currently supported."); 997 } 1058 "Only data type PS_TYPE_F32 is currently supported (0x%x).", 1059 in->type.type); 1060 } 1061 998 1062 if (mask != NULL) { 999 1063 if (in->n != mask->n) { … … 1018 1082 1019 1083 // ************************************************************************ 1084 // GUS: The Stdev calculation requires the mean. Should we assume the 1085 // mean has already been calculated? Or should we always calculate it? 1020 1086 if (stats->options & PS_STAT_SAMPLE_STDEV) { 1087 p_psVectorSampleMean(in, mask, maskVal, stats); 1021 1088 p_psVectorSampleStdev(in, mask, maskVal, stats); 1022 1089 }
Note:
See TracChangeset
for help on using the changeset viewer.
