| 54 fn new() -> Self { |
53 fn new() -> Self { |
| 55 NullAggregator |
54 NullAggregator |
| 56 } |
55 } |
| 57 } |
56 } |
| 58 |
57 |
| 59 /// Upper and lower bounds on an `F`-valued function. |
|
| 60 #[derive(Copy, Clone, Debug)] |
|
| 61 pub struct Bounds<F>( |
|
| 62 /// Lower bound |
|
| 63 pub F, |
|
| 64 /// Upper bound |
|
| 65 pub F, |
|
| 66 ); |
|
| 67 |
|
| 68 impl<F: Copy> Bounds<F> { |
|
| 69 /// Returns the lower bound |
|
| 70 #[inline] |
|
| 71 pub fn lower(&self) -> F { |
|
| 72 self.0 |
|
| 73 } |
|
| 74 |
|
| 75 /// Returns the upper bound |
|
| 76 #[inline] |
|
| 77 pub fn upper(&self) -> F { |
|
| 78 self.1 |
|
| 79 } |
|
| 80 } |
|
| 81 |
|
| 82 impl<F: Float> Bounds<F> { |
|
| 83 /// Returns a uniform bound. |
|
| 84 /// |
|
| 85 /// This is maximum over the absolute values of the upper and lower bound. |
|
| 86 #[inline] |
|
| 87 pub fn uniform(&self) -> F { |
|
| 88 let &Bounds(lower, upper) = self; |
|
| 89 lower.abs().max(upper.abs()) |
|
| 90 } |
|
| 91 |
|
| 92 /// Construct a bounds, making sure `lower` bound is less than `upper` |
|
| 93 #[inline] |
|
| 94 pub fn corrected(lower: F, upper: F) -> Self { |
|
| 95 if lower <= upper { |
|
| 96 Bounds(lower, upper) |
|
| 97 } else { |
|
| 98 Bounds(upper, lower) |
|
| 99 } |
|
| 100 } |
|
| 101 |
|
| 102 /// Refine the lower bound |
|
| 103 #[inline] |
|
| 104 pub fn refine_lower(&self, lower: F) -> Self { |
|
| 105 let &Bounds(l, u) = self; |
|
| 106 debug_assert!(l <= u); |
|
| 107 Bounds(l.max(lower), u.max(lower)) |
|
| 108 } |
|
| 109 |
|
| 110 /// Refine the lower bound |
|
| 111 #[inline] |
|
| 112 pub fn refine_upper(&self, upper: F) -> Self { |
|
| 113 let &Bounds(l, u) = self; |
|
| 114 debug_assert!(l <= u); |
|
| 115 Bounds(l.min(upper), u.min(upper)) |
|
| 116 } |
|
| 117 } |
|
| 118 |
|
| 119 impl<'a, F: Float> std::ops::Add<Self> for Bounds<F> { |
|
| 120 type Output = Self; |
|
| 121 #[inline] |
|
| 122 fn add(self, Bounds(l2, u2): Self) -> Self::Output { |
|
| 123 let Bounds(l1, u1) = self; |
|
| 124 debug_assert!(l1 <= u1 && l2 <= u2); |
|
| 125 Bounds(l1 + l2, u1 + u2) |
|
| 126 } |
|
| 127 } |
|
| 128 |
|
| 129 impl<'a, F: Float> std::ops::Mul<Self> for Bounds<F> { |
|
| 130 type Output = Self; |
|
| 131 #[inline] |
|
| 132 fn mul(self, Bounds(l2, u2): Self) -> Self::Output { |
|
| 133 let Bounds(l1, u1) = self; |
|
| 134 debug_assert!(l1 <= u1 && l2 <= u2); |
|
| 135 let a = l1 * l2; |
|
| 136 let b = u1 * u2; |
|
| 137 // The order may flip when negative numbers are involved, so need min/max |
|
| 138 Bounds(a.min(b), a.max(b)) |
|
| 139 } |
|
| 140 } |
|
| 141 |
|
| 142 impl<F: Float> std::iter::Product for Bounds<F> { |
|
| 143 #[inline] |
|
| 144 fn product<I>(mut iter: I) -> Self |
|
| 145 where |
|
| 146 I: Iterator<Item = Self>, |
|
| 147 { |
|
| 148 match iter.next() { |
|
| 149 None => Bounds(F::ZERO, F::ZERO), |
|
| 150 Some(init) => iter.fold(init, |a, b| a * b), |
|
| 151 } |
|
| 152 } |
|
| 153 } |
|
| 154 |
|
| 155 impl<F: Float> Set<F> for Bounds<F> { |
|
| 156 fn contains<I: Instance<F>>(&self, item: I) -> bool { |
|
| 157 let v = item.own(); |
|
| 158 let &Bounds(l, u) = self; |
|
| 159 debug_assert!(l <= u); |
|
| 160 l <= v && v <= u |
|
| 161 } |
|
| 162 } |
|
| 163 |
|
| 164 impl<F: Float> Bounds<F> { |
|
| 165 /// Calculate a common bound (glb, lub) for two bounds. |
|
| 166 #[inline] |
|
| 167 pub fn common(&self, &Bounds(l2, u2): &Self) -> Self { |
|
| 168 let &Bounds(l1, u1) = self; |
|
| 169 debug_assert!(l1 <= u1 && l2 <= u2); |
|
| 170 Bounds(l1.min(l2), u1.max(u2)) |
|
| 171 } |
|
| 172 |
|
| 173 /// Indicates whether `Self` is a superset of the argument bound. |
|
| 174 #[inline] |
|
| 175 pub fn superset(&self, &Bounds(l2, u2): &Self) -> bool { |
|
| 176 let &Bounds(l1, u1) = self; |
|
| 177 debug_assert!(l1 <= u1 && l2 <= u2); |
|
| 178 l1 <= l2 && u2 <= u1 |
|
| 179 } |
|
| 180 |
|
| 181 /// Returns the greatest bound contained by both argument bounds, if one exists. |
|
| 182 #[inline] |
|
| 183 pub fn glb(&self, &Bounds(l2, u2): &Self) -> Option<Self> { |
|
| 184 let &Bounds(l1, u1) = self; |
|
| 185 debug_assert!(l1 <= u1 && l2 <= u2); |
|
| 186 let l = l1.max(l2); |
|
| 187 let u = u1.min(u2); |
|
| 188 debug_assert!(l <= u); |
|
| 189 if l < u { |
|
| 190 Some(Bounds(l, u)) |
|
| 191 } else { |
|
| 192 None |
|
| 193 } |
|
| 194 } |
|
| 195 } |
|
| 196 |
|
| 197 impl<F: Float> Aggregator for Bounds<F> { |
58 impl<F: Float> Aggregator for Bounds<F> { |
| 198 #[inline] |
59 #[inline] |
| 199 fn aggregate<I>(&mut self, aggregates: I) |
60 fn aggregate<I>(&mut self, aggregates: I) |
| 200 where |
61 where |
| 201 I: Iterator<Item = Self>, |
62 I: Iterator<Item = Self>, |