41 if (max_bucket_value_plus_1 <= min_bucket_value) {
43 max_bucket_value_plus_1 = 1;
45 rangemin_ = min_bucket_value;
46 rangemax_ = max_bucket_value_plus_1;
47 buckets_ =
new inT32[rangemax_ - rangemin_];
63 if (max_bucket_value_plus_1 <= min_bucket_value) {
66 if (rangemax_ - rangemin_ != max_bucket_value_plus_1 - min_bucket_value) {
68 buckets_ =
new inT32[max_bucket_value_plus_1 - min_bucket_value];
70 rangemin_ = min_bucket_value;
71 rangemax_ = max_bucket_value_plus_1;
84 memset(buckets_, 0, (rangemax_ - rangemin_) *
sizeof(buckets_[0]));
102 if (buckets_ == NULL) {
105 value =
ClipToRange(value, rangemin_, rangemax_ - 1);
106 buckets_[value - rangemin_] +=
count;
107 total_count_ +=
count;
116 if (buckets_ == NULL) {
119 inT32 max = buckets_[0];
121 for (
int index = rangemax_ - rangemin_ - 1; index > 0; --index) {
122 if (buckets_[index] > max) {
123 max = buckets_[index];
127 return maxindex + rangemin_;
136 if (buckets_ == NULL || total_count_ <= 0) {
137 return static_cast<double>(rangemin_);
140 for (
int index = rangemax_ - rangemin_ - 1; index >= 0; --index) {
141 sum +=
static_cast<inT64>(index) * buckets_[index];
143 return static_cast<double>(sum) / total_count_ + rangemin_;
152 if (buckets_ == NULL || total_count_ <= 0) {
157 for (
int index = rangemax_ - rangemin_ - 1; index >= 0; --index) {
158 sum +=
static_cast<inT64>(index) * buckets_[index];
159 sqsum +=
static_cast<double>(index) * index * buckets_[index];
161 double variance =
static_cast<double>(sum) / total_count_;
162 variance = sqsum / total_count_ - variance * variance;
164 return sqrt(variance);
175 if (buckets_ == NULL || total_count_ == 0) {
176 return static_cast<double>(rangemin_);
185 double target = frac * total_count_;
186 target =
ClipToRange(target, 1.0, static_cast<double>(total_count_));
190 for (index = 0; index < rangemax_ - rangemin_ && sum < target;
191 sum += buckets_[index++]);
194 return rangemin_ + index -
195 static_cast<double>(sum - target) / buckets_[index - 1];
197 return static_cast<double>(rangemin_);
207 if (buckets_ == NULL || total_count_ == 0) {
211 for (min = 0; (min < rangemax_ - rangemin_) && (buckets_[min] == 0); min++);
212 return rangemin_ + min;
222 if (buckets_ == NULL || total_count_ == 0) {
226 for (max = rangemax_ - rangemin_ - 1; max > 0 && buckets_[max] == 0; max--);
227 return rangemin_ + max;
240 if (buckets_ == NULL) {
241 return static_cast<double>(rangemin_);
244 int median_pile =
static_cast<int>(floor(
median));
245 if ((total_count_ > 1) && (
pile_count(median_pile) == 0)) {
249 for (min_pile = median_pile;
pile_count(min_pile) == 0; min_pile--);
251 for (max_pile = median_pile;
pile_count(max_pile) == 0; max_pile++);
252 median = (min_pile + max_pile) / 2.0;
263 if (buckets_ == NULL) {
266 x =
ClipToRange(x, rangemin_, rangemax_ - 1) - rangemin_;
267 if (buckets_[x] == 0)
270 for (index = x - 1; index >= 0 && buckets_[index] == buckets_[x]; --index);
271 if (index >= 0 && buckets_[index] < buckets_[x])
273 for (index = x + 1; index < rangemax_ - rangemin_ &&
274 buckets_[index] == buckets_[x]; ++index);
275 if (index < rangemax_ - rangemin_ && buckets_[index] < buckets_[x])
290 if (buckets_ == NULL || factor < 2) {
293 STATS result(rangemin_, rangemax_);
294 int entrycount = rangemax_ - rangemin_;
295 for (
int entry = 0; entry < entrycount; entry++) {
297 int count = buckets_[entry] * factor;
298 for (
int offset = 1; offset < factor; offset++) {
299 if (entry - offset >= 0)
300 count += buckets_[entry - offset] * (factor - offset);
301 if (entry + offset < entrycount)
302 count += buckets_[entry + offset] * (factor - offset);
304 result.
add(entry + rangemin_,
count);
306 total_count_ = result.total_count_;
307 memcpy(buckets_, result.buckets_, entrycount *
sizeof(buckets_[0]));
330 inT32 new_centre = 0;
337 if (buckets_ == NULL || max_clusters < 1)
339 centres =
new float[max_clusters + 1];
340 for (cluster_count = 1; cluster_count <= max_clusters
341 && clusters[cluster_count].buckets_ != NULL
342 && clusters[cluster_count].total_count_ > 0;
344 centres[cluster_count] =
345 static_cast<float>(clusters[cluster_count].
ile(0.5));
346 new_centre = clusters[cluster_count].
mode();
347 for (entry = new_centre - 1; centres[cluster_count] - entry < lower
348 && entry >= rangemin_
353 clusters[cluster_count].
add(entry,
count);
357 for (entry = new_centre + 1; entry - centres[cluster_count] < lower
363 clusters[cluster_count].
add(entry,
count);
370 if (cluster_count == 0) {
371 clusters[0].
set_range(rangemin_, rangemax_);
376 for (entry = 0; entry < rangemax_ - rangemin_; entry++) {
377 count = buckets_[entry] - clusters[0].buckets_[entry];
380 min_dist =
static_cast<float>(
MAX_INT32);
383 dist = entry + rangemin_ - centres[
cluster];
387 if (dist < min_dist) {
393 && (best_cluster == 0
394 || entry + rangemin_ > centres[best_cluster] * multiple
395 || entry + rangemin_ < centres[best_cluster] / multiple)) {
396 if (
count > new_mode) {
398 new_centre = entry + rangemin_;
404 if (new_mode > 0 && cluster_count < max_clusters) {
407 if (!clusters[cluster_count].
set_range(rangemin_, rangemax_)) {
411 centres[cluster_count] =
static_cast<float>(new_centre);
412 clusters[cluster_count].
add(new_centre, new_mode);
413 clusters[0].
add(new_centre, new_mode);
414 for (entry = new_centre - 1; centres[cluster_count] - entry < lower
415 && entry >= rangemin_
419 clusters[cluster_count].
add(entry,
count);
423 for (entry = new_centre + 1; entry - centres[cluster_count] < lower
428 clusters[cluster_count].
add(entry,
count);
432 centres[cluster_count] =
433 static_cast<float>(clusters[cluster_count].
ile(0.5));
435 }
while (new_cluster && cluster_count < max_clusters);
437 return cluster_count;
446 static bool GatherPeak(
int index,
const int* src_buckets,
int* used_buckets,
447 int* prev_count,
int* total_count,
double* total_value) {
448 int pile_count = src_buckets[index] - used_buckets[index];
449 if (pile_count <= *prev_count && pile_count > 0) {
451 *total_count += pile_count;
452 *total_value += index * pile_count;
454 used_buckets[index] = src_buckets[index];
455 *prev_count = pile_count;
471 if (max_modes <= 0)
return 0;
472 int src_count = rangemax_ - rangemin_;
474 STATS used(rangemin_, rangemax_);
484 for (
int src_index = 0; src_index < src_count; src_index++) {
485 int pile_count = buckets_[src_index] - used.buckets_[src_index];
488 max_index = src_index;
493 used.buckets_[max_index] = max_count;
495 double total_value = max_index * max_count;
496 int total_count = max_count;
497 int prev_pile = max_count;
498 for (
int offset = 1; max_index + offset < src_count; ++offset) {
499 if (!GatherPeak(max_index + offset, buckets_, used.buckets_,
500 &prev_pile, &total_count, &total_value))
503 prev_pile = buckets_[max_index];
504 for (
int offset = 1; max_index - offset >= 0; ++offset) {
505 if (!GatherPeak(max_index - offset, buckets_, used.buckets_,
506 &prev_pile, &total_count, &total_value))
509 if (total_count > least_count || modes->size() < max_modes) {
511 if (modes->size() == max_modes)
512 modes->truncate(max_modes - 1);
513 int target_index = 0;
515 while (target_index < modes->size() &&
516 (*modes)[target_index].data >= total_count)
519 static_cast<float>(total_value / total_count + rangemin_);
522 least_count = modes->back().data;
525 }
while (max_count > 0);
526 return modes->size();
535 if (buckets_ == NULL) {
542 for (
int index = min; index <= max; index++) {
543 if (buckets_[index] != 0) {
544 tprintf(
"%4d:%-3d ", rangemin_ + index, buckets_[index]);
545 if (++num_printed % 8 == 0)
561 if (buckets_ == NULL) {
566 tprintf(
"Total count=%d\n", total_count_);
567 tprintf(
"Min=%.2f Really=%d\n",
ile(0.0), min);
571 tprintf(
"Max=%.2f Really=%d\n",
ile(1.0), max);
572 tprintf(
"Range=%d\n", max + 1 - min);
584 #ifndef GRAPHICS_DISABLED 591 if (buckets_ == NULL) {
596 for (
int index = 0; index < rangemax_ - rangemin_; index++) {
597 window->
Rectangle( xorigin + xscale * index, yorigin,
598 xorigin + xscale * (index + 1),
599 yorigin + yscale * buckets_[index]);
611 #ifndef GRAPHICS_DISABLED 618 if (buckets_ == NULL) {
622 window->
SetCursor(xorigin, yorigin + yscale * buckets_[0]);
623 for (
int index = 0; index < rangemax_ - rangemin_; index++) {
624 window->
DrawTo(xorigin + xscale * index,
625 yorigin + yscale * buckets_[index]);
649 if (array[0] < array[1]) {
650 return index >= 1 ? 1 : 0;
653 return index >= 1 ? 0 : 1;
659 else if (index >=
count)
662 pivot = array[equal_count];
664 array[equal_count] = array[0];
666 prev_greater =
count;
668 for (next_sample = 1; next_sample < prev_greater;) {
669 sample = array[next_sample];
672 array[next_lesser++] =
sample;
675 else if (
sample > pivot) {
678 array[next_sample] = array[prev_greater];
679 array[prev_greater] =
sample;
686 for (next_sample = next_lesser; next_sample < prev_greater;)
687 array[next_sample++] = pivot;
688 if (index < next_lesser)
690 else if (index < prev_greater)
694 array + prev_greater,
695 count - prev_greater) + prev_greater;
706 int (*compar)(
const void*,
const void*)) {
717 if (compar (array, (
char *) array + size) < 0) {
718 return index >= 1 ? 1 : 0;
721 return index >= 1 ? 0 : 1;
726 else if (index >=
count)
731 prev_greater =
count;
733 for (next_sample = 1; next_sample < prev_greater;) {
735 compar ((
char *) array + size * next_sample,
736 (
char *) array + size * next_lesser);
738 swap_entries (array, size, next_lesser++, next_sample++);
741 else if (result > 0) {
750 if (index < next_lesser)
752 else if (index < prev_greater)
756 (
char *) array + size * prev_greater,
757 count - prev_greater, size,
758 compar) + prev_greater;
775 ptr1 =
reinterpret_cast<char*
>(array) + index1 * size;
776 ptr2 =
reinterpret_cast<char*
>(array) + index2 * size;
void DrawTo(int x, int y)
int IntCastRounded(double x)
void plotline(ScrollView *window, float xorigin, float yorigin, float xscale, float yscale, ScrollView::Color colour) const
void SetCursor(int x, int y)
void swap_entries(void *array, size_t size, inT32 index1, inT32 index2)
void add(inT32 value, inT32 count)
bool local_min(inT32 x) const
T ClipToRange(const T &x, const T &lower_bound, const T &upper_bound)
void print_summary() const
inT32 choose_nth_item(inT32 index, float *array, inT32 count)
void smooth(inT32 factor)
int top_n_modes(int max_modes, GenericVector< tesseract::KDPairInc< float, int > > *modes) const
void Rectangle(int x1, int y1, int x2, int y2)
inT32 cluster(float lower, float upper, float multiple, inT32 max_clusters, STATS *clusters)
inT32 pile_count(inT32 value) const
double ile(double frac) const
void plot(ScrollView *window, float xorigin, float yorigin, float xscale, float yscale, ScrollView::Color colour) const
bool set_range(inT32 min_bucket_value, inT32 max_bucket_value_plus_1)