use pounce_common::types::Number;
pub fn scaled_distance(a: &[Number], b: &[Number], l: &[Number]) -> Number {
let mut acc = 0.0;
for i in 0..a.len() {
let d = (a[i] - b[i]) / l[i];
acc += d * d;
}
acc.sqrt()
}
pub struct Archive {
dedup: Number,
l: Vec<Number>,
pub xs: Vec<Vec<Number>>,
pub fs: Vec<Number>,
}
impl Archive {
pub fn new(dedup: Number, l: Vec<Number>) -> Self {
Self {
dedup,
l,
xs: Vec::new(),
fs: Vec::new(),
}
}
pub fn len(&self) -> usize {
self.xs.len()
}
pub fn is_empty(&self) -> bool {
self.xs.is_empty()
}
pub fn is_known(&self, x: &[Number]) -> bool {
self.xs
.iter()
.any(|m| scaled_distance(x, m, &self.l) <= self.dedup)
}
pub fn near_any(&self, x: &[Number], radius: Number) -> bool {
self.xs
.iter()
.any(|m| scaled_distance(x, m, &self.l) <= radius)
}
pub fn add(&mut self, x: Vec<Number>, f: Number) {
self.xs.push(x);
self.fs.push(f);
}
pub fn order_by_objective(&self) -> Vec<usize> {
let mut idx: Vec<usize> = (0..self.fs.len()).collect();
idx.sort_by(|&a, &b| {
self.fs[a]
.partial_cmp(&self.fs[b])
.unwrap_or(std::cmp::Ordering::Equal)
});
idx
}
}