Javascript implementation of a Shannon entropy calculation in bits per symbol
// entropy.js MIT License © 2014 James Abney http://github.com/jabney | |
/*************************************** | |
* ES2015 | |
***************************************/ | |
// Shannon entropy in bits per symbol. | |
function entropy(str) { | |
const len = str.length | |
// Build a frequency map from the string. | |
const frequencies = Array.from(str) | |
.reduce((freq, c) => (freq[c] = (freq[c] || 0) + 1) && freq, {}) | |
// Sum the frequency of each character. | |
return Object.values(frequencies) | |
.reduce((sum, f) => sum - f/len * Math.log2(f/len), 0) | |
} | |
console.log(entropy('1223334444')) // 1.8464393446710154 | |
console.log(entropy('0')) // 0 | |
console.log(entropy('01')) // 1 | |
console.log(entropy('0123')) // 2 | |
console.log(entropy('01234567')) // 3 | |
console.log(entropy('0123456789abcdef')) // 4 | |
/*************************************** | |
* ES5 | |
***************************************/ | |
// Calculate the Shannon entropy of a string in bits per symbol. | |
(function(shannon) { | |
'use strict'; | |
// Create a dictionary of character frequencies and iterate over it. | |
function process(s, evaluator) { | |
var h = Object.create(null), k; | |
s.split('').forEach(function(c) { | |
h[c] && h[c]++ || (h[c] = 1); }); | |
if (evaluator) for (k in h) evaluator(k, h[k]); | |
return h; | |
}; | |
// Measure the entropy of a string in bits per symbol. | |
shannon.entropy = function(s) { | |
var sum = 0,len = s.length; | |
process(s, function(k, f) { | |
var p = f/len; | |
sum -= p * Math.log(p) / Math.log(2); | |
}); | |
return sum; | |
}; | |
// Measure the entropy of a string in total bits. | |
shannon.bits = function(s) { | |
return shannon.entropy(s) * s.length; | |
}; | |
// Log the entropy of a string to the console. | |
shannon.log = function(s) { | |
console.log('Entropy of "' + s + '" in bits per symbol:', shannon.entropy(s)); | |
}; | |
})(window.shannon = window.shannon || Object.create(null)); | |
shannon.log('1223334444'); // 1.8464393446710154 | |
shannon.log('0'); // 0 | |
shannon.log('01'); // 1 | |
shannon.log('0123'); // 2 | |
shannon.log('01234567'); // 3 | |
shannon.log('0123456789abcdef'); // 4 |
This comment has been minimized.
This comment has been minimized.
Glad you found it helpful. Here's an updated (and more concise) version for ECMAScript 2015: // Shannon entropy in bits per symbol.
function entropy(str) {
const len = str.length
// Build a frequency map from the string.
const frequencies = Array.from(str)
.reduce((freq, c) => (freq[c] = (freq[c] || 0) + 1) && freq, {})
// Sum the frequency of each character.
return Object.values(frequencies)
.reduce((sum, f) => sum - f/len * Math.log2(f/len), 0)
}
console.log(entropy('1223334444')) // 1.8464393446710154
console.log(entropy('0')) // 0
console.log(entropy('01')) // 1
console.log(entropy('0123')) // 2
console.log(entropy('01234567')) // 3
console.log(entropy('0123456789abcdef')) // 4 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
Thank you very much, quite useful!