1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
use noisy_float::prelude::*;
use pyo3::prelude::*;
use rayon::slice::ParallelSliceMut;
use std::sync::Arc;
#[pyclass]
#[derive(Clone)]
pub struct Breakpoints {
pub bs: Vec<N64>,
#[allow(clippy::type_complexity)]
pub next:
Option<Arc<dyn Fn(f64) -> (Option<f64>, Option<f64>) + Send + Sync>>,
}
impl Breakpoints {
pub fn empty() -> Self {
Breakpoints {
bs: vec![],
next: None,
}
}
pub fn from(bs: Vec<f64>) -> Self {
Self::empty().add(&bs)
}
pub fn grid(d: f64) -> Self {
Breakpoints {
bs: vec![],
next: Some(Arc::new(move |b| {
(Some(b.ceil() - d), Some(b.floor() + d))
})),
}
}
pub fn add(&self, bs: &Vec<f64>) -> Self {
let new_bs = bs
.iter()
.filter(|&&b| !self.bs.contains(&n64(b)))
.map(|&b| n64(b));
let mut breakpoints = self.clone();
breakpoints.bs.extend(new_bs);
breakpoints.bs.par_sort_unstable();
breakpoints
}
}
impl Default for Breakpoints {
fn default() -> Self {
Breakpoints::empty()
}
}
#[pymethods]
impl Breakpoints {
#[new]
fn constructor(bs: Vec<f64>) -> Self {
Breakpoints::from(bs)
}
}