From 6bf4b90c90f15f4ab60833bddf5b5756d1a6b1f6 Mon Sep 17 00:00:00 2001 From: Elizabeth Alexander Hunt Date: Thu, 2 Jul 2026 11:55:17 -0700 Subject: Init --- Homework/cs3460/rands/distributions.cpp | 168 ++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 Homework/cs3460/rands/distributions.cpp (limited to 'Homework/cs3460/rands/distributions.cpp') diff --git a/Homework/cs3460/rands/distributions.cpp b/Homework/cs3460/rands/distributions.cpp new file mode 100644 index 0000000..e3f92ab --- /dev/null +++ b/Homework/cs3460/rands/distributions.cpp @@ -0,0 +1,168 @@ +#include "distributions.hpp" + +#include +#include +#include +#include +#include +#include +#include +#if defined(_MSC_VER) + #pragma warning(push) + #pragma warning(disable : 4189) // Disable some compiler warnings that come from fmt +#endif +#include +#if defined(_MSC_VER) + #pragma warning(pop) +#endif + +/* + @param bins: std::vector&, reference to vector of bins + @param element: std::uint32_t, the number to insert - fractional values + should be `floored` as to meet the fractional requirements of the + program + @param start: std::uint8_t, the beginning of the current window + @param end: std::uint8_t, the end of the current window + @return DistributionPair*: pointer to the bin element fits in +*/ +DistributionPair* binarySearchBins(std::vector& bins, + std::uint32_t element, std::uint8_t start, + std::uint8_t end); +/* + @param min: uint32_t, the minvalue value of the first bin + @param max: uint32_t, the maxvalue of the last bin + @param howMany: uint32_t, the number of bins to create + @return std::vector: a vector of bins initialized + with count = 0 +*/ +std::vector +initializeBins(std::uint32_t min, std::uint32_t max, std::uint8_t howMany); + +DistributionPair* binarySearchBins(std::vector& bins, + std::uint32_t element, std::uint8_t start, + std::uint8_t end) +{ + std::uint8_t mid = (end + start) / 2; + DistributionPair* dP = &bins.at(mid); + + // Base cases: + // 1. Our element is less than the minimum in the bins + // 2. Our element is greater than maximum in the bins + // 3. Our element belongs in the current bin + if (end <= start || mid == bins.size() - 1 || + (dP->minValue <= element && dP->maxValue >= element)) + return dP; + + // RESCURSION!!! + if (dP->maxValue < element) + return binarySearchBins(bins, element, mid, end); + return binarySearchBins(bins, element, start, mid); +} + +std::vector +initializeBins(std::uint32_t min, std::uint32_t max, std::uint8_t howMany) +{ + std::vector bins; + // The difference between each minValue and maxValue of each bin can be zero + // if numBins = num. of elements + std::uint32_t delta = static_cast( + std::ceil((static_cast(max - min) / howMany) - 1)); + + for (std::uint32_t i = 0; i < howMany; i++) + { + std::uint32_t newMin = min; + if (i) + newMin = bins.at(i - 1).maxValue + 1; + DistributionPair newBin(newMin, newMin + delta); + bins.push_back(newBin); + } + + return bins; +} + +void plotDistribution(std::string title, + const std::vector& distribution, + const std::uint8_t maxPlotLineSize) +{ + std::cout << fmt::format("{}", title) << std::endl; + + std::uint32_t maxCount = + std::max_element( + std::begin(distribution), std::end(distribution), + [](const DistributionPair bin1, const DistributionPair bin2) + { return bin1.count < bin2.count; }) + ->count; + + std::uint32_t maxBinElementWidth = static_cast(ceil(log10(distribution.back().maxValue)) + 1); + + std::uint32_t binThreshold = maxCount / maxPlotLineSize; + for (const DistributionPair bin : distribution) + { + std::cout << fmt::format("[{0:>{1}}, {2:>{3}}] {4:<{5}}", bin.minValue, + maxBinElementWidth, bin.maxValue, + maxBinElementWidth, std::string(bin.count / binThreshold, '*'), maxPlotLineSize) + << std::endl; + } +} + +std::vector +generateUniformDistribution(std::uint32_t howMany, std::uint32_t min, + std::uint32_t max, std::uint8_t numberBins) +{ + std::vector bins = initializeBins(min, max, numberBins); + + std::default_random_engine generator; + std::uniform_int_distribution distribution(min, max); + + for (std::uint32_t i = 0; i < howMany; i++) + { + uint32_t randomElement = distribution(generator); + binarySearchBins(bins, randomElement, 0, numberBins)->count++; + } + + return bins; +} + +std::vector +generateNormalDistribution(std::uint32_t howMany, float mean, float stdev, + std::uint8_t numberBins) +{ + std::uint32_t min = static_cast(mean - 4 * stdev); + std::uint32_t max = static_cast(mean + 4 * stdev); + + // Get the right number of bins + if (((max - min) % numberBins > 0) && (((max - 1) - min) % numberBins == 0)) + max -= 1; + + std::vector bins = initializeBins(min, max, numberBins); + + std::default_random_engine generator; + std::normal_distribution distribution(mean, stdev); + + for (std::uint32_t i = 0; i < howMany; i++) + { + uint32_t randomElement = static_cast(distribution(generator)); + binarySearchBins(bins, randomElement, 0, numberBins)->count++; + } + + return bins; +} + +std::vector +generatePoissonDistribution(std::uint32_t howMany, std::uint8_t howOften, + std::uint8_t numberBins) +{ + std::vector bins = + initializeBins(0, numberBins - 1, numberBins); + + std::default_random_engine generator; + std::poisson_distribution distribution(howOften); + + for (std::uint32_t i = 0; i < howMany; i++) + { + uint32_t randomElement = distribution(generator); + binarySearchBins(bins, randomElement, 0, numberBins)->count++; + } + + return bins; +} \ No newline at end of file -- cgit v1.3