pub trait EncoderModel<const PRECISION: usize>: EntropyModel<PRECISION> {
    // Required method
    fn left_cumulative_and_probability(
        &self,
        symbol: impl Borrow<Self::Symbol>
    ) -> Option<(Self::Probability, <Self::Probability as BitArray>::NonZero)>;

    // Provided method
    fn floating_point_probability<F>(&self, symbol: Self::Symbol) -> F
       where F: FloatCore,
             Self::Probability: Into<F> { ... }
}
Expand description

A trait for EntropyModels that can be used for encoding (compressing) data.

As discussed in the module level documentation, all stream codes in constriction use so-called EntropyModels for encoding and/or decoding data. Some of these EntropyModels may be used only for encoding, only for decoding, or for both, depending on their internal representation.

This EncoderModel trait is implemented for all entropy models that can be used for encoding data. To encode data with an EncoderModel, construct an entropy coder that implements the Encode trait and pass the data and the entropy model to one of the methods of the Encode trait (or to an inherent method of the entropy coder, such as AnsCoder::encode_symbols_reverse).

Blanket Implementation for &impl EncoderModel

We provide the following blanket implementation for references to EncoderModels:

impl<M, const PRECISION: usize> EncoderModel<PRECISION> for &M
where
    M: EncoderModel<PRECISION> + ?Sized
{ ... }

This means that, if some type M implements EncoderModel<PRECISION> for some PRECISION, then so does the reference type &M. Therefore, generic functions or methods should never take a generic EncoderModel by reference. They should always take the generic EncoderModel by value because this also covers the case of references but is strictly more general. If your generic function needs to be able to cheaply copy the EncoderModel (as it could with a shared reference) then it should still take the generic EncoderModel formally by value and just add an additional Copy bound (see, e.g., the method signature of Encode::encode_iid_symbols. For a more elaborate explanation, please refer to the discussion of the analogous blanket implementation for EntropyModel.

See Also

Required Methods§

source

fn left_cumulative_and_probability( &self, symbol: impl Borrow<Self::Symbol> ) -> Option<(Self::Probability, <Self::Probability as BitArray>::NonZero)>

Looks up a symbol in the entropy model.

Takes a symbol either by value or by reference and looks it up in the entropy model.

  • If symbol has a nonzero probability under the model, then this method returns Some((left_sided_cumulative, probability)), where probability is the probability in fixed-point representation (see discussion) and left_sided_cumulative is the sum of the probabilities of all symbols up to but not including symbol (also in fixed-point representation). Both left_sided_cumulative and probability are guaranteed to be strictly smaller than 1 << PRECISION (which would semantically represent “probability one”) because probability is nonzero and because we don’t support degenerate entropy models that put all probability mass on a single symbol.
  • If symbol has zero probability under the model, then this method returns None.

Provided Methods§

source

fn floating_point_probability<F>(&self, symbol: Self::Symbol) -> F
where F: FloatCore, Self::Probability: Into<F>,

Returns the probability of the given symbol in floating point representation.

The trait bound Self::Probability: Into<F> guarantees that no rounding occurs in the conversion. You may have to specify the return type explicitly using “turbofish” notation ::<f64>(...) or ::<f32>(...), see example below.

Returns 0.0 if symbol is not in the support of the entropy model.

This method is provided mainly as a convenience for debugging.

Example
use constriction::stream::model::{EncoderModel, DefaultNonContiguousCategoricalEncoderModel};

let symbols = vec!['a', 'b', 'c', 'd'];
let probabilities = vec![1u32 << 21, 1 << 23, 1 << 22, 1 << 21];
let model = DefaultNonContiguousCategoricalEncoderModel // "Default" uses `PRECISION = 24`
    ::from_symbols_and_nonzero_fixed_point_probabilities(
        symbols.iter().copied(), &probabilities, false)
    .unwrap();

assert_eq!(model.floating_point_probability::<f64>('a'), 0.125);
assert_eq!(model.floating_point_probability::<f64>('b'), 0.5);
assert_eq!(model.floating_point_probability::<f64>('c'), 0.25);
assert_eq!(model.floating_point_probability::<f64>('d'), 0.125);
assert_eq!(model.floating_point_probability::<f64>('x'), 0.0);

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

source§

impl<M, const PRECISION: usize> EncoderModel<PRECISION> for &M
where M: EncoderModel<PRECISION> + ?Sized,

source§

fn left_cumulative_and_probability( &self, symbol: impl Borrow<Self::Symbol> ) -> Option<(Self::Probability, <Self::Probability as BitArray>::NonZero)>

Implementors§

source§

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

EncoderModel is only implemented for contiguous generic categorical models. To decode encode symbols from a non-contiguous support, use an NonContiguousCategoricalEncoderModel.

source§

impl<Probability: BitArray, const PRECISION: usize> EncoderModel<PRECISION> for UniformModel<Probability, PRECISION>

source§

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

source§

impl<Symbol, Probability, const PRECISION: usize> EncoderModel<PRECISION> for NonContiguousCategoricalEncoderModel<Symbol, Probability, PRECISION>
where Symbol: Hash + Eq, Probability: BitArray,