Reference

Contents

The type

MathChecker.MathCheckerModule
MathChecker

Floating-point numbers that check their own arithmetic.

Wrap a value in Checked and use it exactly as you would the underlying float. After every operation, the checks selected by the type's flag parameters inspect the result and signal an error pointing at the offending operation:

Checked{T, Precision, NaN, Inf, Cancellation, Absorption, Subnormal, Rounding}
FlagSignals when …
Precisionmixed with a float of a different type (a dispatch error)
NaNa NaN is produced or used as an operand
Inf±Inf is produced
Cancellationa ± b cancels most significant bits
Absorptionan addend is too small to register
Subnormala subnormal is produced
Rounding+ - * / sqrt is inexact
using MathChecker
x = checked(1e-8; cancellation=true)
(1 + x) - 1        # throws CancellationError

Disabled checks are eliminated by the compiler, so a Checked{Float64} with every flag false is exactly as fast as a Float64. See handler and collect_failures for reporting failures without throwing.

source
MathChecker.CheckedType
Checked{T<:AbstractFloat, Precision, NaN, Inf, Cancellation, Absorption, Subnormal, Rounding} <: AbstractFloat

A floating-point number of type T whose every operation is verified by the checks selected by the flag type parameters. A Checked participates in arithmetic exactly like a T — all of Base's arithmetic, math, comparison, rounding, and conversion functions are supported — but after every operation the enabled checks inspect the result (and operands) and signal a CheckError through the current handler if something is wrong. Disabled checks cost nothing: they are eliminated at compile time.

Flags

Each flag is false (off) or true (on). Three of them accept a configuration value in place of true:

FlagSignals when …Instead of true
Precisionimplicitly mixed with a float of another typea Type of extra permitted types
NaNa NaN is produced, or used as an operand
Inf±Inf is produced
Cancellationa ± b loses more than half its significant bitsa Float64 relative tolerance
Absorptionan addend is too small to change the result at alla Float64 relative tolerance
Subnormala subnormal number is produced
Rounding+, -, *, /, or sqrt is not exact

Each flag is documented in detail in the manual's "Checks" section. The defaults, used by Checked{T}(x) and checked, turn on Precision, NaN, and Inf — the three checks that can never produce a false positive — and leave the rest off.

Constructors

Checked{T, flags...}(x)                 # x::Real; converts x to T; never signals
Checked{T}(x; nan=true, inf=true, …)    # defaults for flags not given
Checked(x; …)                           # T = typeof(float(x))
checked(x; …)                           # also handles arrays, tuples, complexes

Constructors never signal, even for NaN or Inf, so that sentinels can be created (see the NaN check). Constructors are also exempt from the Precision check: they are explicit conversions. The functions checked and unchecked wrap and unwrap values, arrays, tuples, and complex numbers; flags and valuetype recover the parameters.

Examples

julia> x = Checked(1.0)
Checked{Float64}(1.0)

julia> x / 0
ERROR: InfError: 1.0 / 0.0 produced Inf:
       division by zero (the exact result is infinite).
[...]

julia> unchecked(sqrt(x + 1))
1.4142135623730951

julia> y = checked(1e-9; cancellation=true)
Checked{Float64, true, true, true, true, false, false, false}(1.0e-9)

julia> (1 + y) - 1
ERROR: CancellationError: 1.000000001 - 1.0 produced 1.000000082740371e-9,
       cancelling 29.9 of 53 significant bits: |result| / max(|a|, |b|) = 1e-09
       is below the tolerance 1.49e-08 (26 bits).
[...]

Promotion

Two Checked values with the same T promote to a Checked with the union of their flags, so a value checked for NaN added to a value checked for Inf is checked for both. A Checked{T} combined with a plain T, Integer, Rational, or irrational constant yields a Checked{T}. Combining with a different floating-point type follows Julia's usual promotion unless the Precision flag is set, in which case the checked value keeps its own T and the conversion of the other operand is a MethodError (with an explanatory hint) unless that type is permitted.

source
MathChecker.checkedFunction
checked(x; precision=true, nan=true, inf=true, cancellation=false, absorption=false,
           subnormal=false, rounding=false)
checked(T::Type{<:AbstractFloat}; flags...)

Wrap x in a Checked with the given check flags (see Checked for their meanings and accepted values); flags not mentioned take their defaults.

x may be a real number, a Complex, a Tuple, or an AbstractArray of any of these; containers are wrapped elementwise. Integers and rationals are converted to Float64 first. Applied to a Checked value, the flags given are changed and the others kept, so checked(x; cancellation=true) adds a check to x.

Applied to a floating-point type, checked returns the corresponding Checked type, which is convenient with zeros, rand, etc.:

zeros(checked(Float64; nan=true), 3)

See also unchecked.

source
MathChecker.uncheckedFunction
unchecked(x)

Remove the Checked wrapper from x, returning the underlying value. Complexes, Tuples, and AbstractArrays are unwrapped elementwise; anything else is returned unchanged, so unchecked can be applied blindly to the result of a computation.

See also checked.

source
MathChecker.flagsFunction
flags(x::Checked)
flags(::Type{<:Checked})

The check flags of x as a NamedTuple with fields precision, nan, inf, cancellation, absorption, subnormal, and rounding, in that order (the order of the type parameters).

source
MathChecker.valuetypeFunction
valuetype(x::Checked)
valuetype(::Type{<:Checked})

