Public
Edited
Aug 30, 2024
Insert cell
Insert cell
Insert cell
randomNumbers = Array.from({ length: 400 }, () => Math.floor(Math.random() * 256));
Insert cell
enCoded = enCode(randomNumbers, _probabilities, _cumulativeProbs)
Insert cell
decoded = deCode(enCoded, _probabilities, _cumulativeProbs, randomNumbers.length)
Insert cell
_cumulativeProbs = CumulativeProbs(_probabilities)
Insert cell
_probabilities = Probabilities(randomNumbers);
Insert cell
Big.DP = 1000; // Set number of decimal places to retain precision
Insert cell
function enCode(input_data, _probabilities, _cumulativeProbs) {
let low = new Big(0);
let high = new Big(1);

for (let symbol of input_data) {
const rangeSize = high.minus(low);

// Debugging logs
// console.log(`symbol: ${symbol}, low: ${low.toString()}, high: ${high.toString()}, rangeSize: ${rangeSize.toString()}`);

// Access cumulative probability before the current symbol and the probability of the symbol
const cumulativeProbBefore = new Big(_cumulativeProbs[symbol]);
const symbolProb = new Big(_probabilities[symbol]);

// console.log(`cumulativeProbs[symbol]: ${cumulativeProbBefore.toString()} - probabilities[symbol]: ${symbolProb.toString()}`)
high = low.plus(rangeSize.times(cumulativeProbBefore.plus(symbolProb)));
low = low.plus(rangeSize.times(cumulativeProbBefore));

// console.log(`new high = ${high.toString()} new low = ${low.toString()}`);
// console.log('---------------------------------------------------');
}

const encodedValue = low.plus(high).div(2);
return encodedValue;
}
Insert cell
function Probabilities(input_data) {
// Step 1: Calculate the frequency of each symbol
let frequency = {};
for (let symbol of input_data) {
if (frequency[symbol]) {
frequency[symbol] = frequency[symbol].plus(1);
} else {
frequency[symbol] = new Big(1);
}
}

// Step 2: Calculate the probability of each symbol
let probabilities = {};
let inputSize = new Big(input_data.length);
for (let symbol in frequency) {
probabilities[symbol] = frequency[symbol].div(inputSize);
}

return probabilities;
}
Insert cell
function CumulativeProbs(probabilities) {
// Step 1: Extract and sort the symbols
let symbols = Object.keys(probabilities).map(Number).sort((a, b) => a - b);
// Step 2: Calculate cumulative probabilities
let cumulativeProbs = {};
let cumulativeSum = new Big(0);

for (let symbol of symbols) {
cumulativeProbs[symbol] = cumulativeSum;
cumulativeSum = cumulativeSum.plus(new Big(probabilities[symbol]));
}

return cumulativeProbs;
}
Insert cell
function deCode(encodedValue, probabilities, cumulativeProbs, inputSize) {
let low = new Big(0);
let high = new Big(1);
let decoded = [];
let bigEncodedValue = new Big(encodedValue);

for (let i = 0; i < inputSize; i++) {
const rangeSize = high.minus(low);
const scaledValue = bigEncodedValue.minus(low).div(rangeSize);

// Debugging logs
// console.log(`i: ${i}, low: ${low.toString()}, high: ${high.toString()}, range: ${rangeSize.toString()}, scaledValue: ${scaledValue.toString()}`);

let symbol;
for (let s in cumulativeProbs) {
const cumulativeProb = new Big(cumulativeProbs[s]);
const prob = new Big(probabilities[s]);
const cumulativeProbAfter = cumulativeProb.plus(prob);

if (scaledValue.gte(cumulativeProb) && scaledValue.lt(cumulativeProbAfter)) {
symbol = parseInt(s); // Convert the key back to a number if needed
high = low.plus(rangeSize.times(cumulativeProbAfter));
low = low.plus(rangeSize.times(cumulativeProb));
decoded.push(symbol);
break;
}
}

if (symbol === undefined) {
throw new Error("Decoding error: Unable to find matching symbol.");
}
}

return decoded;
}
Insert cell
Insert cell
Big = require('big.js')
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more