use crate::ScaletError;
use crate::err::try_vec;
use crate::sample::CwtSample;
use crate::scale_bounds::linspace;
use num_traits::AsPrimitive;
pub(crate) fn log_piecewise_scales<T: CwtSample>(
min_scale: T,
max_scale: T,
nv: T,
) -> Result<Vec<T>, ScaletError>
where
usize: AsPrimitive<T>,
isize: AsPrimitive<T>,
{
let na: isize = (nv * (max_scale / min_scale).log2()).ceil().as_();
let mn_pow: isize = (nv * min_scale.log2()).floor().as_();
let mx_pow = mn_pow + na;
if mx_pow < mn_pow {
panic!("Something went wrong and impossible condition has occur");
}
let mut base_scales = try_vec![T::zero(); (mx_pow - mn_pow) as usize];
for (i, dst) in base_scales.iter_mut().enumerate() {
let p = i as isize + mn_pow;
let p_f64 = p.as_();
let exponent = p_f64 / nv;
let scale_value = exponent.exp2();
*dst = scale_value;
}
Ok(base_scales)
}
pub(crate) fn linear_scales<T: CwtSample>(
min_scale: T,
max_scale: T,
nv: T,
) -> Result<Vec<T>, ScaletError>
where
usize: AsPrimitive<T>,
isize: AsPrimitive<T>,
{
let na: isize = (nv * (max_scale / min_scale).log2()).ceil().as_();
let mn_pow: isize = (nv * min_scale.log2()).floor().as_();
let mx_pow = mn_pow + na;
let min_scale = (mn_pow.as_() / nv).exp2();
let max_scale = (mx_pow.as_() / nv).exp2();
let na: usize = (max_scale / min_scale).ceil().as_();
linspace(min_scale, max_scale, na)
}