use faer::Mat;
use crate::KernelFunction;
#[inline(always)]
pub fn get_pointarray_extents<T>(points: &Mat<T>) -> Vec<T>
where
T: PartialOrd + Clone,
{
let ncols = points.shape().1;
let mut extents: Vec<T> = vec![points.get(0, 0).clone(); 2 * ncols];
for col in 0..ncols {
extents[col] = points.get(0, col).clone(); extents[col + ncols] = points.get(0, col).clone(); }
for row in points.row_iter() {
for (col, item) in row.iter().enumerate() {
if item < &extents[col] {
extents[col] = item.clone();
}
if item > &extents[col + ncols] {
extents[col + ncols] = item.clone();
}
}
}
extents
}
#[inline(always)]
pub fn select_mat_rows(existing_mat: &Mat<f64>, row_indices: &Vec<usize>) -> Mat<f64>
{
Mat::from_fn(row_indices.len(), existing_mat.ncols(), |i, j| {
existing_mat.get(row_indices[i], j).clone()
})
}
#[inline(always)]
pub fn get_a_matrix<K>(
target_points: &Mat<f64>,
source_points: &Mat<f64>,
kernel_function: &K,
) -> Mat<f64>
where
K: KernelFunction,
{
let m = target_points.shape().0;
let n = source_points.shape().0;
let mut a_matrix = Mat::<f64>::zeros(m, n);
for j in 0..n {
let source = source_points.row(j);
for i in 0..m {
let target = target_points.row(i);
a_matrix[(i, j)] = kernel_function.evaluate(target, source);
}
}
a_matrix
}
#[inline(always)]
pub fn get_a_matrix_subset<K>(
target_points: &Mat<f64>,
source_points: &Mat<f64>,
kernel_function: &K,
rows_start: &usize,
rows_end: &usize,
columns_start: &usize,
columns_end: &usize,
) -> Mat<f64>
where
K: KernelFunction,
{
let m = rows_end - rows_start;
let n = columns_end - columns_start;
let mut a_matrix = Mat::<f64>::zeros(m, n);
for j in 0..n {
let source = source_points.row(columns_start + j);
for i in 0..m {
let target = target_points.row(rows_start + i);
a_matrix[(i, j)] = kernel_function.evaluate(target, source);
}
}
a_matrix
}
#[inline(always)]
pub fn cartesian_product<T>(values: &[T], num_columns: usize) -> Mat<T>
where
T: Clone,
{
let base = values.len();
let total_rows = base.pow(num_columns as u32);
Mat::from_fn(total_rows, num_columns, |i, j| {
let index = (i / base.pow((num_columns - j - 1) as u32)) % base;
values[index].clone()
})
}
#[inline(always)]
pub fn argsort<T: PartialOrd>(data: &[T]) -> Vec<usize> {
let mut indices = (0..data.len()).collect::<Vec<_>>();
indices.sort_by(|&i, &j| data[i].partial_cmp(&data[j]).unwrap_or(std::cmp::Ordering::Equal));
indices
}