1#[cfg(feature = "use_serde")]
2use serde::{Deserialize, Serialize};
3
4#[cfg(feature = "use_rkyv")]
5use rkyv::{Deserialize, Serialize, Archive};
6
7const DEFAULT_MAX_BINS: u32 = 2048;
8const DEFAULT_ALPHA: f64 = 0.01;
9const DEFAULT_MIN_VALUE: f64 = 1.0e-9;
10
11#[derive(Copy, Clone, Debug, PartialEq)]
13#[cfg_attr(feature = "use_serde", derive(Serialize, Deserialize))]
14#[cfg_attr(feature = "use_rkyv", derive(Serialize, Deserialize, Archive))]
15pub struct Config {
16 pub max_num_bins: u32,
17 pub gamma: f64,
18 gamma_ln: f64,
19 min_value: f64,
20 pub offset: i32,
21}
22
23fn log_gamma(value: f64, gamma_ln: f64) -> f64 {
24 value.ln() / gamma_ln
25}
26
27impl Config {
28 pub fn new(alpha: f64, max_num_bins: u32, min_value: f64) -> Self {
33 let gamma_ln = (2.0 * alpha) / (1.0 - alpha);
34 let gamma_ln = gamma_ln.ln_1p();
35
36 Config {
37 max_num_bins,
38 gamma: 1.0 + (2.0 * alpha) / (1.0 - alpha),
39 gamma_ln,
40 min_value,
41 offset: 1 - (log_gamma(min_value, gamma_ln) as i32),
42 }
43 }
44
45 pub fn defaults() -> Self {
47 Self::new(DEFAULT_ALPHA, DEFAULT_MAX_BINS, DEFAULT_MIN_VALUE)
48 }
49
50 pub fn key(&self, v: f64) -> i32 {
51 self.log_gamma(v).ceil() as i32
52 }
53
54 pub fn value(&self, key: i32) -> f64 {
55 self.pow_gamma(key) * (2.0 / (1.0 + self.gamma))
56 }
57
58 pub fn log_gamma(&self, value: f64) -> f64 {
59 log_gamma(value, self.gamma_ln)
60 }
61
62 pub fn pow_gamma(&self, key: i32) -> f64 {
63 ((key as f64) * self.gamma_ln).exp()
64 }
65
66 pub fn min_possible(&self) -> f64 {
67 self.min_value
68 }
69}
70
71impl Default for Config {
72 fn default() -> Self {
73 Self::new(DEFAULT_ALPHA, DEFAULT_MAX_BINS, DEFAULT_MIN_VALUE)
74 }
75}