Reference
Contents
The type
MathChecker.MathChecker — Module
MathCheckerFloating-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}| Flag | Signals when … |
|---|---|
Precision | mixed with a float of a different type (a dispatch error) |
NaN | a NaN is produced or used as an operand |
Inf | ±Inf is produced |
Cancellation | a ± b cancels most significant bits |
Absorption | an addend is too small to register |
Subnormal | a subnormal is produced |
Rounding | + - * / sqrt is inexact |
using MathChecker
x = checked(1e-8; cancellation=true)
(1 + x) - 1 # throws CancellationErrorDisabled 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.
MathChecker.Checked — Type
Checked{T<:AbstractFloat, Precision, NaN, Inf, Cancellation, Absorption, Subnormal, Rounding} <: AbstractFloatA 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:
| Flag | Signals when … | Instead of true … |
|---|---|---|
Precision | implicitly mixed with a float of another type | a Type of extra permitted types |
NaN | a NaN is produced, or used as an operand | |
Inf | ±Inf is produced | |
Cancellation | a ± b loses more than half its significant bits | a Float64 relative tolerance |
Absorption | an addend is too small to change the result at all | a Float64 relative tolerance |
Subnormal | a 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, complexesConstructors 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.
MathChecker.checked — Function
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.
MathChecker.unchecked — Function
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.
MathChecker.flags — Function
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).
MathChecker.valuetype — Function
valuetype(x::Checked)
valuetype(::Type{<:Checked})The underlying floating-point type T of a Checked{T, …}. For any other type, the type itself.
MathChecker.DEFAULT_FLAGS — Constant
DEFAULT_FLAGSThe 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)Errors
MathChecker.CheckError — Type
CheckError <: ExceptionSupertype of the exceptions signalled by the runtime checks. Every subtype has at least the fields
op: the function that was being evaluated (e.g.+,sqrt),result: the (unwrapped) value the operation produced, andargs::Tuple: the (unwrapped) operands.
The concrete subtypes are NaNError, InfError, SubnormalError, RoundingError, CancellationError, and AbsorptionError.
MathChecker.NaNError — Type
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).
MathChecker.InfError — Type
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.
MathChecker.SubnormalError — Type
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.
MathChecker.RoundingError — Type
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.
MathChecker.CancellationError — Type
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.
MathChecker.AbsorptionError — Type
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.
MathChecker.bitslost — Function
bitslost(err::CancellationError)The number of significant bits cancelled: log2(max(|a|, |b|) / |a ± b|), or Inf if the result was exactly zero.
Handlers
MathChecker.handler — Constant
MathChecker.handlerA 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.
MathChecker.with_handler — Function
with_handler(f, h)Call f() with MathChecker.handler set to h for the dynamic extent of the call. h is a function of one argument, a CheckError.
with_handler(warn_handler) do
risky_computation(checked(x))
endMathChecker.warn_handler — Function
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.
MathChecker.collect_failures — Function
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)MathChecker.fail — Function
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.
Internals
MathChecker.runchecks — Function
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.
MathChecker.issubnormal — Function
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.
MathChecker.hasprecision — Function
MathChecker.hasprecision(::Type{<:Checked}) -> BoolWhether the type's Precision flag is set (to true or to a whitelist type).
MathChecker.PrecisionMismatch — Type
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).
MathChecker.mixed_precision — Function
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.
MathChecker.formatcall — Function
MathChecker.formatcall(op, args) -> StringThe call op(args...) in a readable form: infix for binary operators ("a + b"), functional otherwise ("sqrt(a)").
MathChecker.message — Function
MathChecker.message(err::CheckError) -> StringThe 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.
Index
MathChecker.MathCheckerMathChecker.DEFAULT_FLAGSMathChecker.handlerMathChecker.AbsorptionErrorMathChecker.CancellationErrorMathChecker.CheckErrorMathChecker.CheckedMathChecker.InfErrorMathChecker.NaNErrorMathChecker.PrecisionMismatchMathChecker.RoundingErrorMathChecker.SubnormalErrorMathChecker.bitslostMathChecker.checkedMathChecker.collect_failuresMathChecker.failMathChecker.flagsMathChecker.formatcallMathChecker.hasprecisionMathChecker.issubnormalMathChecker.messageMathChecker.mixed_precisionMathChecker.runchecksMathChecker.uncheckedMathChecker.valuetypeMathChecker.warn_handlerMathChecker.with_handler