Type:
template <typename TItem, typename TCounter = size_t>
class fcf::NTest::HistogramBasic
Package: fcfTest
File:
test.hpp
( link_to_the_text_position_in_the_file )
Available from version: 1.2.5
A template-based histogram class for statistical frequency distribution analysis, supporting ASCII visualization and median estimation.
The fcf::NTest::HistogramBasic class is a powerful tool for analyzing the distribution of data points collected during benchmarking or testing. It allows users to group values into bins, calculate statistical measures such as the median, and generate visual representations of the data distribution through ASCII tables and bar charts.
It is highly flexible, allowing for dynamic resizing of bins and redistribution of data. The class is designed to handle various arithmetic types for both the data items and the counters, making it suitable for a wide range of performance analysis scenarios.
Template arguments
TItem
- Type of the value stored in the histogram
TCounter
- Type of the counter used for counting in the histogram
Methods
[CONSTRUCTOR]
HistogramBasic(
size_t a_capacity,
TItem a_min,
TItem a_max)
- Constructs a new histogram with specified capacity and range.
void
append(
TItem a_item,
size_t a_count
= 1)
const
- Appends a new item (or multiple items) to the histogram, automatically adjusting the range if necessary.
- Returns the total number of items appended to the histogram.
- Checks if a given value falls outside the current histogram range.
void
size(
size_t a_newSize)
- Returns the number of bins (size of the internal vector) or resizes the histogram.
- Calculates the estimated median value of the distribution.
- Returns the minimum value recorded in the histogram.
- Returns the maximum value recorded in the histogram.
void
rangeByValue(
TItem a_value,
TItem a_min,
size_t a_size)
const
void
rangeByValue(
TItem a_value,
TItem a_min,
TItem a_max)
const
[STATIC] std::pair<
TItem,
TItem>
rangeByValue(
TItem a_value,
TItem a_min,
TItem a_max,
size_t a_size)
- Calculates the lower and upper boundaries of the bin containing the specified value.
void
rangeByIndex(
size_t a_index,
TItem a_min,
size_t a_size)
const
void
rangeByIndex(
size_t a_index,
TItem a_min,
TItem a_max)
const
[STATIC] std::pair<
TItem,
TItem>
rangeByIndex(
size_t a_index,
TItem a_min,
TItem a_max,
size_t a_size)
- Calculates the lower and upper boundaries of a specific bin index.
[STATIC] std::vector<
TCounter>
countVector(
TItem a_min,
TItem a_max,
size_t a_size)
- Creates a new vector of counts by redistributing values into a specified range or size.
std::string
toTable(
size_t a_size)
const
std::string
toTable(
TItem a_min,
TItem a_max,
size_t a_size)
const
[STATIC] std::string
toTable(
const std::vector<
TCounter>& a_vector,
TItem a_min,
TItem a_max)
- Generates a formatted ASCII table representing the histogram distribution.
std::string
toBarChart(
size_t a_width,
size_t a_height
= 10)
const
std::string
toBarChart(
TItem a_min,
TItem a_max,
size_t a_width,
size_t a_height)
const
[STATIC] std::string
toBarChart(
const std::vector<
TCounter>& a_vector,
TItem a_min,
TItem a_max,
size_t a_width,
size_t a_height)
- Generates an ASCII bar chart representing the histogram distribution.
Example: Statistical Distribution Analysis
Demonstrates how to collect data points, resize the histogram, and generate an ASCII bar chart for visual analysis.
#define FCF_TEST_IMPLEMENTATION
#include <fcfTest/test.hpp>
#include <vector>
#include <algorithm>
#include <random>
FCF_TEST_DEFINE("Statistics", "Analysis", "HistogramDemo"){
// 1. Initialize a histogram with 5 initial bins
fcf::NTest::HistogramBasic<double, size_t> histogram = fcf::NTest::HistogramBasic<double, size_t>(20);
// 2. Prepare random data generator
std::mt19937 gen(42);
std::uniform_real_distribution<double> dist(0.0, 100.0);
// 3. Append 1000 random data points to the histogram
for(int i = 0; i < 1000; ++i) {
histogram.append(dist(gen));
}
// 4. Calculate and log the median value
fcf::NTest::log() << "Median value: " << histogram.median() << std::endl;
// 5. Generate and print an ASCII bar chart
fcf::NTest::log() << "\n--- ASCII Bar Chart ---\n" << histogram.toBarChart(40, 10) << std::endl;
// 6. Generate and print an table
fcf::NTest::log() << "\n--- Table ---\n" << histogram.toTable() << std::endl;
}
int main(int a_argc, char* a_argv[]) {
bool error = false;
fcf::NTest::cmdRun(a_argc, a_argv, fcf::NTest::CRM_RUN, &error);
return error ? 1 : 0;
}
Output:
Performing the test: "Statistics" -> "Analysis" -> "HistogramDemo" ...
> Median value: 51.5836
>
> --- ASCII Bar Chart ---
> |
> ||
> | || || |
> | || || || || || |
> ||| || |||||| || || ||
> || ||| ||| ||||||| || || |||
> |||| ||||||||||||||||| ||| || ||||
> ||||| |||||||||||||||||||||| || ||||
> |||||| ||||||||||||||||||||||||||||||||
> |||||| |||||||||||||||||||||||||||||||||
> ════════════════════════════════════════
> OX (value): [0.05 : 99.77]; Step: 2.49
> OY (count): [18 : 33]; Step: 1.50
>
>
> --- Table ---
> ╔════╦═════════════════════════╦═══════╗
> ║ # ║ values ║ count ║
> ╠════╬═════════════════════════╬═══════╣
> ║ 1 ║ [0.0520377 : 4.08814] ║ 46 ║
> ║ 2 ║ [ 5.08814 : 9.12424] ║ 50 ║
> ║ 3 ║ [ 10.1242 : 14.1603] ║ 42 ║
> ║ 4 ║ [ 15.1603 : 19.1964] ║ 37 ║
> ║ 5 ║ [ 20.1964 : 24.2325] ║ 54 ║
> ║ 6 ║ [ 25.2325 : 29.2686] ║ 50 ║
> ║ 7 ║ [ 30.2686 : 34.3047] ║ 49 ║
> ║ 8 ║ [ 35.3047 : 39.3408] ║ 57 ║
> ║ 9 ║ [ 40.3408 : 44.3769] ║ 48 ║
> ║ 10 ║ [ 45.3769 : 49.413] ║ 58 ║
> ║ 11 ║ [ 50.413 : 54.4491] ║ 54 ║
> ║ 12 ║ [ 55.4491 : 59.4852] ║ 64 ║
> ║ 13 ║ [ 60.4852 : 64.5213] ║ 47 ║
> ║ 14 ║ [ 65.5213 : 69.5574] ║ 46 ║
> ║ 15 ║ [ 70.5574 : 74.5935] ║ 58 ║
> ║ 16 ║ [ 75.5935 : 79.6296] ║ 40 ║
> ║ 17 ║ [ 80.6296 : 84.6657] ║ 56 ║
> ║ 18 ║ [ 85.6657 : 89.7018] ║ 41 ║
> ║ 19 ║ [ 90.7018 : 94.7379] ║ 48 ║
> ║ 20 ║ [ 95.7379 : 99.774] ║ 55 ║
> ╚════╩═════════════════════════╩═══════╝
>
[SUCCESS] Test completed successfully (0.000`458`127 sec)
[SUCCESS] All tests were completed.
Tests: 1 passed, 0 failed, 0 skipped, 1 total
Duration: 0.000`458`127 sec