pub trait IterableEntropyModel<'m, const PRECISION: usize>: EntropyModel<PRECISION> {
    type Iter: Iterator<Item = (Self::Symbol, Self::Probability, <Self::Probability as BitArray>::NonZero)>;

    // Required method
    fn symbol_table(&'m self) -> Self::Iter;

    // Provided methods
    fn floating_point_symbol_table<F>(
        &'m self
    ) -> FloatingPointSymbolTable<F, Self::Iter, PRECISION> 
       where F: From<Self::Probability> { ... }
    fn entropy_base2<F>(&'m self) -> F
       where F: Float + Sum,
             Self::Probability: Into<F> { ... }
    fn to_generic_encoder_model(
        &'m self
    ) -> NonContiguousCategoricalEncoderModel<Self::Symbol, Self::Probability, PRECISION>
       where Self::Symbol: Hash + Eq { ... }
    fn to_generic_decoder_model(
        &'m self
    ) -> NonContiguousCategoricalDecoderModel<Self::Symbol, Self::Probability, Vec<(Self::Probability, Self::Symbol)>, PRECISION>
       where Self::Symbol: Clone { ... }
    fn to_generic_lookup_decoder_model(
        &'m self
    ) -> LookupDecoderModel<Self::Symbol, Self::Probability, NonContiguousSymbolTable<Vec<(Self::Probability, Self::Symbol)>>, Box<[Self::Probability]>, PRECISION>
       where Self::Probability: Into<usize>,
             usize: AsPrimitive<Self::Probability>,
             Self::Symbol: Copy + Default { ... }
}
Expand description

A trait for EntropyModels that can be serialized into a common format.

The method symbol_table iterates over all symbols with nonzero probability under the entropy. The iteration occurs in uniquely defined order of increasing left-sided cumulative probability distribution of the symbols. All EntropyModels for which such iteration can be implemented efficiently should implement this trait. EntropyModels for which such iteration would require extra work (e.g., sorting symbols by left-sided cumulative distribution) should not implement this trait so that callers can assume that calling symbol_table is cheap.

The main advantage of implementing this trait is that it provides default implementations of conversions to various other EncoderModels and DecoderModels, see to_generic_encoder_model, to_generic_decoder_model, and to_generic_lookup_decoder_model.

Required Associated Types§

source

type Iter: Iterator<Item = (Self::Symbol, Self::Probability, <Self::Probability as BitArray>::NonZero)>

The type of the iterator returned by symbol_table.

Each item is a tuple (symbol, left_sided_cumulative, probability).

Required Methods§

source

fn symbol_table(&'m self) -> Self::Iter

Iterates over all symbols in the unique order that is consistent with the cumulative distribution.

The iterator iterates in order of increasing cumulative.

This method may be used, e.g., to export the model into a serializable format. It is also used internally by constructors that create a different but equivalent representation of the same entropy model (e.g., to construct a LookupDecoderModel from some EncoderModel).

Example
use constriction::stream::model::{
    IterableEntropyModel, SmallNonContiguousCategoricalDecoderModel
};

let symbols = vec!['a', 'b', 'x', 'y'];
let probabilities = vec![0.125, 0.5, 0.25, 0.125]; // Can all be represented without rounding.
let model = SmallNonContiguousCategoricalDecoderModel
    ::from_symbols_and_floating_point_probabilities(&symbols, &probabilities).unwrap();

// Print a table representation of this entropy model (e.g., for debugging).
dbg!(model.symbol_table().collect::<Vec<_>>());

// Create a lookup model. This method is provided by the trait `IterableEntropyModel`.
let lookup_decoder_model = model.to_generic_lookup_decoder_model();
See also

Provided Methods§

source

fn floating_point_symbol_table<F>( &'m self ) -> FloatingPointSymbolTable<F, Self::Iter, PRECISION>
where F: From<Self::Probability>,

Similar to symbol_table, but yields both cumulatives and probabilities in floating point representation.

The conversion to floats is guaranteed to be lossless due to the trait bound F: From<Self::Probability>.

source

fn entropy_base2<F>(&'m self) -> F
where F: Float + Sum, Self::Probability: Into<F>,

Returns the entropy in units of bits (i.e., base 2).

The entropy is the theoretical lower bound on the expected bit rate in any lossless entropy coder.

Note that calling this method on a LeakilyQuantizedDistribution will return the entropy after quantization, not the differential entropy of the underlying continuous probability distribution.

source

fn to_generic_encoder_model( &'m self ) -> NonContiguousCategoricalEncoderModel<Self::Symbol, Self::Probability, PRECISION>
where Self::Symbol: Hash + Eq,

Creates an EncoderModel from this EntropyModel

This is a fallback method that should only be used if no more specialized conversions are available. It generates a NonContiguousCategoricalEncoderModel with the same probabilities and left-sided cumulatives as self. Note that a NonContiguousCategoricalEncoderModel is very generic and therefore not particularly optimized. Thus, before calling this method first check:

  • if the original Self type already implements EncoderModel (some types implement both EncoderModel and DecoderModel); or
  • if the Self type has some inherent method with a name like to_encoder_model; if it does, that method probably returns an implementation of EncoderModel that is better optimized for your use case.
source

fn to_generic_decoder_model( &'m self ) -> NonContiguousCategoricalDecoderModel<Self::Symbol, Self::Probability, Vec<(Self::Probability, Self::Symbol)>, PRECISION>
where Self::Symbol: Clone,

Creates a DecoderModel from this EntropyModel

This is a fallback method that should only be used if no more specialized conversions are available. It generates a NonContiguousCategoricalDecoderModel with the same probabilities and left-sided cumulatives as self. Note that a NonContiguousCategoricalEncoderModel is very generic and therefore not particularly optimized. Thus, before calling this method first check:

  • if the original Self type already implements DecoderModel (some types implement both EncoderModel and DecoderModel); or
  • if the Self type has some inherent method with a name like to_decoder_model; if it does, that method probably returns an implementation of DecoderModel that is better optimized for your use case.
source

fn to_generic_lookup_decoder_model( &'m self ) -> LookupDecoderModel<Self::Symbol, Self::Probability, NonContiguousSymbolTable<Vec<(Self::Probability, Self::Symbol)>>, Box<[Self::Probability]>, PRECISION>

Creates a DecoderModel from this EntropyModel

This is a fallback method that should only be used if no more specialized conversions are available. It generates a LookupDecoderModel that makes no assumption about contiguity of the support. Thus, before calling this method first check if the Self type has some inherent method with a name like to_lookup_decoder_model. If it does, that method probably returns a LookupDecoderModel that is better optimized for your use case.

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

source§

impl<'m, M, const PRECISION: usize> IterableEntropyModel<'m, PRECISION> for &'m M
where M: IterableEntropyModel<'m, PRECISION>,

§

type Iter = <M as IterableEntropyModel<'m, PRECISION>>::Iter

source§

fn symbol_table(&'m self) -> Self::Iter

source§

fn entropy_base2<F>(&'m self) -> F
where F: Float + Sum, Self::Probability: Into<F>,

source§

fn to_generic_encoder_model( &'m self ) -> NonContiguousCategoricalEncoderModel<Self::Symbol, Self::Probability, PRECISION>
where Self::Symbol: Hash + Eq,

source§

fn to_generic_decoder_model( &'m self ) -> NonContiguousCategoricalDecoderModel<Self::Symbol, Self::Probability, Vec<(Self::Probability, Self::Symbol)>, PRECISION>
where Self::Symbol: Clone,

Implementors§

source§

impl<'m, 'q: 'm, Symbol, Probability, D, const PRECISION: usize> IterableEntropyModel<'m, PRECISION> for LeakilyQuantizedDistribution<f64, Symbol, Probability, D, PRECISION>
where f64: AsPrimitive<Probability>, Symbol: PrimInt + AsPrimitive<Probability> + AsPrimitive<usize> + Into<f64> + WrappingSub, Probability: BitArray + Into<f64>, D: Distribution + 'm, D::Value: AsPrimitive<Symbol>,

§

type Iter = LeakilyQuantizedDistributionIter<Symbol, Probability, &'m LeakilyQuantizedDistribution<f64, Symbol, Probability, D, PRECISION>, PRECISION>

source§

impl<'m, Probability, Table, LookupTable, const PRECISION: usize> IterableEntropyModel<'m, PRECISION> for LookupDecoderModel<Probability, Probability, ContiguousSymbolTable<Table>, LookupTable, PRECISION>
where Probability: BitArray + Into<usize>, usize: AsPrimitive<Probability>, Table: AsRef<[Probability]>, LookupTable: AsRef<[Probability]>,

§

type Iter = SymbolTableIter<Probability, Probability, ContiguousSymbolTable<&'m [Probability]>>

source§

impl<'m, Probability, Table, const PRECISION: usize> IterableEntropyModel<'m, PRECISION> for ContiguousCategoricalEntropyModel<Probability, Table, PRECISION>
where Probability: BitArray, Table: AsRef<[Probability]>,

source§

impl<'m, Probability, const PRECISION: usize> IterableEntropyModel<'m, PRECISION> for UniformModel<Probability, PRECISION>
where Probability: AsPrimitive<usize> + BitArray,

§

type Iter = UniformModelIter<'m, Probability, PRECISION>

source§

impl<'m, Symbol, Probability, Table, LookupTable, const PRECISION: usize> IterableEntropyModel<'m, PRECISION> for LookupDecoderModel<Symbol, Probability, NonContiguousSymbolTable<Table>, LookupTable, PRECISION>
where Symbol: Clone + 'm, Probability: BitArray + Into<usize>, usize: AsPrimitive<Probability>, Table: AsRef<[(Probability, Symbol)]>, LookupTable: AsRef<[Probability]>,

source§

impl<'m, Symbol, Probability, Table, const PRECISION: usize> IterableEntropyModel<'m, PRECISION> for NonContiguousCategoricalDecoderModel<Symbol, Probability, Table, PRECISION>
where Symbol: Clone + 'm, Probability: BitArray, Table: AsRef<[(Probability, Symbol)]>,