#include #include #include #include #include // // If the default clang follows the the one true brace style is that not // obviously the better brace style??? // class DistributionPair { public: DistributionPair(std::uint32_t minValue, std::uint32_t maxValue) : minValue(minValue), maxValue(maxValue), count(0) {} std::uint32_t minValue; std::uint32_t maxValue; std::uint32_t count; }; std::vector generateUniformDistribution(std::uint32_t howMany, std::uint32_t min, std::uint32_t max, std::uint8_t numberBins); std::vector generateNormalDistribution(std::uint32_t howMany, float mean, float stdev, std::uint8_t numberBins); std::vector generatePoissonDistribution(std::uint32_t howMany, std::uint8_t howOften, std::uint8_t numberBins); void plotDistribution(std::string title, const std::vector& distribution, const std::uint8_t maxPlotLineSize); std::vector createBins(int min, int max, int binCount); std::random_device randomDevice; std::default_random_engine randomEngine(randomDevice()); int main() { auto uniform = generateUniformDistribution(100000, 0, 79, 40); plotDistribution("--- Uniform ---", uniform, 80); auto normal = generateNormalDistribution(100000, 50, 5, 40); plotDistribution("--- Normal ---", normal, 80); auto poisson = generatePoissonDistribution(100000, 6, 40); plotDistribution("--- Poisson ---", poisson, 80); return 0; } std::vector generateUniformDistribution(std::uint32_t howMany, std::uint32_t min, std::uint32_t max, std::uint8_t numberBins) { std::uniform_int_distribution distribution(min, max); auto bins = createBins(min, max, numberBins); for (int i = 0; i < static_cast(howMany); i++) { int number = distribution(randomEngine); for (int j = 0; j <= numberBins; j++) { if (static_cast(bins[j].maxValue) >= number && static_cast(bins[j].minValue) <= number) bins[j].count++; } } return bins; } std::vector generateNormalDistribution(std::uint32_t howMany, float mean, float stdev, std::uint8_t numberBins) { int min = static_cast(mean - (4 * stdev)); int max = static_cast(mean + (4 * stdev) - 1); std::normal_distribution distribution(mean, stdev); auto bins = createBins(min, max, numberBins); for (int i = 0; i < static_cast(howMany); i++) { double number = distribution(randomEngine); int position = static_cast(number - min / ((max - min) / float(numberBins))); if (position > numberBins - 1) bins[numberBins - 1].count++; else if (position < 0) bins[0].count++; else bins[position].count++; } return bins; } std::vector generatePoissonDistribution(std::uint32_t howMany, std::uint8_t howOften, std::uint8_t numberBins) { std::poisson_distribution distribution(howOften); int min = 0; int max = numberBins - 1; auto bins = createBins(min, max, numberBins); for (int i = 0; i < static_cast(howMany); i++) { int number = distribution(randomEngine); if (number > numberBins - 1) bins[numberBins - 1].count++; else if (number < 0) bins[0].count++; else bins[number].count++; } return bins; } std::vector createBins(int min, int max, int binCount) { std::vector myVector; int difference = static_cast(float(max - min + 1) / binCount); for (int i = 0; i < binCount; i++) { DistributionPair dpair((min + i) * difference, (min + i) * difference + difference - 1); myVector.push_back(dpair); } return myVector; } void plotDistribution(std::string title, const std::vector& distribution, const std::uint8_t maxPlotLineSize) { std::cout << title << std::endl; auto max = 0; for (auto currentBin : distribution) { if (static_cast(currentBin.count) > static_cast(max)) max = currentBin.count; } for (auto currentBin : distribution) { int starCount = static_cast(currentBin.count / float(max) * maxPlotLineSize); std::string info = "[ " + std::to_string(currentBin.minValue) + ", " + std::to_string(currentBin.maxValue) + " ] : "; std::string starString; for (int i = 0; i < starCount; i++) starString += "*"; std::cout << std::setw(15) << info << starString; std::cout << std::endl; } }