MinMaxMapping default implementations dev

Thu, 01 May 2025 15:32:10 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Thu, 01 May 2025 15:32:10 -0500
branch
dev
changeset 126
0ccad3ee8e95
parent 125
25b6c8b20d1b
child 127
212f75931da0
child 141
1a0c29c397ab

MinMaxMapping default implementations

src/bounds.rs file | annotate | diff | comparison | revisions
--- a/src/bounds.rs	Thu May 01 14:53:14 2025 -0500
+++ b/src/bounds.rs	Thu May 01 15:32:10 2025 -0500
@@ -57,7 +57,7 @@
 
 impl<F: Float, T: GlobalAnalysis<F, Bounds<F>>> Bounded<F> for T {}
 
-/// A [`RealMapping`] that provides rough bounds as well as minimisation and maximisation.
+/// A real-valued [`Mapping`] that provides rough bounds as well as minimisation and maximisation.
 pub trait MinMaxMapping<Domain: Space, F: Float = f64>:
     Mapping<Domain, Codomain = F> + Bounded<F>
 {
@@ -72,7 +72,10 @@
     /// At most `max_steps` refinement steps are taken.
     /// Returns the approximate maximiser and the corresponding function value when one is found
     /// above the `bound` threshold, otherwise `None`.
-    fn maximise_above(&mut self, bound: F, tolerance: F, max_steps: usize) -> Option<(Domain, F)>;
+    fn maximise_above(&mut self, bound: F, tolerance: F, max_steps: usize) -> Option<(Domain, F)> {
+        let res @ (_, v) = self.maximise(tolerance, max_steps);
+        (v > bound).then_some(res)
+    }
 
     /// Minimise the mapping within stated value `tolerance`.
     ///
@@ -84,18 +87,31 @@
     ///
     /// At most `max_steps` refinement steps are taken.
     /// Returns the approximate minimiser and the corresponding function value when one is found
-    /// above the `bound` threshold, otherwise `None`.
-    fn minimise_below(&mut self, bound: F, tolerance: F, max_steps: usize) -> Option<(Domain, F)>;
+    /// below the `bound` threshold, otherwise `None`.
+    fn minimise_below(&mut self, bound: F, tolerance: F, max_steps: usize) -> Option<(Domain, F)> {
+        let res @ (_, v) = self.minimise(tolerance, max_steps);
+        (v < bound).then_some(res)
+    }
 
     /// Verify that the mapping has a given upper `bound` within indicated `tolerance`.
     ///
     /// At most `max_steps` refinement steps are taken.
-    fn has_upper_bound(&mut self, bound: F, tolerance: F, max_steps: usize) -> bool;
+    fn has_upper_bound(&mut self, bound: F, tolerance: F, max_steps: usize) -> bool {
+        match self.maximise_above(bound, tolerance, max_steps) {
+            None => true,
+            Some((_, v)) => v <= bound,
+        }
+    }
 
     /// Verify that the mapping has a given lower `bound` within indicated `tolerance`.
     ///
     /// At most `max_steps` refinement steps are taken.
-    fn has_lower_bound(&mut self, bound: F, tolerance: F, max_steps: usize) -> bool;
+    fn has_lower_bound(&mut self, bound: F, tolerance: F, max_steps: usize) -> bool {
+        match self.minimise_below(bound, tolerance, max_steps) {
+            None => true,
+            Some((_, v)) => v >= bound,
+        }
+    }
 }
 
 /// Upper and lower bounds on an `F`-valued function.

mercurial