1use crate::generic::{Contain, Displacement, MinDist, Overlap};
2
3use std::cmp::{Eq, PartialEq, PartialOrd};
4use std::fmt::{Display, Formatter, Result as FmtResult};
5use std::marker::PhantomData;
6use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
29#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
30pub struct Interval<T> {
31 pub lb: T,
32 pub ub: T,
33 pub _marker: PhantomData<T>,
34}
35
36impl<T> Interval<T> {
37 #[inline]
56 pub const fn new(lb: T, ub: T) -> Self {
57 Self {
58 lb,
59 ub,
60 _marker: PhantomData,
61 }
62 }
63}
64
65impl<T: Copy> Interval<T> {
66 #[inline]
68 pub const fn lb(&self) -> T {
69 self.lb
70 }
71
72 #[inline]
74 pub const fn ub(&self) -> T {
75 self.ub
76 }
77}
78
79impl<T: PartialOrd> Interval<T> {
80 #[inline]
94 pub fn is_invalid(&self) -> bool {
95 self.lb > self.ub
96 }
97}
98
99impl<T: Copy + Sub<Output = T>> Interval<T> {
100 #[inline]
116 pub fn length(&self) -> T {
117 self.ub - self.lb
118 }
119}
120
121impl<T> Display for Interval<T>
122where
123 T: PartialOrd + Copy + Display,
124{
125 #[inline]
127 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
128 write!(f, "[{}, {}]", self.lb, self.ub)
129 }
130}
131
132impl<T: Sub<Output = T>> Sub for Interval<T> {
134 type Output = Self;
135
136 fn sub(self, other: Self) -> Self::Output {
137 Self {
138 lb: self.lb - other.lb,
139 ub: self.ub - other.ub,
140 _marker: PhantomData,
141 }
142 }
143}
144
145impl<T> Neg for Interval<T>
147where
148 T: Copy + Neg<Output = T>,
149{
150 type Output = Interval<T>;
151
152 #[inline]
153 fn neg(self) -> Self::Output {
154 Interval {
155 lb: -self.ub,
156 ub: -self.lb,
157 _marker: self._marker,
158 }
159 }
160}
161
162impl<T> AddAssign<T> for Interval<T>
163where
164 T: Copy + AddAssign<T>,
165{
166 #[inline]
168 fn add_assign(&mut self, rhs: T) {
169 self.lb += rhs;
170 self.ub += rhs;
171 }
172}
173
174impl<T> Add<T> for Interval<T>
175where
176 T: Copy + Add<Output = T>,
177{
178 type Output = Interval<T>;
179
180 #[inline]
182 fn add(self, rhs: T) -> Self::Output {
183 Interval {
184 lb: self.lb + rhs,
185 ub: self.ub + rhs,
186 _marker: self._marker,
187 }
188 }
189}
190
191impl<T> SubAssign<T> for Interval<T>
192where
193 T: Copy + SubAssign<T>,
194{
195 #[inline]
197 fn sub_assign(&mut self, rhs: T) {
198 self.lb -= rhs;
199 self.ub -= rhs;
200 }
201}
202
203impl<T: Add<Output = T>> Add for Interval<T> {
205 type Output = Self;
206
207 fn add(self, other: Self) -> Self::Output {
208 Self {
209 lb: self.lb + other.lb,
210 ub: self.ub + other.ub,
211 _marker: PhantomData,
212 }
213 }
214}
215
216impl<T> Sub<T> for Interval<T>
217where
218 T: Copy + Sub<Output = T>,
219{
220 type Output = Interval<T>;
221
222 #[inline]
224 fn sub(self, rhs: T) -> Self::Output {
225 Interval {
226 lb: self.lb - rhs,
227 ub: self.ub - rhs,
228 _marker: self._marker,
229 }
230 }
231}
232
233impl<T> MulAssign<T> for Interval<T>
234where
235 T: Copy + MulAssign<T>,
236{
237 #[inline]
239 fn mul_assign(&mut self, rhs: T) {
240 self.lb *= rhs;
241 self.ub *= rhs;
242 }
243}
244
245impl<T> Mul<T> for Interval<T>
246where
247 T: Copy + Mul<Output = T>,
248{
249 type Output = Interval<T>;
250
251 #[inline]
253 fn mul(self, rhs: T) -> Self::Output {
254 Interval {
255 lb: self.lb * rhs,
256 ub: self.ub * rhs,
257 _marker: self._marker,
258 }
259 }
260}
261
262pub trait Enlarge<Alpha> {
264 type Output;
265
266 fn enlarge_with(&self, alpha: Alpha) -> Self::Output;
267}
268
269impl Enlarge<i32> for i32 {
270 type Output = Interval<i32>;
271
272 #[inline]
274 fn enlarge_with(&self, alpha: i32) -> Interval<i32> {
275 Interval {
276 lb: *self - alpha,
277 ub: *self + alpha,
278 _marker: PhantomData,
279 }
280 }
281}
282
283impl<T> Enlarge<T> for Interval<T>
284where
285 T: Copy + Add<Output = T> + Sub<Output = T>,
286{
287 type Output = Interval<T>;
288
289 #[inline]
291 fn enlarge_with(&self, alpha: T) -> Self {
292 Interval {
293 lb: self.lb - alpha,
294 ub: self.ub + alpha,
295 _marker: self._marker,
296 }
297 }
298}
299
300impl<T: PartialOrd> PartialOrd for Interval<T> {
301 #[inline]
311 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
312 if self.ub < other.lb {
313 Some(std::cmp::Ordering::Less)
314 } else if other.ub < self.lb {
315 Some(std::cmp::Ordering::Greater)
316 } else {
317 Some(std::cmp::Ordering::Equal)
318 }
319 }
320}
321
322impl<T: PartialOrd> Overlap<Interval<T>> for Interval<T> {
323 #[inline]
325 fn overlaps(&self, other: &Interval<T>) -> bool {
326 self.ub >= other.lb && other.ub >= self.lb
327 }
328}
329
330impl<T: PartialOrd> Overlap<T> for Interval<T> {
331 #[inline]
333 fn overlaps(&self, other: &T) -> bool {
334 self.ub >= *other && *other >= self.lb
335 }
336}
337
338impl<T: PartialOrd> Overlap<Interval<T>> for T {
339 #[inline]
341 fn overlaps(&self, other: &Interval<T>) -> bool {
342 *self >= other.lb && other.ub >= *self
343 }
344}
345
346impl<T: PartialOrd> Contain<Interval<T>> for Interval<T> {
347 #[inline]
349 fn contains(&self, other: &Interval<T>) -> bool {
350 self.lb <= other.lb && other.ub <= self.ub
351 }
352}
353
354impl<T: PartialOrd> Contain<T> for Interval<T> {
355 #[inline]
357 fn contains(&self, other: &T) -> bool {
358 self.lb <= *other && *other <= self.ub
359 }
360}
361
362impl<T: PartialOrd> Contain<Interval<T>> for T {
363 #[inline]
375 fn contains(&self, _other: &Interval<T>) -> bool {
376 false
377 }
378}
379
380impl<T> Displacement<Interval<T>> for Interval<T>
381where
382 T: Displacement<T, Output = T>,
383{
384 type Output = Interval<T>;
385
386 #[inline]
388 fn displace(&self, other: &Interval<T>) -> Self::Output {
389 Self::Output::new(self.lb.displace(&other.lb), self.ub.displace(&other.ub))
390 }
391}
392
393impl MinDist<Interval<i32>> for Interval<i32> {
394 #[inline]
398 fn min_dist_with(&self, other: &Interval<i32>) -> u32 {
399 if self.ub < other.lb {
400 (other.lb - self.ub) as u32
401 } else if other.ub < self.lb {
402 (self.lb - other.ub) as u32
403 } else {
404 0
405 }
406 }
407}
408
409impl MinDist<i32> for Interval<i32> {
410 #[inline]
412 fn min_dist_with(&self, other: &i32) -> u32 {
413 if self.ub < *other {
414 (*other - self.ub) as u32
415 } else if *other < self.lb {
416 (self.lb - *other) as u32
417 } else {
418 0
419 }
420 }
421}
422
423impl MinDist<Interval<i32>> for i32 {
424 #[inline]
426 fn min_dist_with(&self, other: &Interval<i32>) -> u32 {
427 if *self < other.lb {
428 (other.lb - *self) as u32
429 } else if other.ub < *self {
430 (*self - other.ub) as u32
431 } else {
432 0
433 }
434 }
435}
436
437pub trait Hull<T: ?Sized> {
439 type Output;
440
441 fn hull_with(&self, other: &T) -> Self::Output;
442}
443
444impl Hull<i32> for i32 {
445 type Output = Interval<i32>;
446
447 #[inline]
449 fn hull_with(&self, other: &i32) -> Self::Output {
450 if *self < *other {
451 Interval::new(*self, *other)
452 } else {
453 Interval::new(*other, *self)
454 }
455 }
456}
457
458impl<T> Hull<Interval<T>> for Interval<T>
459where
460 T: Copy + Ord,
461{
462 type Output = Interval<T>;
463
464 #[inline]
468 fn hull_with(&self, other: &Interval<T>) -> Self::Output {
469 Self::Output {
470 lb: self.lb.min(other.lb),
471 ub: self.ub.max(other.ub),
472 _marker: self._marker,
473 }
474 }
475}
476
477impl<T> Hull<T> for Interval<T>
478where
479 T: Copy + Ord,
480{
481 type Output = Interval<T>;
482
483 #[inline]
491 fn hull_with(&self, other: &T) -> Self::Output {
492 Self::Output {
493 lb: self.lb.min(*other),
494 ub: self.ub.max(*other),
495 _marker: self._marker,
496 }
497 }
498}
499
500impl<T> Hull<Interval<T>> for T
501where
502 T: Copy + Ord,
503{
504 type Output = Interval<T>;
505
506 #[inline]
508 fn hull_with(&self, other: &Interval<T>) -> Self::Output {
509 other.hull_with(self)
510 }
511}
512
513pub trait Intersect<T: ?Sized> {
515 type Output;
516
517 fn intersect_with(&self, other: &T) -> Self::Output;
518}
519
520impl Intersect<i32> for i32 {
521 type Output = Interval<i32>;
522
523 #[inline]
525 fn intersect_with(&self, other: &i32) -> Self::Output {
526 Self::Output {
527 lb: (*self).max(*other),
528 ub: (*self).min(*other),
529 _marker: PhantomData,
530 }
531 }
532}
533
534impl<T> Intersect<Interval<T>> for Interval<T>
535where
536 T: Copy + Ord,
537{
538 type Output = Interval<T>;
539
540 #[inline]
544 fn intersect_with(&self, other: &Interval<T>) -> Self::Output {
545 Self::Output {
546 lb: self.lb.max(other.lb),
547 ub: self.ub.min(other.ub),
548 _marker: self._marker,
549 }
550 }
551}
552
553impl<T> Intersect<T> for Interval<T>
554where
555 T: Copy + Ord,
556{
557 type Output = Interval<T>;
558
559 #[inline]
561 fn intersect_with(&self, other: &T) -> Self::Output {
562 Self::Output {
563 lb: self.lb.max(*other),
564 ub: self.ub.min(*other),
565 _marker: self._marker,
566 }
567 }
568}
569
570impl<T> Intersect<Interval<T>> for T
571where
572 T: Copy + Ord,
573{
574 type Output = Interval<T>;
575
576 #[inline]
578 fn intersect_with(&self, other: &Interval<T>) -> Self::Output {
579 other.intersect_with(self)
580 }
581}
582
583#[cfg(test)]
584mod tests {
585 use super::*;
586
587 #[test]
588 fn test_interval() {
589 let interval_a = Interval::new(4, 8);
590 let interval_b = Interval::new(5, 6);
591
592 assert!(interval_a <= interval_b);
593 assert!(interval_b <= interval_a);
594 assert!(interval_a >= interval_b);
595 assert!(interval_b >= interval_a);
596
597 assert!(interval_a.overlaps(&interval_b));
598 assert!(interval_b.overlaps(&interval_a));
599 assert!(interval_a.contains(&4));
601 assert!(interval_a.contains(&8));
602 assert!(interval_a.contains(&interval_b));
603 assert_eq!(interval_a, interval_a);
604 assert_eq!(interval_b, interval_b);
605 assert_ne!(interval_a, interval_b);
606 assert_ne!(interval_b, interval_a);
607 assert!(interval_a.overlaps(&interval_a));
608 assert!(interval_b.overlaps(&interval_b));
609 assert!(interval_a.contains(&interval_a));
610 assert!(interval_b.contains(&interval_b));
611 assert!(interval_a.overlaps(&interval_b));
612 assert!(interval_b.overlaps(&interval_a));
613 }
614
615 #[test]
616 fn test_hull_more_cases() {
617 let interval_a = Interval::new(3, 5);
618 let interval_b = Interval::new(1, 7);
619 assert_eq!(interval_a.hull_with(&interval_b), Interval::new(1, 7));
620
621 let interval_c = Interval::new(-2, 2);
622 assert_eq!(interval_a.hull_with(&interval_c), Interval::new(-2, 5));
623
624 let val_d = 4;
625 assert_eq!(interval_a.hull_with(&val_d), Interval::new(3, 5));
626
627 let val_e = 8;
628 assert_eq!(interval_a.hull_with(&val_e), Interval::new(3, 8));
629
630 let val_f = 0;
631 assert_eq!(interval_a.hull_with(&val_f), Interval::new(0, 5));
632 }
633
634 #[test]
635 fn test_interval1() {
636 let interval_a = Interval::new(4, 5);
637 let interval_b = Interval::new(6, 8);
638 assert!(interval_a < interval_b);
639 assert!(!(interval_b == interval_a));
640 assert!(interval_b != interval_a);
641 }
642
643 #[test]
644 fn test_interval2() {
645 let interval_a = Interval::new(4, 8);
646 let interval_b = Interval::new(5, 6);
647
648 assert!(interval_a.contains(&4));
649 assert!(interval_a.contains(&8));
650 assert!(interval_a.contains(&interval_b));
651 assert!(!interval_b.contains(&interval_a));
654 assert!(interval_a.overlaps(&interval_b));
655 assert!(interval_b.overlaps(&interval_a));
656 }
657
658 #[test]
659 fn test_interval3() {
660 let interval_a = Interval::new(3, 4);
661 assert!(interval_a.lb == 3);
662 assert!(interval_a.ub == 4);
663 assert!(interval_a.contains(&3));
665 assert!(interval_a.contains(&4));
666 assert!(!interval_a.contains(&5));
667 assert!(interval_a.contains(&Interval::new(3, 4)));
668 assert!(!interval_a.contains(&Interval::new(3, 5)));
669 assert!(!interval_a.contains(&Interval::new(2, 3)));
670 assert!(!interval_a.contains(&2));
671 assert!(interval_a.contains(&4));
672 assert!(!interval_a.contains(&5));
673 }
674
675 #[test]
676 fn test_arithmetic() {
677 let mut interval_a = Interval::new(3, 5);
678 assert_eq!(interval_a + 1, Interval::new(4, 6));
681 assert_eq!(interval_a - 1, Interval::new(2, 4));
682 assert_eq!(interval_a * 2, Interval::new(6, 10));
683 assert!(-interval_a == Interval::new(-5, -3));
684 interval_a += 1;
685 assert!(interval_a == Interval::new(4, 6));
686 interval_a -= 1;
687 assert!(interval_a == Interval::new(3, 5));
688 interval_a *= 2;
689 assert!(interval_a == Interval::new(6, 10));
690 }
691
692 #[test]
693 fn test_overlap() {
694 let interval_a = Interval::new(3, 5);
695 let interval_b = Interval::new(5, 7);
696 let interval_c = Interval::new(7, 8);
697 assert!(interval_a.overlaps(&interval_b));
698 assert!(interval_b.overlaps(&interval_c));
699 assert!(!interval_a.overlaps(&interval_c));
700 assert!(!interval_c.overlaps(&interval_a));
701
702 let val_d = 4;
703 assert!(interval_a.overlaps(&val_d));
704 assert!(!interval_a.overlaps(&6));
705 assert!(val_d.overlaps(&interval_a));
706 assert!(val_d.overlaps(&val_d));
707 }
708
709 #[test]
710 fn test_contains() {
711 let interval_a = Interval::new(3, 5);
712 let interval_b = Interval::new(5, 7);
713 let interval_c = Interval::new(7, 8);
714 assert!(!interval_a.contains(&interval_b));
715 assert!(!interval_b.contains(&interval_c));
716 assert!(!interval_a.contains(&interval_c));
717 assert!(!interval_c.contains(&interval_a));
718
719 let val_d = 4;
720 assert!(interval_a.contains(&val_d));
721 assert!(!interval_a.contains(&6));
722 assert!(!val_d.contains(&interval_a));
723 assert!(val_d.contains(&val_d));
724 }
725
726 #[test]
727 fn test_intersect() {
728 let interval_a = Interval::new(3, 5);
729 let interval_b = Interval::new(5, 7);
730 let interval_c = Interval::new(7, 8);
731 assert_eq!(interval_a.intersect_with(&interval_b), Interval::new(5, 5));
732 assert_eq!(interval_b.intersect_with(&interval_c), Interval::new(7, 7));
733 assert!(interval_a.intersect_with(&interval_c).is_invalid());
734 assert_eq!(interval_a.intersect_with(&interval_b), Interval::new(5, 5));
735 assert_eq!(interval_b.intersect_with(&interval_c), Interval::new(7, 7));
736 let val_d = 4;
737 assert_eq!(interval_a.intersect_with(&val_d), Interval::new(4, 4));
738 assert!(interval_a.intersect_with(&6).is_invalid());
739 assert_eq!(interval_a.intersect_with(&val_d), Interval::new(4, 4));
740 assert_eq!(val_d.intersect_with(&interval_a), Interval::new(4, 4));
741 assert_eq!(val_d.intersect_with(&val_d), Interval::new(4, 4));
742 }
743
744 #[test]
745 fn test_hull() {
746 let interval_a = Interval::new(3, 5);
747 let interval_b = Interval::new(5, 7);
748 let interval_c = Interval::new(7, 8);
749 assert_eq!(interval_a.hull_with(&interval_b), Interval::new(3, 7));
750 assert_eq!(interval_b.hull_with(&interval_c), Interval::new(5, 8));
751 assert_eq!(interval_a.hull_with(&interval_c), Interval::new(3, 8));
752 let val_d = 4;
753 assert_eq!(interval_a.hull_with(&val_d), Interval::new(3, 5));
754 assert_eq!(interval_a.hull_with(&6), Interval::new(3, 6));
755 }
761
762 #[test]
763 fn test_min_dist() {
764 let interval_a = Interval::new(3, 5);
765 let interval_b = Interval::new(5, 7);
766 let interval_c = Interval::new(7, 8);
767 assert_eq!(interval_a.min_dist_with(&interval_b), 0);
768 assert_eq!(interval_a.min_dist_with(&interval_c), 2);
769 assert_eq!(interval_b.min_dist_with(&interval_c), 0);
770 let val_d = 4;
771 assert_eq!(interval_a.min_dist_with(&val_d), 0);
772 assert_eq!(val_d.min_dist_with(&interval_a), 0);
773 assert_eq!(interval_a.min_dist_with(&6), 1);
774 assert_eq!(6.min_dist_with(&interval_a), 1);
775 }
776
777 #[test]
778 fn test_displacement() {
779 let interval_a = Interval::new(3, 5);
780 let interval_b = Interval::new(5, 7);
781 let interval_c = Interval::new(7, 8);
782 assert_eq!(interval_a.displace(&interval_b), Interval::new(-2, -2));
783 assert_eq!(interval_a.displace(&interval_c), Interval::new(-4, -3));
784 assert_eq!(interval_b.displace(&interval_c), Interval::new(-2, -1));
785 let val_d = 4;
786 assert_eq!(val_d.displace(&val_d), 0);
787 assert_eq!(val_d.displace(&6), -2);
788 assert_eq!(6.displace(&val_d), 2);
789 }
790
791 #[test]
792 fn test_enlarge() {
793 let interval_a = Interval::new(3, 5);
794 assert!(interval_a.enlarge_with(2) == Interval::new(1, 7));
795 let val_d = 4;
796 assert_eq!(val_d.enlarge_with(6), Interval::new(-2, 10));
797 assert_eq!(6.enlarge_with(val_d), Interval::new(2, 10));
798 }
799
800 #[test]
801 fn test_min_dist_with_interval_other_ub_less_self_lb() {
802 use crate::generic::MinDist;
803 let a = Interval::new(10, 20);
804 let b = Interval::new(0, 5);
805 assert_eq!(a.min_dist_with(&b), 5);
806 }
807
808 #[test]
809 fn test_min_dist_with_scalar_other_less_self_lb() {
810 use crate::generic::MinDist;
811 let a = Interval::new(10, 20);
812 assert_eq!(a.min_dist_with(&5), 5);
813 }
814
815 #[test]
816 fn test_min_dist_with_scalar_self_less_interval_lb() {
817 let val = 3;
818 let other = Interval::new(10, 20);
819 assert_eq!(val.min_dist_with(&other), 7);
820 }
821}
822
823#[test]
824fn test_interval_length() {
825 let interval = Interval::new(3, 8);
826 assert_eq!(interval.length(), 5);
827
828 let interval2 = Interval::new(-2, 3);
829 assert_eq!(interval2.length(), 5);
830}
831
832#[test]
833fn test_interval_display() {
834 let interval = Interval::new(3, 8);
835 let display_str = format!("{}", interval);
836 assert_eq!(display_str, "[3, 8]");
837
838 let interval2 = Interval::new(-5, 10);
839 let display_str2 = format!("{}", interval2);
840 assert_eq!(display_str2, "[-5, 10]");
841}
842
843#[test]
844fn test_interval_sub_interval() {
845 let interval_a = Interval::new(5, 10);
846 let interval_b = Interval::new(2, 3);
847 let result = interval_a - interval_b;
848 assert_eq!(result, Interval::new(3, 7));
849}
850
851#[test]
852fn test_interval_add_interval() {
853 let interval_a = Interval::new(1, 3);
854 let interval_b = Interval::new(2, 5);
855 let result = interval_a + interval_b;
856 assert_eq!(result, Interval::new(3, 8));
857}
858
859#[test]
860fn test_interval_is_invalid() {
861 let valid_interval = Interval::new(1, 5);
862 assert!(!valid_interval.is_invalid());
863
864 let invalid_interval = Interval::new(5, 1);
865 assert!(invalid_interval.is_invalid());
866}
867
868#[test]
869fn test_interval_sub_assign_interval() {
870 let mut interval = Interval::new(10, 20);
871 interval -= 3;
872 assert_eq!(interval, Interval::new(7, 17));
873}
874
875#[test]
876fn test_interval_hull_t_for_t() {
877 let val = 5;
878 let interval = Interval::new(3, 8);
879 let result = val.hull_with(&interval);
881 assert_eq!(result.lb, 3);
882 assert_eq!(result.ub, 8);
883}
884
885#[test]
886fn test_interval_contains_interval_t() {
887 let interval = Interval::new(3, 8);
888 let val = 5;
890 assert!(!val.contains(&interval));
891}
892
893#[test]
894fn test_interval_overlap_interval_t() {
895 let val = 5;
897 let interval = Interval::new(3, 8);
898 assert!(val.overlaps(&interval));
899
900 let val2 = 10;
901 assert!(!val2.overlaps(&interval));
902}
903
904#[test]
905fn test_interval_partial_cmp_greater() {
906 let interval_a = Interval::new(8, 10);
907 let interval_b = Interval::new(3, 5);
908 let cmp = interval_a.partial_cmp(&interval_b);
910 assert_eq!(cmp, Some(std::cmp::Ordering::Greater));
911}