intervals_rs/
interval_seq.rs

1use std::cmp::Ordering;
2use std::fmt::{Debug, Display};
3use std::hash::Hash;
4
5use crate::{Interval, IntervalLimit, to_ordering};
6
7#[derive(Clone)]
8pub enum Ordered {
9  UpperLower {
10    inverse_lower: bool,
11    inverse_upper: bool,
12  },
13  LowerUpper {
14    inverse_lower: bool,
15    inverse_upper: bool,
16  },
17}
18
19impl Ordered {
20  fn lower_factor(&self) -> i8 {
21    match self {
22      Ordered::UpperLower { inverse_lower, .. } => {
23        if *inverse_lower {
24          -1
25        } else {
26          1
27        }
28      }
29      Ordered::LowerUpper { inverse_lower, .. } => {
30        if *inverse_lower {
31          -1
32        } else {
33          1
34        }
35      }
36    }
37  }
38  fn upper_factor(&self) -> i8 {
39    match self {
40      Ordered::UpperLower { inverse_upper, .. } => {
41        if *inverse_upper {
42          -1
43        } else {
44          1
45        }
46      }
47      Ordered::LowerUpper { inverse_upper, .. } => {
48        if *inverse_upper {
49          -1
50        } else {
51          1
52        }
53      }
54    }
55  }
56
57  pub fn compare<T>(&self, e1: &Interval<T>, e2: &Interval<T>) -> Ordering
58  where
59    T: Debug + Display + Clone + Hash + Eq + Ord + PartialEq + PartialOrd,
60  {
61    match self {
62      Ordered::UpperLower { .. } => {
63        if e1.is_empty() && e2.is_empty() {
64          Ordering::Equal
65        } else if e1.is_empty() {
66          Ordering::Less
67        } else if e2.is_empty() {
68          Ordering::Greater
69        } else {
70          let upper_comparance = e1.upper.partial_cmp(&e2.upper).unwrap();
71          let lower_comparance = e1.lower.partial_cmp(&e2.lower).unwrap();
72          if upper_comparance != Ordering::Equal {
73            to_ordering(upper_comparance as i8 * self.upper_factor())
74          } else {
75            to_ordering(lower_comparance as i8 * self.lower_factor())
76          }
77        }
78      }
79      Ordered::LowerUpper { .. } => {
80        if e1.is_empty() && e2.is_empty() {
81          Ordering::Equal
82        } else if e1.is_empty() {
83          Ordering::Greater
84        } else if e2.is_empty() {
85          Ordering::Less
86        } else {
87          let upper_comparance = e1.upper.partial_cmp(&e2.upper).unwrap();
88          let lower_comparance = e1.lower.partial_cmp(&e2.lower).unwrap();
89          if upper_comparance != Ordering::Equal {
90            to_ordering(upper_comparance as i8 + self.lower_factor())
91          } else {
92            to_ordering(lower_comparance as i8 * self.upper_factor())
93          }
94        }
95      }
96    }
97  }
98}
99
100/// A structure that represents an interval sequence (a sequence of multiple Intervals).
101pub struct IntervalSeq<T: Debug + Display + Clone + Hash + Eq + Ord + PartialEq + PartialOrd> {
102  /// interval sequence
103  intervals: Vec<Interval<T>>,
104  /// ordered
105  ordered: Ordered,
106}
107
108impl<T: Debug + Display + Clone + Hash + Eq + Ord + PartialEq + PartialOrd> IntervalSeq<T> {
109  /// Add an interval element to this interval sequence.
110  ///
111  /// - value: an interval
112  pub fn append(&mut self, value: &Interval<T>) {
113    self.intervals.push(value.clone());
114  }
115
116  /// Return whether the interval sequence are empty.
117  ///
118  /// return: true if the interval sequence are empty
119  pub fn is_empty(&self) -> bool {
120    self.intervals.is_empty()
121  }
122
123  /// Generate empty interval sequence.
124  ///
125  /// - return: `IntervalSeq`
126  pub fn empty() -> Self {
127    let intervals: Vec<Interval<T>> = vec![];
128    Self::new(intervals)
129  }
130
131  pub fn new(values: impl IntoIterator<Item = Interval<T>>) -> Self {
132    let mut intervals: Vec<Interval<T>> = vec![];
133    values.into_iter().for_each(|e| {
134      intervals.push(e);
135    });
136    Self {
137      intervals,
138      ordered: Ordered::UpperLower {
139        inverse_lower: true,
140        inverse_upper: false,
141      },
142    }
143  }
144
145  /// Return the smallest interval that encompasses all the element intervals.
146  ///
147  /// - return: the smallest interval that encompasses all the elemental intervals.
148  /// - panic: if none of the elements are present
149  pub fn extent(&self) -> Interval<T> {
150    if self.intervals.is_empty() {
151      panic!("self.interval is empty!")
152    }
153    let first = self.intervals.get(0).unwrap();
154    if self.intervals.len() == 1 {
155      first.clone()
156    } else {
157      let mut lowers = self
158        .intervals
159        .iter()
160        .map(|e| e.lower.clone())
161        .collect::<Vec<IntervalLimit<T>>>();
162      lowers.sort_by(|a, b| a.partial_cmp(&b).unwrap());
163      let lower = lowers.get(0).unwrap();
164      let mut uppers = self
165        .intervals
166        .iter()
167        .map(|e| e.upper.clone())
168        .collect::<Vec<IntervalLimit<T>>>();
169      uppers.sort_by(|a, b| b.partial_cmp(&a).unwrap());
170      let upper = uppers.get(0).unwrap();
171      first.new_of_same_type(
172        lower.as_value().clone(),
173        lower.is_closed(),
174        upper.as_value().clone(),
175        upper.is_closed(),
176      )
177    }
178  }
179
180  /// In the sorted intervals, return the intervals that are between adjacent intervals as the interval sequence.
181  ///
182  /// If the number of intervals is less than two, an empty sequence of intervals is returned.
183  /// If the intervals overlap or touch each other, the intervals are not included in the result element.
184  /// If all the intervals overlap, an empty interval sequence is returned.
185  ///
186  /// - return: gap interval sequence
187  pub fn gap(&self) -> Self {
188    if self.intervals.len() < 2 {
189      let values: Vec<Interval<T>> = vec![];
190      Self::new(values)
191    } else {
192      let mut values: Vec<Interval<T>> = vec![];
193      for i in 1usize..self.intervals.len() {
194        let left = &self.intervals[i - 1];
195        let right = &self.intervals[i];
196        let gap = left.gap(right);
197        if !gap.is_empty() {
198          values.push(gap);
199        }
200      }
201      Self::new(values)
202    }
203  }
204
205  /// Return the sorted intervals where adjacent intervals overlap each other as an interval sequence.
206  ///
207  /// If the number of intervals is less than two, an empty sequence of intervals is returned.
208  /// If the intervals do not overlap or are tangent to each other, the intervals are not included in the result element.
209  /// If all the intervals do not overlap, an empty interval sequence is returned.
210  ///
211  /// - return: common interval sequence
212  pub fn intersections(&self) -> Self {
213    if self.intervals.len() < 2 {
214      let values: Vec<Interval<T>> = vec![];
215      Self::new(values)
216    } else {
217      let mut values: Vec<Interval<T>> = vec![];
218      for i in 1usize..self.intervals.len() {
219        let left = &self.intervals[i - 1];
220        let right = &self.intervals[i];
221        let gap = left.intersect(right);
222        if !gap.is_empty() {
223          values.push(gap);
224        }
225      }
226      Self::new(values)
227    }
228  }
229
230  /// Gets an iterator of this interval sequence.
231  pub fn iter(&mut self) -> impl Iterator<Item = &Interval<T>> {
232    let mut l = self.intervals.clone();
233    l.sort_by(|a, b| self.ordered.compare(a, b));
234    self.intervals = l;
235    self.intervals.iter()
236  }
237
238  /// Gets an into iterator of this interval sequence.
239  pub fn into_iter(mut self) -> impl IntoIterator<Item = Interval<T>> {
240    let mut l = self.intervals.clone();
241    l.sort_by(|a, b| self.ordered.compare(a, b));
242    self.intervals = l;
243    self.intervals.into_iter()
244  }
245
246  /// Gets the len of this interval sequence.
247  pub fn len(&self) -> usize {
248    self.intervals.len()
249  }
250
251  /// Gets the interval in this interval sequence by index
252  pub fn get(&self, idx: usize) -> Option<&Interval<T>> {
253    self.intervals.get(idx)
254  }
255}