Calculate how much a set of boxes is homogeneously distributed or contentrated within one dimension, returning the range_quintile of of the overlap counts per cell in a uniform partition of the extent of the dimension.
A uniform distribution of counts will have a small range and will require few cells in a selectivity histogram. A diverse distribution of counts will have a larger range and require more cells in a selectivity histogram (to distinguish between areas of feature density and areas of feature sparseness. This measurement should help us identify cases like X/Y/Z data where there is lots of variability in density in X/Y (diversely in a multi-kilometer range) and far less in Z (in a few-hundred meter range).
649{
650 int d, i, k, range;
651 int *counts;
652 double smin, smax;
653 double swidth;
654#if POSTGIS_DEBUG_LEVEL >= 3
655 double average, sdev, sdev_ratio;
656#endif
657 int bmin, bmax;
659
661 counts = palloc0(num_bins * sizeof(int));
662
663
664 for ( d = 0; d < ndims; d++ )
665 {
666
667 memset(counts, 0, num_bins * sizeof(int));
668
669
670 smin = extent->
min[d];
671 smax = extent->
max[d];
672 swidth = smax - smin;
673
674
675
676
677
678
680 {
681 distribution[d] = 0;
682 continue;
683 }
684
685
686 for ( i = 0; i < num_boxes; i++ )
687 {
688 double minoffset, maxoffset;
689
690
691 ndb = nd_boxes[i];
692 if ( ! ndb ) continue;
693
694
695 minoffset = ndb->
min[d] - smin;
696 maxoffset = ndb->
max[d] - smin;
697
698
699 if ( minoffset < 0 || minoffset > swidth ||
700 maxoffset < 0 || maxoffset > swidth )
701 {
702 continue;
703 }
704
705
706 bmin = floor(num_bins * minoffset / swidth);
707 bmax = floor(num_bins * maxoffset / swidth);
708
709
710 if (bmax >= num_bins)
711 bmax = num_bins-1;
712
713 POSTGIS_DEBUGF(4, " dimension %d, feature %d: bin %d to bin %d", d, i, bmin, bmax);
714
715
716 for ( k = bmin; k <= bmax; k++ )
717 {
718 counts[k] += 1;
719 }
720
721 }
722
723
724
726
727#if POSTGIS_DEBUG_LEVEL >= 3
728 average = avg(counts, num_bins);
729 sdev = stddev(counts, num_bins);
730 sdev_ratio = sdev/average;
731
732 POSTGIS_DEBUGF(3, " dimension %d: range = %d", d, range);
733 POSTGIS_DEBUGF(3, " dimension %d: average = %.6g", d, average);
734 POSTGIS_DEBUGF(3, " dimension %d: stddev = %.6g", d, sdev);
735 POSTGIS_DEBUGF(3, " dimension %d: stddev_ratio = %.6g", d, sdev_ratio);
736#endif
737
738 distribution[d] = range;
739 }
740
741 pfree(counts);
742
743 return true;
744}
static int range_full(int *vals, int nvals)
The difference between the fourth and first quintile values, the "inter-quintile range".
#define MAX_DIMENSION_WIDTH
Maximum width of a dimension that we'll bother trying to compute statistics on.