divans/probability/
variant_speed_cdf.rs

1use core;
2use super::interface::{Prob, BaseCDF, Speed, CDF16, BLEND_FIXED_POINT_PRECISION, SPEED_PALETTE_SIZE, SymStartFreq};
3use brotli::enc::util::FastLog2u16;
4
5#[derive(Clone,Copy)]
6pub struct VariantSpeedCDF<ChildCDF:BaseCDF+CDF16+Sized+Clone+Copy> {
7    cdf: [ChildCDF; SPEED_PALETTE_SIZE + 1],
8    cost: [f32;SPEED_PALETTE_SIZE+1],
9}
10
11impl<ChildCDF:BaseCDF+CDF16+Sized+Default> Default for VariantSpeedCDF<ChildCDF> {
12    fn default() -> Self{
13        VariantSpeedCDF {
14            cdf:[ChildCDF::default();SPEED_PALETTE_SIZE + 1],
15            cost:[0.0;SPEED_PALETTE_SIZE+1],
16        }
17    }
18}
19
20impl<ChildCDF:BaseCDF+CDF16+Sized+Default> CDF16 for VariantSpeedCDF<ChildCDF> {
21    fn blend(&mut self, symbol: u8, dyn:Speed) {
22        for (index, (cdf, cost)) in self.cdf.iter_mut().zip(self.cost.iter_mut()).enumerate() {
23            let pdf = cdf.pdf(symbol);
24            let max = cdf.max();
25            *cost += FastLog2u16(max as u16) - FastLog2u16(pdf as u16);
26            cdf.blend(symbol, if index == 0 {dyn} else {Speed::ENCODER_DEFAULT_PALETTE[index - 1]});
27        }
28    }
29    fn average(&self, other: &Self, mix_rate: i32) ->Self {
30        let mut ret = self.clone();
31        ret.cdf[0] = self.cdf[0].average(&other.cdf[0], mix_rate);
32        ret
33    }
34}
35
36impl<ChildCDF:BaseCDF+CDF16+Sized> BaseCDF for VariantSpeedCDF<ChildCDF> {
37    fn num_symbols() -> u8 {
38        <ChildCDF as BaseCDF>::num_symbols()
39    }
40    fn cdf(&self, symbol: u8) -> Prob {
41        self.cdf[0].cdf(symbol)
42    }
43    fn pdf(&self, symbol: u8) -> Prob {
44        self.cdf[0].pdf(symbol)
45    }
46    fn div_by_max(&self, val: i32) -> i32 {
47        self.cdf[0].div_by_max(val)
48    }
49    fn max(&self) -> Prob {
50        self.cdf[0].max()
51    }
52    fn log_max(&self) -> Option<i8> {
53        self.cdf[0].log_max()
54    }
55    fn used(&self) -> bool {
56        self.cdf[0].used()
57    }
58
59    // returns true if valid.
60    fn valid(&self) -> bool {
61        self.cdf[0].valid()
62    }
63
64    // returns the entropy of the current distribution.
65    fn entropy(&self) -> f64 {
66        self.cdf[0].entropy()
67    }
68    #[inline(always)]
69    fn sym_to_start_and_freq(&self,
70                             sym: u8) -> SymStartFreq {
71        self.cdf[0].sym_to_start_and_freq(sym)
72    }
73    #[inline(always)]
74    fn rescaled_cdf(&self, sym: u8) -> i32 {
75        self.cdf[0].rescaled_cdf(sym)
76    }
77    #[inline(always)]
78    fn cdf_offset_to_sym_start_and_freq(&self,
79                                        cdf_offset_p: Prob) -> SymStartFreq {
80        self.cdf[0].cdf_offset_to_sym_start_and_freq(cdf_offset_p)
81    }
82
83    // These methods are optional because implementing them requires nontrivial bookkeeping.
84    // Only CDFs that are intended for debugging should support them.
85    fn num_samples(&self) -> Option<u32> {
86        self.cdf[0].num_samples()
87    }
88    fn true_entropy(&self) -> Option<f64> {
89        self.cdf[0].true_entropy()
90    }
91    fn rolling_entropy(&self) -> Option<f64> {
92        self.cdf[0].rolling_entropy()
93    }
94    fn encoding_cost(&self) -> Option<f64> {
95        self.cdf[0].encoding_cost()
96    }
97    fn num_variants(&self) -> usize {
98        SPEED_PALETTE_SIZE
99    }
100    fn variant_cost(&self, variant_index: usize) -> f32 {
101        self.cost[variant_index + 1]
102    }
103    fn base_variant_cost(&self) -> f32 {
104        self.cost[0]
105    }
106}