pub const WGSL: &str = concat!(
include_str!("../wgsl_byte_primitives/bytes.wgsl"),
"\n",
include_str!("wgsl/sliding_entropy.wgsl"),
);
#[must_use]
pub fn sliding_entropy(input: &[u8], window: u32) -> Vec<f32> {
let Ok(window) = usize::try_from(window) else {
return Vec::new();
};
if window == 0 || window > input.len() {
return Vec::new();
}
input
.windows(window)
.map(|slice| {
let mut counts = [0_u32; 256];
for &byte in slice {
counts[usize::from(byte)] += 1;
}
let len = slice.len() as f64;
counts
.iter()
.filter(|&&count| count != 0)
.map(|&count| {
let p = f64::from(count) / len;
-p * p.log2()
})
.sum::<f64>() as f32
})
.collect()
}
#[must_use]
pub fn sliding_entropy_bits(input: &[u8], window: u32) -> Vec<u32> {
sliding_entropy(input, window)
.into_iter()
.map(f32::to_bits)
.collect()
}