use crate::{Vec, WaveletHaar, WaveletUnitRole, vec_ as vec};
#[allow(unused_imports, reason = "!std: abs")]
use crate::FloatExt;
#[doc = crate::_tags!(wave)]
#[doc = crate::_doc_location!("phys/wave")]
pub trait WaveletCompressionVec {
fn compress(&self, coeffs: &[f64], tolerance: f64) -> Vec<f64>;
}
#[doc = crate::_tags!(wave)]
#[doc = crate::_doc_location!("phys/wave")]
pub trait WaveletTransformVec {
#[must_use]
fn forward(&self, input: &[f64]) -> Vec<f64>;
#[must_use]
fn inverse(&self, coeffs: &[f64]) -> Vec<f64>;
}
#[doc = crate::_tags!(wave)]
#[doc = crate::_doc_location!("phys/wave")]
#[derive(Debug)]
pub struct WaveletUnitVec {
pub component_type: WaveletUnitRole,
pub level: usize,
pub position: usize,
pub values: Vec<f64>,
}
impl WaveletUnitVec {
pub fn new(
component_type: WaveletUnitRole,
level: usize,
position: usize,
values: Vec<f64>,
) -> Self {
Self { component_type, level, position, values }
}
}
impl WaveletCompressionVec for WaveletHaar {
fn compress(&self, coeffs: &[f64], tolerance: f64) -> Vec<f64> {
coeffs.iter().map(|&c| if c.abs() < tolerance { 0.0 } else { c }).collect()
}
}
impl WaveletTransformVec for WaveletHaar {
fn forward(&self, input: &[f64]) -> Vec<f64> {
let mut output = input.to_vec();
let mut length = output.len();
while length > 1 {
let mut temp = vec![0.0; length];
for i in 0..length / 2 {
let average = (output[2 * i] + output[2 * i + 1]) / 2.0;
let difference = (output[2 * i] - output[2 * i + 1]) / 2.0;
temp[i] = average;
temp[length / 2 + i] = difference; }
output[..length].clone_from_slice(&temp);
length /= 2; }
output
}
fn inverse(&self, coeffs: &[f64]) -> Vec<f64> {
let mut output = coeffs.to_vec();
let mut length = 2;
while length <= output.len() {
let mut temp = vec![0.0; length];
for i in 0..length / 2 {
let average = output[i];
let difference = output[length / 2 + i];
temp[2 * i] = average + difference; temp[2 * i + 1] = average - difference; }
output[..length].clone_from_slice(&temp);
length *= 2; }
output
}
}