ans
Asymmetric numeral systems entropy coding.
Pure Rust, no_std-compatible, with streaming primitives (peek/advance)
for bits-back coding (BB-ANS, ROC).
Batch API
use ;
let counts = ; // A, B, C
let table = from_counts?;
let message = ;
let bytes = encode?;
let back = decode?;
assert_eq!;
# Ok::
Streaming API
Symbol-at-a-time encoding/decoding. Required for bits-back coding (BB-ANS, ROC).
use ;
let table = from_counts?;
let message = ;
// Encode in reverse order (rANS requirement).
let mut enc = new;
for &sym in message.iter.rev
let bytes = enc.finish;
// Decode in forward order.
let mut dec = new?;
let mut decoded = Vecnew;
for _ in 0..message.len
assert_eq!;
# Ok::
Bits-back primitives
RansDecoder::peek and RansDecoder::advance allow inspecting the decoded slot
before advancing state, which is the key operation for bits-back coding:
# use ;
# let table = from_counts?;
# let bytes = encode?;
let mut dec = new?;
let sym = dec.peek; // look at slot without advancing
dec.advance?; // advance after external logic
# Ok::
Building frequency tables
From integer counts (quantized internally):
use FrequencyTable;
let table = from_counts?;
# Ok::
From floating-point probabilities (e.g. neural network output):
use FrequencyTable;
let table = from_float_probs?;
# Ok::
From pre-normalized frequencies (skip internal quantization):
use FrequencyTable;
// Frequencies must sum to exactly 2^precision_bits.
let table = from_normalized?;
# Ok::
no_std
This crate has zero dependencies and is no_std-compatible (requires alloc).
Notes
- Encoding returns a byte vector in a stack format: decoding consumes bytes from the end.
- This crate is focused on correctness and integration simplicity (not maximum throughput).
Choosing precision_bits
FrequencyTable::from_counts(counts, precision_bits) builds a model with total mass
(T = 2^{precision_bits}). Practical guidance:
- Larger
precision_bitsapproximates the empirical distribution more closely (less quantization), but increases memory and can slow decoding. - Typical ranges are ~12–16 for small alphabets.
Memory footprint
The table stores sym_by_slot of length (T), mapping each slot to a symbol. This dominates:
- Approx size (\approx 4 \cdot 2^{precision_bits}) bytes (u32 per slot), plus
cdf/freqs. - Example:
precision_bits = 14→ (2^{14} = 16384) slots → ~64 KiB forsym_by_slot.
Security / robustness
This is an entropy coder, not encryption. Do not treat it as a cryptographic primitive.
License
MIT OR Apache-2.0