2021-07-26 09:39:57 -07:00
|
|
|
use nalgebra::{DMatrix, DVector};
|
|
|
|
|
|
|
|
|
|
pub struct Searcher<'a> {
|
|
|
|
|
pub counts: Vec<u64>,
|
|
|
|
|
maxes: &'a Vec<f64>,
|
|
|
|
|
generators: &'a Vec<DMatrix<f64>>,
|
2021-07-26 10:58:45 -07:00
|
|
|
max_depth: usize,
|
|
|
|
|
tolerance: f64,
|
2021-08-03 00:27:07 -07:00
|
|
|
faces: &'a Vec<Vec<usize>>,
|
2021-07-26 09:39:57 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a> Searcher<'a> {
|
2021-07-26 10:58:45 -07:00
|
|
|
pub fn new(
|
|
|
|
|
maxes: &'a Vec<f64>,
|
|
|
|
|
generators: &'a Vec<DMatrix<f64>>,
|
|
|
|
|
max_depth: usize,
|
|
|
|
|
n: u64,
|
2021-08-03 00:27:07 -07:00
|
|
|
faces: &'a Vec<Vec<usize>>,
|
2021-07-26 10:58:45 -07:00
|
|
|
) -> Self {
|
2021-07-26 09:39:57 -07:00
|
|
|
Self {
|
2021-07-26 10:58:45 -07:00
|
|
|
counts: vec![n; maxes.len()],
|
2021-07-26 09:39:57 -07:00
|
|
|
maxes,
|
|
|
|
|
generators,
|
2021-07-26 10:58:45 -07:00
|
|
|
max_depth,
|
2021-08-03 00:27:07 -07:00
|
|
|
tolerance: 1e-8,
|
|
|
|
|
faces,
|
2021-07-26 09:39:57 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-03 00:27:07 -07:00
|
|
|
pub fn search(
|
|
|
|
|
&mut self,
|
|
|
|
|
circle: &DVector<f64>,
|
|
|
|
|
seed: usize,
|
|
|
|
|
previous_generator: usize,
|
|
|
|
|
depth: usize,
|
|
|
|
|
) {
|
2021-07-26 10:58:45 -07:00
|
|
|
if self.max_depth > 0 && depth > self.max_depth {
|
2021-07-26 09:39:57 -07:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
for (i, generator) in self.generators.iter().enumerate() {
|
2021-08-03 00:27:07 -07:00
|
|
|
if depth == 0 {
|
|
|
|
|
for vertex in &self.faces[i] {
|
|
|
|
|
if *vertex == seed {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-07-26 09:39:57 -07:00
|
|
|
if i != previous_generator {
|
|
|
|
|
let new_circle = generator * circle;
|
2021-08-03 00:27:07 -07:00
|
|
|
if new_circle[1] - circle[1] <= self.tolerance {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2021-07-26 09:39:57 -07:00
|
|
|
{
|
|
|
|
|
let mut seen = false;
|
|
|
|
|
for (j, max) in self.maxes.iter().enumerate() {
|
2021-08-03 00:27:07 -07:00
|
|
|
if seen || new_circle[1] <= *max {
|
2021-07-26 09:39:57 -07:00
|
|
|
seen = true;
|
|
|
|
|
self.counts[j] += 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if !seen {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
} // ensure seen is dropped before recursive call to minimize stack frame size
|
2021-08-03 00:27:07 -07:00
|
|
|
self.search(&new_circle, seed, i, depth + 1);
|
2021-07-26 09:39:57 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|