Deterministic transcendental functions (exp, log, tanh, sinh, cosh) #
IEEE-754 fixes the representation and the basic arithmetic operations, but it does not mandate
exact bit-level behavior for transcendental functions like exp and log. In practice, libraries
(libm, SVML, CUDA math, etc.) make slightly different choices, and results can differ across
platforms.
In TorchLean, we still need executable transcendental operations in some examples and runtime
experiments. So we give IEEE32Exec deterministic definitions for a small set of functions using
fixed algorithms:
exp: range reduction + a fixed-point polynomial for2^(x/ln 2),log: normalizationx = m * 2^k+ a convergent atanh-series forlog m,sinh,cosh: defined viaexp,tanh: a numerically stable expression in terms ofexp.
Here we prove the special-value rules for those definitions: how NaNs, infinities, signed
zeros (+0 and -0), and sign checks behave. These are the facts we want in proofs without
unfolding the full fixed-point
implementations.
We do not claim that the finite-value approximations match any particular hardware expf/logf;
the goal is reproducibility (and well-defined behavior) inside Lean.
exp #
Special values we follow (common libm / PyTorch behavior):
exp(NaN) = NaN(we quiet signaling NaNs),exp(+Inf) = +Inf,exp(-Inf) = +0.
For finite inputs, Exec32.lean defines a deterministic approximation. These lemmas only expose
the early "special-case" branches, so proofs do not have to unfold the fixed-point core.
exp propagates NaNs by returning the quieted NaN payload.
log #
The special cases match the usual real-analytic extension used by common libraries:
log(NaN) = NaN(quieted),log(+Inf) = +Inf,log(0) = -Inf(for both+0and-0),log(x < 0) = NaN(includinglog(-Inf)).
PyTorch follows these conventions on IEEE hardware; we mirror them in IEEE32Exec.log.
log propagates NaNs by returning the quieted NaN payload.
log(-Inf) = NaN (domain error for negative inputs).
log returns canonicalNaN on negative finite inputs (domain error).
This captures the standard real domain restriction log : (0, +∞) → ℝ, transported to the float32
setting (excluding NaNs/Infs/zeros which are handled by earlier branches).
tanh #
Special values we follow:
tanh(NaN) = NaN(quieted),tanh(+Inf) = +1,tanh(-Inf) = -1.
The bit patterns used below are the IEEE-754 binary32 encodings of +1.0f and -1.0f:
0x3F800000=+1,0xBF800000=-1.
tanh propagates NaNs by returning the quieted NaN payload (via chooseNaN1).
sinh / cosh #
These are defined in Exec32.lean in terms of exp (with a NaN short-circuit up front), so the
special cases are the familiar ones:
- propagate NaNs (quieted),
sinh(±Inf) = ±Inf,cosh(±Inf) = +Inf.
sinh propagates NaNs by returning the quieted NaN payload (via chooseNaN1).
cosh propagates NaNs by returning the quieted NaN payload (via chooseNaN1).