use std::{cmp::Ordering, io::Read};
use ndarray::{Array, Array1, ArrayView1, ArrayView2, Axis};
use npyz::{Deserialize, NpyFile};
#[cfg(feature = "progress_bar")]
use indicatif::{ProgressBar, ProgressStyle};
#[cfg(feature = "progress_bar")]
use std::time::Duration;
pub fn read_array1_from_npy_file<T: Deserialize, R: Read>(npy: NpyFile<R>) -> Array1<T> {
let mut v: Vec<T> = Vec::new();
v.reserve_exact(npy.shape()[0].try_into().unwrap());
v.extend(npy.data().unwrap().map(|x| x.unwrap()));
Array::from_vec(v)
}
#[cfg(feature = "progress_bar")]
pub fn progress_bar(len: usize) -> ProgressBar {
let progress_bar = ProgressBar::new(len as u64).with_style(
ProgressStyle::with_template("{elapsed_precise} {wide_bar} {pos}/{len} ({eta})").unwrap(),
);
progress_bar.enable_steady_tick(Duration::new(0, 100000000));
progress_bar
}
pub fn max_per_row(arr: ArrayView2<f32>) -> Array1<f32> {
arr.axis_iter(Axis(0))
.map(|row| {
*row.into_iter()
.reduce(|a, b| {
let mut tmp = a;
if tmp < b {
tmp = b;
}
tmp
})
.unwrap()
})
.collect()
}
pub fn argsort_by<T, F>(data: &[T], compare: F) -> Vec<usize>
where
F: Fn(&T, &T) -> Ordering,
{
let mut indices: Vec<usize> = (0..data.len()).collect();
indices.sort_by(|&a, &b| compare(&data[a], &data[b]));
indices
}
pub fn argmax_by<T, F>(array: ArrayView1<T>, compare: F) -> usize
where
F: Fn(&T, &T) -> Ordering,
{
let mut idx_max = 0;
for i in 0..array.len() {
if compare(&array[i], &array[idx_max]).is_gt() {
idx_max = i;
}
}
idx_max
}
pub fn chipwhisperer_float_to_u16(x: f64) -> u16 {
debug_assert!((-0.5..=0.5).contains(&x));
((x + 1.) * 2048.) as u16
}