isApproximatelyEqual(to:absoluteTolerance:relativeTolerance:norm:)
Test if self
and other
are approximately equal with specified tolerances and norm.
func isApproximatelyEqual<Magnitude>(to other: Self, absoluteTolerance: Magnitude, relativeTolerance: Magnitude = 0, norm: (Self) -> Magnitude) -> Bool where Magnitude : FloatingPoint
Parameters
- other
The value to which
self
is compared.- absoluteTolerance
The absolute tolerance to use in the comparison.
This value should be non-negative and finite. This constraint on is only checked in debug builds, because a mathematically well-defined result exists for any tolerance, even one out of range.
- relativeTolerance
The relative tolerance to use in the comparison. Defaults to zero.
This value should be non-negative and less than or equal to 1. This constraint on is only checked in debug builds, because a mathematically well-defined result exists for any tolerance, even one out of range.
- norm
The norm to use for the comparison. Defaults to
\.magnitude
.For example, if we wanted to test if a complex value was inside a circle of radius 0.001 centered at (1 + 0i), we could use:
z.isApproximatelyEqual( to: 1, absoluteTolerance: 0.001, norm: \.length )
(if we used the default norm,
.magnitude
, we would be testing ifz
were inside a square region instead.)
true
if self
and other
are equal, or if they are finite and either
norm(self - other) <= absoluteTolerance
or
norm(self - other) <= relativeTolerance * scale
where scale
is max(norm(self), norm(other))
.
Mathematical Properties:
isApproximatelyEqual(to:absoluteTolerance:relativeTolerance:norm:)
is reflexive for non-exceptional values (such as NaN).isApproximatelyEqual(to:absoluteTolerance:relativeTolerance:norm:)
is symmetric.isApproximatelyEqual(to:absoluteTolerance:relativeTolerance:norm:)
is not transitive. Because of this, approximately equality is not an equivalence relation, even when restricted to non-exceptional values.This means that you must not use approximate equality to implement a conformance to Equatable, as it will violate the invariants of code written against that protocol.
For any point
a
, the set of values that compare approximately equal toa
is convex (under the assumption thatnorm
implements a valid norm, which cannot be checked by this function or a protocol).
See Also:
isApproximatelyEqual(to:[relativeTolerance:norm:])
isApproximatelyEqual(to:absoluteTolerance:[relativeTolerance:])