The underlying floating-point type T of a Checked{T, …}. For any other type, the type itself.

source
MathChecker.DEFAULT_FLAGSConstant
DEFAULT_FLAGS

The flags used when none are specified: Precision, NaN, and Inf on; everything else off.

(precision = true, nan = true, inf = true, cancellation = false, absorption = false,
 subnormal = false, rounding = false)
source

Errors

MathChecker.NaNErrorType
NaNError(op, result, args)

Signalled by the NaN check when op(args...) produced a NaN, or had a NaN operand. The message says whether the operation generated the NaN (no operand was NaN), propagated it (NaN in, NaN out), or consumed it (NaN in, ordinary value out — the point at which a NaN silently becomes a wrong answer).

source
MathChecker.InfErrorType
InfError(op, result, args)

Signalled by the Inf check when op(args...) produced ±Inf. The message says whether this was a division by zero (an exact infinity), an overflow, or the propagation of an already-infinite operand.

source
MathChecker.SubnormalErrorType
SubnormalError(op, result, args)

Signalled by the Subnormal check when op(args...) produced a subnormal number, or underflowed to zero although its exact result is nonzero.

source
MathChecker.RoundingErrorType
RoundingError(op, result, args, residual)

Signalled by the Rounding check when op(args...) was not exact. residual is the (approximate) rounding error exact - result, as computed by an error-free transformation.

source
MathChecker.CancellationErrorType
CancellationError(op, result, args, ratio, tolerance)

Signalled by the Cancellation check when an addition or subtraction lost most of its significant bits. ratio is the measured |result| / max(|a|, |b|) and tolerance the relative threshold it fell below. The number of bits lost is available from bitslost.

source
MathChecker.AbsorptionErrorType
AbsorptionError(op, result, args, absorbed, ratio, tolerance)

Signalled by the Absorption check when an operand of an addition or subtraction was too small to (fully) register in the result ("absorption", also called "swamping"). absorbed is the index into args of the operand that was lost, ratio is the measured |small| / |large| of the two addends, and tolerance is the relative threshold used, or nothing for the exact test.

source
MathChecker.bitslostFunction
bitslost(err::CancellationError)

The number of significant bits cancelled: log2(max(|a|, |b|) / |a ± b|), or Inf if the result was exactly zero.

source

Handlers

MathChecker.handlerConstant
MathChecker.handler

A ScopedValue holding the function that is called with a CheckError whenever a check fails. The default handler is throw. Other handlers are free to log, record, or ignore the error; if the handler returns, the operation that failed the check returns its (possibly NaN, infinite, …) result as usual.

Use with_handler to change the handler for the dynamic extent of a function call, or ScopedValues.with(MathChecker.handler => f) do … end directly. Because it is a scoped value, the setting is task-local and safe to use from multiple threads.

Provided handlers: throw (default), warn_handler, and the collecting handler used by collect_failures.

source
MathChecker.warn_handlerFunction
warn_handler(err::CheckError)

A handler that logs each failed check as a warning (including a backtrace to the offending operation) and lets the computation continue.

source
MathChecker.collect_failuresFunction
collect_failures(f) -> (result, failures::Vector{CheckError})

Run f() with a handler that records every failed check instead of throwing, and return the result of f together with the vector of recorded CheckErrors. This is the recommended way to survey all the numerical problems in a computation at once, or to assert that there are none:

result, failures = collect_failures() do
    myalgorithm(checked(A; cancellation=true))
end
@test isempty(failures)
source
MathChecker.failFunction
MathChecker.fail(err::CheckError)

Report a failed check by calling the current handler. The checks call this rather than throw, so that users can switch handlers.

source

Internals

MathChecker.runchecksFunction
MathChecker.runchecks(::Type{X<:Checked}, op, result, args...)

Run the checks enabled in the type X on result = op(args...) (all unwrapped). The NaN, Inf, and Subnormal checks run first, so that a non-finite result is reported as such rather than as a cancellation or absorption.

source
MathChecker.issubnormalFunction
MathChecker.issubnormal(x)

Like Base.issubnormal, but defined (as false) for any Real, so that the Subnormal check can be used with types that do not implement Base.issubnormal. Extend this for such types if they can hold subnormal values.

source
MathChecker.hasprecisionFunction
MathChecker.hasprecision(::Type{<:Checked}) -> Bool

Whether the type's Precision flag is set (to true or to a whitelist type).

source
MathChecker.PrecisionMismatchType
MathChecker.PrecisionMismatch{X, Y}

Trait type marking that values of types X and Y may not be implicitly converted into one another, because at least one of them is a Checked with the Precision flag that does not permit the other. There is deliberately no method of MathChecker.mixed_precision for this type, so that the attempt fails with a MethodError (which carries an explanatory hint).

source
MathChecker.mixed_precisionFunction
MathChecker.mixed_precision(trait, x)

Identity on x when trait is PrecisionOK(). Deliberately has no method for a PrecisionMismatch, so that implicitly mixing a Checked that has the Precision flag with a float of another type is a MethodError.

source
MathChecker.formatcallFunction
MathChecker.formatcall(op, args) -> String

The call op(args...) in a readable form: infix for binary operators ("a + b"), functional otherwise ("sqrt(a)").

source
MathChecker.messageFunction
MathChecker.message(err::CheckError) -> String

The full text of the error message, as printed by showerror. Continuation lines are indented to line up under the error name after the REPL's ERROR: prefix.

source

Index