pub struct Comparator { /* private fields */ }Expand description
Utility struct to compare real numbers.
One limitiation of computable real numbers is that, in general whether two numbers are equal is undecidable. We could evaluate them to incraesingly high precision until they diverge, but if they are in fact equal, this would never terminate.
Given this, we provide the Comparator struct to compare real numbers and get the sign of a real number. You will have to provide some kind of tolerance level for the comparison.
Three different precision levels can be configured, and they are all typically negative:
Comparator::relsets the relative precision levelComparator::abssets the absolute precision levelComparator::min_precsets the minimum precision level
The relative level is added on top of max(msd(a), msd(b)) to determine the
precision we evaluate the numbers to to perform the comparison. Here msd
is defined as the binary position of the most significant digit, such that
2^(msd-1) < |x| < 2^(msd+1). Note that the relative level is only used
if the absolute level is set.
If no relative level is set, the numbers will be evaluated to the absolute level for comparison. If the relative level is set, the precision will be taken as the maximum between the relative and absolute levels.
The minimum precision level sets a bound of the evaluation precision. We will never evaluate the numbers to a precision beyond this. When no absolute level is set, we will iteratively evaluate the numbers until they diverge, or until the minimum precision level is reached.
§Examples
use computable_real::{Comparator, Real};
use std::cmp::Ordering;
let mut one = Real::from(1);
let mut pi = Real::pi();
let cmp = Comparator::new();
assert_eq!(cmp.cmp(&mut one, &mut pi), Ordering::Less);
// A comparator that will only evaluate to 2^-10 precision
let lazy_cmp = Comparator::new().abs(-10);
let mut smol = Real::from(1).shifted(-100);
// It cannot tell smol from 0
assert_eq!(lazy_cmp.signum(&mut smol), 0);
let mut pi_smol = pi.clone() + smol.clone();
// It cannot tell pi + smol from pi
assert_eq!(lazy_cmp.cmp(&mut pi_smol, &mut pi), Ordering::Equal);
// The default comparator can correctly compare
assert_eq!(cmp.signum(&mut smol), 1);
assert_eq!(cmp.cmp(&mut pi_smol, &mut pi), Ordering::Greater);Implementations§
Source§impl Comparator
impl Comparator
Sourcepub fn new() -> Self
pub fn new() -> Self
Returns a new comparator with no relative and absolute precision levels,
and a minimum precision level of i32::MIN.
When two numbers may be equal, you should set at least the absolute precision or the minimum precision level.
Sourcepub fn cmp(&self, a: &mut Real, b: &mut Real) -> Ordering
pub fn cmp(&self, a: &mut Real, b: &mut Real) -> Ordering
Compares two real numbers.
See examples in Comparator.
Sourcepub fn signum(&self, n: &mut Real) -> i32
pub fn signum(&self, n: &mut Real) -> i32
Returns the sign of a real number.
See examples in Comparator.
Trait Implementations§
Source§impl Default for Comparator
impl Default for Comparator
Source§fn default() -> Self
fn default() -> Self
Equivalent to Comparator::new.