From c0529dc9323300ae6f1790b63acc333a938ea126 Mon Sep 17 00:00:00 2001 From: unageek <29035331+unageek@users.noreply.github.com> Date: Tue, 1 Mar 2022 19:26:52 +0900 Subject: [PATCH] Update the docs of `cancel_{minus,plus}` --- src/basic.rs | 79 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 62 insertions(+), 17 deletions(-) diff --git a/src/basic.rs b/src/basic.rs index cee5ff0..adcedf4 100644 --- a/src/basic.rs +++ b/src/basic.rs @@ -4,26 +4,71 @@ use std::{cmp::Ordering, unreachable}; // NOTE: `neg`, `add`, `sub`, `mul` and `div` are implemented in arith.rs impl Interval { - /// When `self` and `rhs` are bounded, returns the tightest - /// interval `z` such that `rhs` + `z` ⊇ `self` if such `z` - /// exists, which is the case iff the width of `self` is greater - /// than or equal to the width of `rhs`. If `self` or `rhs` is - /// unbounded, or such `z` does not exist, returns - /// [`ENTIRE`][Self::ENTIRE]. + /// Returns the tightest interval `z` such that `rhs` $+$ `z` $⊇$ `self`, + /// if both `self` and `rhs` are bounded and the width of `self` is greater than or equal to + /// that of `rhs`. Otherwise, returns [`Interval::ENTIRE`]. /// - /// Mathematically, $\operatorname{cancel_minus}(y+z, y) = z$ - /// should hold. However, with floating-point arithmetic, this - /// function may return a slight overestimation of $z$. Moreover, - /// when `x.cancel_minus(y)` is not [`ENTIRE`][Self::ENTIRE], one has - /// `x.cancel_minus(y)` ⊆ `x` - `y` but generally not the equality. + /// Even when `x.cancel_minus(y)` is not [`Interval::ENTIRE`], its value is generally + /// different from `x - y`, as the latter gives the tightest enclosure of `x` $-$ `y`, + /// while the former does not always enclose `x` $-$ `y`. + /// In such case, `x.cancel_minus(y)` $⊆$ `x - y` holds, but generally not the equality. /// - /// # Example + /// # Examples + /// + /// Getting an enclosure of a partial sum omitting a single term from their total: + /// + /// ``` + /// use inari::*; + /// let x = interval!("[0.1, 0.2]").unwrap(); + /// let y = interval!("[0.3, 0.4]").unwrap(); + /// let z = interval!("[0.5, 0.6]").unwrap(); + /// let sum = x + y + z; + /// assert!((y + z).subset(sum.cancel_minus(x))); + /// assert!((x + z).subset(sum.cancel_minus(y))); + /// assert!((x + y).subset(sum.cancel_minus(z))); + /// ``` + /// + /// `sum.cancel_minus(x)` is a subset of `sum - x`: + /// + /// ``` + /// # use inari::*; + /// # let x = interval!("[0.1, 0.2]").unwrap(); + /// # let y = interval!("[0.3, 0.4]").unwrap(); + /// # let z = interval!("[0.5, 0.6]").unwrap(); + /// # let sum = x + y + z; + /// assert!(sum.cancel_minus(x).subset(sum - x)); + /// ``` + /// + /// But the inverse does not hold in general: + /// + /// ```should_panic + /// # use inari::*; + /// # let x = interval!("[0.1, 0.2]").unwrap(); + /// # let y = interval!("[0.3, 0.4]").unwrap(); + /// # let z = interval!("[0.5, 0.6]").unwrap(); + /// # let sum = x + y + z; + /// assert!((sum - x).subset(sum.cancel_minus(x))); + /// ``` + /// + /// `sum.cancel_minus(x)`, etc. returns [`Interval::ENTIRE`] when `sum` is unbounded: + /// + /// ``` + /// use inari::*; + /// let x = const_interval!(1.0, 2.0); + /// let y = const_interval!(3.0, f64::MAX); + /// let sum = x + y; + /// assert_eq!(sum.cancel_minus(x), Interval::ENTIRE); + /// assert_eq!(sum.cancel_minus(y), Interval::ENTIRE); + /// ``` + /// + /// `sum.cancel_minus(x)` returns [`Interval::ENTIRE`] when the width of “`sum`” is + /// less than that of `x`: /// /// ``` /// use inari::*; - /// let y = const_interval!(0.0, 1.0); - /// let z = const_interval!(3.0, 4.0); - /// assert_eq!((y + z).cancel_minus(y), z); + /// let x = const_interval!(1.0, 2.0); + /// let sum = const_interval!(4.0, 4.5); + /// assert_eq!(sum.cancel_minus(x), Interval::ENTIRE); /// ``` #[must_use] pub fn cancel_minus(self, rhs: Self) -> Self { @@ -128,9 +173,9 @@ impl Interval { } } - /// `x.cancel_plus(y)` is `x.cancel_minus(-y)`. + /// `x.cancel_plus(y)` is equivalent to `x.cancel_minus(-y)`. /// - /// See [`cancel_minus`][Self::cancel_minus] for more information. + /// See [`Interval::cancel_minus`] for more information. #[inline] #[must_use] pub fn cancel_plus(self, rhs: Self) -> Self {