From 57c573975353fd6d84d80e8479e514cc1e2248cd Mon Sep 17 00:00:00 2001 From: Gheorghita Mutu Date: Sat, 31 Aug 2024 22:39:58 +0300 Subject: [PATCH] [Entropy] + add Renyi entropy (untested) (2) --- GViewCore/src/Entropy/Entropy.cpp | 44 ++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/GViewCore/src/Entropy/Entropy.cpp b/GViewCore/src/Entropy/Entropy.cpp index 31c6b12c..f794efe7 100644 --- a/GViewCore/src/Entropy/Entropy.cpp +++ b/GViewCore/src/Entropy/Entropy.cpp @@ -2,28 +2,58 @@ #include +constexpr uint32 MAX_NUMBER_OF_BYTES = 256; + namespace GView::Entropy { -double ShannonEntropy(const BufferView& buffer) +void SetFrequencies(const BufferView& buffer, std::array& frequency) { - char frequency[256]{}; - // Count frequency of each byte in the buffer for (uint32 i = 0; i < buffer.GetLength(); i++) { const auto c = buffer[i]; frequency[c]++; } +} - // Calculate entropy +double ShannonEntropy_private(const BufferView& buffer, std::array& frequency) +{ double entropy = 0.0; - for (const auto& value : frequency) { - if (value == 0) { + for (auto f : frequency) { + if (f == 0) { continue; } - double probability = static_cast(value) / buffer.GetLength(); + double probability = static_cast(f) / buffer.GetLength(); entropy -= probability * log2(probability); } return entropy; // max log2(n) = 8 } + +double ShannonEntropy(const BufferView& buffer) +{ + std::array frequency{}; + SetFrequencies(buffer, frequency); + return ShannonEntropy_private(buffer, frequency); +} + +double RenyiEntropy(const BufferView& buffer, double alpha) +{ + std::array frequency{}; + SetFrequencies(buffer, frequency); + + if (alpha == 1.0) { + return ShannonEntropy_private(buffer, frequency); + } + + double sum = 0.0; + for (auto f : frequency) { + double probability = static_cast(f) / buffer.GetLength(); + if (probability > 0) { + sum += pow(probability, alpha); + } + } + + // Convert to bits if using log base e + return ((1.0 / (1.0 - alpha)) * log(sum)) / log(2); +} } // namespace GView::Entropy