use ahash::AHashMap;
use super::counter::Counter;
#[derive(Default)]
pub(crate) struct PairwiseFreq<'s> {
follows: Counter<&'s str>,
followed_by: Counter<&'s str>,
}
#[derive(Default)]
pub(crate) struct Contexts<'s> {
map: AHashMap<&'s str, PairwiseFreq<'s>>,
}
impl<'s> Contexts<'s> {
#[inline]
pub fn track(&mut self, left: &'s str, right: &'s str) {
self.map.entry(right).or_default().follows.inc(left);
self.map.entry(left).or_default().followed_by.inc(right);
}
#[inline]
pub fn cases_term_is_followed(&self, term: &str, by: &str) -> usize {
self.map.get(term).map_or(0, |freq| freq.followed_by.get(&by))
}
pub fn dispersion_of(&self, term: &str) -> (f64, f64) {
match self.map.get(term) {
None => (0.0, 0.0),
Some(PairwiseFreq { follows, followed_by }) => (
if follows.is_empty() {
0.0
} else {
follows.distinct() as f64 / follows.total() as f64
},
if followed_by.is_empty() {
0.0
} else {
followed_by.distinct() as f64 / followed_by.total() as f64
},
),
}
}
}