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