PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ rt_band_get_histogram()

rt_histogram rt_band_get_histogram ( rt_bandstats  stats,
uint32_t  bin_count,
double *  bin_width,
uint32_t  bin_width_count,
int  right,
double  min,
double  max,
uint32_t *  rtn_count 
)

Count the distribution of data.

Parameters
stats: a populated stats struct for processing
bin_count: the number of bins to group the data by
bin_width: the width of each bin as an array
bin_width_count: number of values in bin_width
right: evaluate bins by (a,b] rather than default [a,b)
min: user-defined minimum value of the histogram a value less than the minimum value is not counted in any bins if min = max, min and max are not used
max: user-defined maximum value of the histogram a value greater than the max value is not counted in any bins if min = max, min and max are not used
rtn_count: set to the number of bins being returned
Returns
the histogram of the data or NULL

Definition at line 413 of file rt_statistics.c.

418 {
419 rt_histogram bins = NULL;
420 int init_width = 0;
421 uint32_t i;
422 uint32_t j;
423 double tmp;
424 double value;
425 int sum = 0;
426 double qmin;
427 double qmax;
428
429#if POSTGIS_DEBUG_LEVEL > 0
430 clock_t start, stop;
431 double elapsed = 0;
432#endif
433
434 RASTER_DEBUG(3, "starting");
435#if POSTGIS_DEBUG_LEVEL > 0
436 start = clock();
437#endif
438
439 assert(NULL != stats);
440 assert(NULL != rtn_count);
441
442 if (stats->count < 1 || NULL == stats->values) {
443 rterror("rt_util_get_histogram: rt_bandstats object has no value");
444 return NULL;
445 }
446
447 /* bin width must be positive numbers and not zero */
448 if (NULL != bin_width && bin_width_count > 0) {
449 for (i = 0; i < bin_width_count; i++) {
450 if (bin_width[i] < 0 || FLT_EQ(bin_width[i], 0.0)) {
451 rterror("rt_util_get_histogram: bin_width element is less than or equal to zero");
452 return NULL;
453 }
454 }
455 }
456
457 /* ignore min and max parameters */
458 if (FLT_EQ(max, min)) {
459 qmin = stats->min;
460 qmax = stats->max;
461 }
462 else {
463 qmin = min;
464 qmax = max;
465 if (qmin > qmax) {
466 qmin = max;
467 qmax = min;
468 }
469 }
470
471 /* # of bins not provided */
472 if (bin_count <= 0) {
473 /*
474 determine # of bins
475 http://en.wikipedia.org/wiki/Histogram
476
477 all computed bins are assumed to have equal width
478 */
479 /* Square-root choice for stats->count < 30 */
480 if (stats->count < 30)
481 bin_count = ceil(sqrt(stats->count));
482 /* Sturges' formula for stats->count >= 30 */
483 else
484 bin_count = ceil(log2((double) stats->count) + 1.);
485
486 /* bin_width_count provided and bin_width has value */
487 if (bin_width_count > 0 && NULL != bin_width) {
488 /* user has defined something specific */
489 if (bin_width_count > bin_count)
490 bin_count = bin_width_count;
491 else if (bin_width_count > 1) {
492 tmp = 0;
493 for (i = 0; i < bin_width_count; i++) tmp += bin_width[i];
494 bin_count = ceil((qmax - qmin) / tmp) * bin_width_count;
495 }
496 else
497 bin_count = ceil((qmax - qmin) / bin_width[0]);
498 }
499 /* set bin width count to zero so that one can be calculated */
500 else {
501 bin_width_count = 0;
502 }
503 }
504
505 /* min and max the same */
506 if (FLT_EQ(qmax, qmin)) bin_count = 1;
507
508 RASTER_DEBUGF(3, "bin_count = %d", bin_count);
509
510 /* bin count = 1, all values are in one bin */
511 if (bin_count < 2) {
512 bins = rtalloc(sizeof(struct rt_histogram_t));
513 if (NULL == bins) {
514 rterror("rt_util_get_histogram: Could not allocate memory for histogram");
515 return NULL;
516 }
517
518 bins->count = stats->count;
519 bins->percent = -1;
520 bins->min = qmin;
521 bins->max = qmax;
522 bins->inc_min = bins->inc_max = 1;
523
524 *rtn_count = bin_count;
525 return bins;
526 }
527
528 /* establish bin width */
529 if (bin_width_count == 0) {
530 bin_width_count = 1;
531
532 /* bin_width unallocated */
533 if (NULL == bin_width) {
534 bin_width = rtalloc(sizeof(double));
535 if (NULL == bin_width) {
536 rterror("rt_util_get_histogram: Could not allocate memory for bin widths");
537 return NULL;
538 }
539 init_width = 1;
540 }
541
542 bin_width[0] = (qmax - qmin) / bin_count;
543 }
544
545 /* initialize bins */
546 bins = rtalloc(bin_count * sizeof(struct rt_histogram_t));
547 if (NULL == bins) {
548 rterror("rt_util_get_histogram: Could not allocate memory for histogram");
549 if (init_width) rtdealloc(bin_width);
550 return NULL;
551 }
552 if (!right)
553 tmp = qmin;
554 else
555 tmp = qmax;
556 for (i = 0; i < bin_count;) {
557 for (j = 0; j < bin_width_count; j++) {
558 bins[i].count = 0;
559 bins->percent = -1;
560
561 if (!right) {
562 bins[i].min = tmp;
563 tmp += bin_width[j];
564 bins[i].max = tmp;
565
566 bins[i].inc_min = 1;
567 bins[i].inc_max = 0;
568 }
569 else {
570 bins[i].max = tmp;
571 tmp -= bin_width[j];
572 bins[i].min = tmp;
573
574 bins[i].inc_min = 0;
575 bins[i].inc_max = 1;
576 }
577
578 i++;
579 }
580 }
581 if (!right) {
582 bins[bin_count - 1].inc_max = 1;
583
584 /* align last bin to the max value */
585 if (bins[bin_count - 1].max < qmax)
586 bins[bin_count - 1].max = qmax;
587 }
588 else {
589 bins[bin_count - 1].inc_min = 1;
590
591 /* align first bin to the min value */
592 if (bins[bin_count - 1].min > qmin)
593 bins[bin_count - 1].min = qmin;
594 }
595
596 /* process the values */
597 for (i = 0; i < stats->count; i++) {
598 value = stats->values[i];
599
600 /* default, [a, b) */
601 if (!right) {
602 for (j = 0; j < bin_count; j++) {
603 if (
604 (!bins[j].inc_max && value < bins[j].max) || (
605 bins[j].inc_max && (
606 (value < bins[j].max) ||
607 FLT_EQ(value, bins[j].max)
608 )
609 )
610 ) {
611 bins[j].count++;
612 sum++;
613 break;
614 }
615 }
616 }
617 /* (a, b] */
618 else {
619 for (j = 0; j < bin_count; j++) {
620 if (
621 (!bins[j].inc_min && value > bins[j].min) || (
622 bins[j].inc_min && (
623 (value > bins[j].min) ||
624 FLT_EQ(value, bins[j].min)
625 )
626 )
627 ) {
628 bins[j].count++;
629 sum++;
630 break;
631 }
632 }
633 }
634 }
635
636 for (i = 0; i < bin_count; i++) {
637 bins[i].percent = ((double) bins[i].count) / sum;
638 }
639
640#if POSTGIS_DEBUG_LEVEL > 0
641 stop = clock();
642 elapsed = ((double) (stop - start)) / CLOCKS_PER_SEC;
643 RASTER_DEBUGF(3, "elapsed time = %0.4f", elapsed);
644
645 for (j = 0; j < bin_count; j++) {
646 RASTER_DEBUGF(5, "(min, max, inc_min, inc_max, count, sum, percent) = (%f, %f, %d, %d, %d, %d, %f)",
647 bins[j].min, bins[j].max, bins[j].inc_min, bins[j].inc_max, bins[j].count, sum, bins[j].percent);
648 }
649#endif
650
651 if (init_width) rtdealloc(bin_width);
652 *rtn_count = bin_count;
653 RASTER_DEBUG(3, "done");
654 return bins;
655}
void rterror(const char *fmt,...) __attribute__((format(printf
Wrappers used for reporting errors and info.
void * rtalloc(size_t size)
Wrappers used for managing memory.
Definition rt_context.c:191
#define RASTER_DEBUG(level, msg)
Definition librtcore.h:304
#define RASTER_DEBUGF(level, msg,...)
Definition librtcore.h:308
#define FLT_EQ(x, y)
Definition librtcore.h:2436
void rtdealloc(void *mem)
Definition rt_context.c:206
int value
Definition genraster.py:62
uint32_t count
Definition librtcore.h:2562
double * values
Definition librtcore.h:2570
uint32_t count
Definition librtcore.h:2576

References rt_bandstats_t::count, rt_histogram_t::count, FLT_EQ, rt_histogram_t::inc_max, rt_histogram_t::inc_min, rt_bandstats_t::max, rt_histogram_t::max, rt_bandstats_t::min, rt_histogram_t::min, rt_histogram_t::percent, RASTER_DEBUG, RASTER_DEBUGF, rtalloc(), rtdealloc(), rterror(), and rt_bandstats_t::values.

Referenced by RASTER_histogram(), and test_band_stats().

Here is the call graph for this function:
Here is the caller graph for this function: