1extern crate rayon;
2
3use rayon::prelude::*;
4
5use std::{
6 fs::File,
7 io::Write
8};
9
10use crate::{
11 point::Point,
12 tmspace::TimetricSpace
13};
14
15pub struct Sensor {
16 p: Point,
17 t: f64
18}
19
20impl Sensor {
21 pub fn make(p: &Point, t: f64) -> Self {
22 Self{p: p.clone(), t}
23 }
24}
25
26fn defect_compare_le(tmsp: &impl TimetricSpace, sensorium: &Vec<Sensor>, x: &Point, thres: f64) -> bool {
31 let mut bt_min = f64::MAX;
32 let mut bt_max = f64::MIN;
33 for r in sensorium.iter() {
34 let bt = r.t - tmsp.btau(r.t, x, & r.p);
35 bt_min = bt_min.min(bt);
36 bt_max = bt_max.max(bt);
37 if (bt_max - bt_min) > thres {
38 return false
39 }
40 }
41 true
42}
43
44pub fn rcd(tmsp: &impl TimetricSpace, sensorium: &Vec<Sensor>, anchor0: &Point, radius0: f64, precision: f64, dup_thres: f64, log: bool) -> Result<Point, String> {
46 let mut k: usize = 0;
48 let mut r: f64 = radius0;
49 let mut cover_anchors = vec![anchor0.clone()];
50 let mut z: Point;
51 loop {
52 let next_cover_anchors = cover_anchors.par_iter().map(|a| tmsp.make_rc_anchors(a, r).into_par_iter()).flatten()
54 .filter(|a| defect_compare_le(tmsp, sensorium, a, r)).collect::<Vec<Point>>();
55 if next_cover_anchors.len() == 0 {
56 break Err(format!("cover became empty"));
57 }
58
59 cover_anchors.clear();
61 for c in next_cover_anchors.iter() {
62 let mut dup: bool = false;
63 for uc in cover_anchors.iter() {
64 if tmsp.rho(c, uc) < dup_thres / tmsp.beta() {
65 dup = true;
66 break;
67 }
68 }
69 if !dup {
70 cover_anchors.push(c.clone());
71 }
72 }
73
74 z = cover_anchors[cover_anchors.len() >> 1].clone();
76
77 k += 1;
79 r *= 0.5;
80
81 let d = r + tmsp.beta() * cover_anchors.iter().fold(0f64, |max, a| max.max(tmsp.rho(&z, a)));
82 println!("Iteration {}: {} coverands, d = {:.4}", k, cover_anchors.len(), d);
83
84 if log {
85 let mut logfile = File::create(format!("iter_{}.log", k)).map_err(|e| e.to_string())?;
86 write!(&mut logfile, "{}\n{}\n{}\n{}\n", d, tmsp.dim(), r, cover_anchors.len()).map_err(|e| e.to_string())?;
87 for a in cover_anchors.iter() {
88 for c in a.coords().iter() {
89 writeln!(&mut logfile, "{}", c).map_err(|e| e.to_string())?;
90 }
91 }
92 logfile.flush().map_err(|e| e.to_string())?;
93 }
94
95 if d < precision {
96 break Ok(z);
97 }
98 }
99}