arithmetic_coding_core/
model.rs

1use std::{error::Error, ops::Range};
2
3use crate::BitStore;
4
5pub mod fixed_length;
6pub mod max_length;
7pub mod one_shot;
8
9/// A [`Model`] is used to calculate the probability of a given symbol occuring
10/// in a sequence. The [`Model`] is used both for encoding and decoding.
11///
12/// The more accurately a [`Model`] is able to predict the next symbol, the
13/// greater the compression ratio will be.
14///
15/// # Example
16///
17/// ```
18/// # use std::convert::Infallible;
19/// use std::ops::Range;
20/// #
21/// # use arithmetic_coding_core::Model;
22///
23/// pub enum Symbol {
24///     A,
25///     B,
26///     C,
27/// }
28///
29/// pub struct MyModel;
30///
31/// impl Model for MyModel {
32///     type B = u32;
33///     type Symbol = Symbol;
34///     type ValueError = Infallible;
35///
36///     fn probability(&self, symbol: Option<&Self::Symbol>) -> Result<Range<u32>, Infallible> {
37///         Ok(match symbol {
38///             None => 0..1,
39///             Some(&Symbol::A) => 1..2,
40///             Some(&Symbol::B) => 2..3,
41///             Some(&Symbol::C) => 3..4,
42///         })
43///     }
44///
45///     fn symbol(&self, value: Self::B) -> Option<Self::Symbol> {
46///         match value {
47///             0..1 => None,
48///             1..2 => Some(Symbol::A),
49///             2..3 => Some(Symbol::B),
50///             3..4 => Some(Symbol::C),
51///             _ => unreachable!(),
52///         }
53///     }
54///
55///     fn max_denominator(&self) -> u32 {
56///         4
57///     }
58/// }
59/// ```
60pub trait Model {
61    /// The type of symbol this [`Model`] describes
62    type Symbol;
63
64    /// Invalid symbol error
65    type ValueError: Error;
66
67    /// The internal representation to use for storing integers
68    type B: BitStore;
69
70    /// Given a symbol, return an interval representing the probability of that
71    /// symbol occurring.
72    ///
73    /// This is given as a range, over the denominator given by
74    /// [`Model::denominator`]. This range should in general include `EOF`,
75    /// which is denoted by `None`.
76    ///
77    /// For example, from the set {heads, tails}, the interval representing
78    /// heads could be `0..1`, and tails would be `1..2`, and `EOF` could be
79    /// `2..3` (with a denominator of `3`).
80    ///
81    /// This is the inverse of the [`Model::symbol`] method
82    ///
83    /// # Errors
84    ///
85    /// This returns a custom error if the given symbol is not valid
86    fn probability(
87        &self,
88        symbol: Option<&Self::Symbol>,
89    ) -> Result<Range<Self::B>, Self::ValueError>;
90
91    /// The denominator for probability ranges. See [`Model::probability`].
92    ///
93    /// By default this method simply returns the [`Model::max_denominator`],
94    /// which is suitable for non-adaptive models.
95    ///
96    /// In adaptive models this value may change, however it should never exceed
97    /// [`Model::max_denominator`], or it becomes possible for the
98    /// [`Encoder`](crate::Encoder) and [`Decoder`](crate::Decoder) to panic due
99    /// to overflow or underflow.
100    fn denominator(&self) -> Self::B {
101        self.max_denominator()
102    }
103
104    /// The maximum denominator used for probability ranges. See
105    /// [`Model::probability`].
106    ///
107    /// This value is used to calculate an appropriate precision for the
108    /// encoding, therefore this value must not change, and
109    /// [`Model::denominator`] must never exceed it.
110    fn max_denominator(&self) -> Self::B;
111
112    /// Given a value, return the symbol whose probability range it falls in.
113    ///
114    /// `None` indicates `EOF`
115    ///
116    /// This is the inverse of the [`Model::probability`] method
117    fn symbol(&self, value: Self::B) -> Option<Self::Symbol>;
118
119    /// Update the current state of the model with the latest symbol.
120    ///
121    /// This method only needs to be implemented for 'adaptive' models. It's a
122    /// no-op by default.
123    fn update(&mut self, _symbol: Option<&Self::Symbol>) {}
124}