Elementwise tensor operations (TorchLean.Tensor.*_spec) #
This file defines shape-preserving, elementwise operations on Tensor α s.
Naming convention:
foo_specmeans “pure spec definition” (no runtime side effects).- most functions use packed pointwise kernels via
mapSpec/map2Spec.
Domain / smoothness notes #
Some operations are domain-sensitive or non-smooth:
sqrtSpecusessqrt (max x 0)to stay total on ordered rings.logSpecis total as a function call, but analytic properties require positivity assumptions.relu/clamp/ comparisons are non-smooth; analytic backprop theorems treat these via pointwise assumptions, or by switching to smooth surrogates in verification workflows.
The spec layer is where these semantics are defined; the proof layer decides which assumptions/variants to use for theorems.
Keep a tensor's primal values while removing scalar differentiation metadata.
For ordinary numeric tensors, this returns the same tensor. Dual-valued tensors need a pointwise map as well as the graph's zero JVP and VJP: otherwise a later operation could still read a tangent from the detached value while computing a higher-order derivative.
Instances For
Axis-parametric indexing #
Place one selected slice back into an otherwise-zero tensor.
This is the adjoint of selectSpec and therefore its reverse-mode rule.
Instances For
Select coordinates from an arbitrary axis using an index vector.
The selected axis is replaced by the index count. Repeated indices are preserved, matching
torch.index_select.
Instances For
Insert a sliced gradient back along an arbitrary axis, filling coordinates outside it with zero.
Instances For
Map a scalar function over a tensor (shape preserved).
This is the core packed pointwise combinator for spec tensors.
Most elementwise ops are direct instances of mapSpec f.
PyTorch analogy: f applied pointwise (like torch.<op> broadcasting over all entries),
but here shape is fixed and enforced by the type.
Instances For
Extracting a scalar after an elementwise map applies the scalar function once.
Transport a pointwise tensor property through an elementwise operation.
Map a binary function over two tensors of the same shape.
This is the packed zipWith combinator for spec tensors.
It is intentionally shape-preserving: if the shapes differ, the term is not well-typed.
PyTorch analogy: elementwise binary ops when tensors already have the same shape (no broadcasting).
Broadcasting is handled separately in NN/Spec/Core/TensorReductionShape.lean.
Instances For
Extracting a scalar after a pointwise binary map combines the two scalar values.
Evaluating a pointwise binary operation combines both scalar entries.
Indexing a pointwise binary operation applies the scalar operation after indexing.
Transport two pointwise properties through a binary shape-preserving operation.
Element‑wise addition (shape preserved).
Instances For
Add indexed source slices into an arbitrary axis of a tensor.
Repeated indices accumulate. This is the pure tensor semantics used by the backward rule for
indexSelectSpec and corresponds to torch.scatter_add with an index vector.
Instances For
Element‑wise multiplication (shape preserved).
Instances For
Multiplication by a filled tensor is coordinatewise multiplication by its scalar value.
Mul instance for shape-indexed tensors: multiply pointwise, preserving the shape.
Element‑wise subtraction (shape preserved).
Instances For
Element‑wise division (shape preserved).
Instances For
Div instance for shape-indexed tensors: divide pointwise, preserving the shape.
Epsilon-shifted division, $x/(y+\varepsilon)$. The denominator can still be zero.
Instances For
Scale a tensor by a scalar.
Instances For
Square each element of a tensor.
Instances For
Squaring is elementwise multiplication with the same tensor on both inputs.
Square root of each element (clamped to max x 0 to stay total).
Instances For
Absolute value of each element.
Instances For
Element‑wise natural log.
Instances For
Element‑wise exponential.
Instances For
Element‑wise negation.
Instances For
Element‑wise power.
Instances For
Element‑wise comparisons (returning Bool tensors).
Instances For
Element-wise $\le$ test, implemented via $\neg(>)$ so we only depend on
DecidableRel (· > ·). This agrees with ≤ for a total order; IEEE unordered
comparisons involving NaN return true here.
Instances For
Element‑wise < test (defined as y > x).
Instances For
Element-wise $\ge$ test (defined as $\neg(y>x)$). Like lessEqualSpec, this returns
true for IEEE unordered comparisons involving NaN.
Instances For
Boolean NOT, pointwise on a Bool tensor.
Instances For
Element‑wise reciprocal (1/x).
Instances For
Clamp each entry into [minVal, maxVal].
The runtime uses zero derivative outside the open interval, including at either endpoint. Clearing scalar tangents on that branch gives dual-number execution the same convention as the recorded JVP and VJP. The underlying minimum and maximum still determine the primal value.
Instances For
Element‑wise minimum.
Instances For
Element‑wise maximum.
Instances For
Element‑wise sign function: returns -1, 0, or 1.
Instances For
Elementwise sine, with each input interpreted as an angle in radians.
Instances For
Elementwise cosine, with each input interpreted as an angle in radians.
Instances For
Element‑wise cosh.
Instances For
Element‑wise sinh.
Instances For
Derivative mask for clamp: 1 strictly inside (minVal, maxVal), else 0.
Instances For
Numeric mask: 1 where a > b, else 0.
Instances For
Numeric mask: 1 where a < b, else 0.
Instances For
Convert a Bool to α using 1/0.
Instances For
Multiply a tensor by a Bool mask (casts the mask to 0/1).
Instances For
Apply a Huber-style clamp on entries selected by mask (leaves others unchanged).
Instances For
Update a tensor at a runtime index path.
The index path is interpreted outermost-first. Out-of-bounds indices leave the tensor unchanged. The implementation validates the path once, then performs one copy-on-write physical-buffer replacement.
Instances For
Like updateTensorSpec, but replaces a subtree with another tensor.
Instances For
Specialization of updateTensorSpec for a top-level vector dimension.