| Safe Haskell | None |
|---|---|
| Language | GHC2024 |
Circuit.Diff
Description
Reverse-mode automatic differentiation as a NumHask carrier.
A 'Diff s b' is a smooth function s -> b bundled with its pullback.
These instances turn it into a NumHask carrier in its own right, so any
function written with NumHask-polymorphic operators becomes differentiable
by instantiating at Diff s b. The derivative rules live exactly where
they should: as the instance methods.
This is the "functorial lift" direction of the ecosystem membrane: NumHask-polymorphic code wraps AD by using 'Diff as its carrier.
The lift in one doctest: the identity primitive is "the variable", every
operator applied to it is an instance method carrying its own derivative,
and the pullback of the composite is the chain rule assembled by
instance resolution. f s = sin s^2 + s^3 at s = 2: value
sin 4 + 8, gradient 4*cos 4 + 12.
>>>import Circuit.Diff>>>import NumHask.Algebra.Additive qualified as NHA>>>import NumHask.Algebra.Multiplicative qualified as NHM>>>import NumHask.Algebra.Field qualified as NHF>>>let x = Diff (\s -> (s, \db -> db)) :: Diff' Double Double>>>let f = NHF.sin (x NHM.* x) NHA.+ x NHM.* x NHM.* x>>>let (y, pb) = runDiff f 2.0>>>abs (y - (sin 4 + 8)) < 1e-12True>>>abs (pb 1.0 - (4 * cos 4 + 12)) < 1e-12True
Documentation
newtype Diff (p :: k) a b Source #
A reverse-mode differentiable function tagged by a phantom type p.
The phantom tag prevents perturbation confusion: values of type
Diff p a b can only be composed with other Diff p values. Nested
AD introduces a fresh tag for each level.
runDiff f a returns a pair (b, pullback) where b = f a and pullback
maps a cotangent db on the output to a cotangent da on the input.
Constructors
| Diff | |
Fields
| |
Instances
| Channel Either (Diff p :: Type -> Type -> Type) Source # | Cocartesian channel plumbing for 'Diff. |
| Channel (,) (Diff p :: Type -> Type -> Type) Source # | Cartesian channel plumbing for 'Diff. |
| Strength Either (Diff p :: Type -> Type -> Type) Source # | Cocartesian tensorial strength for 'Diff. |
| Strength (,) (Diff p :: Type -> Type -> Type) Source # | Cartesian tensorial strength for 'Diff. |
Defined in Circuit.Diff.Circuit | |
| Traced Either (Diff p :: Type -> Type -> Type) Source # | Trace for 'Diff with the The The number of iterations is treated as locally constant by the derivative: small perturbations of the input do not change the branch sequence. This is the standard reverse-mode treatment of data-dependent control flow. Proof obligation (joins the linearity obligation on the other
traces): a cotangent on a sum is represented as the same sum, and
its tag must match the primal trajectory — the cotangent space at a
point of |
| Traced (,) (Diff p :: Type -> Type -> Type) Source # |
The forward pass ties the standard lazy knot: let (a, c) = body (a, b) in c The backward pass ties the same shape of knot, transposed. Given let bd = backward (fst bd, dc) in snd bd The knot flows through the pair rather than through the channel cotangent
alone —
|
Defined in Circuit.Diff.Circuit | |
| Action (,) (Diff p :: Type -> Type -> Type) Source # | |
Defined in Circuit.Diff.Circuit | |
| Tensor (,) (Diff p :: Type -> Type -> Type) Source # | |
| Unital (,) (Diff p :: Type -> Type -> Type) Source # | Monoidal product for Diff: independent wires, no additive constraint.
|
| Category (Diff p :: Type -> Type -> Type) Source # | 'Circuit.Diff still provides |
| Category (Diff p :: Type -> Type -> Type) Source # | |
| Zero (->) a => Discard (Diff p :: Type -> Type -> Type) (a :: Type) Source # | |
Defined in Circuit.Diff.Circuit | |
| Zero (->) a => Zero (Diff p :: Type -> Type -> Type) (a :: Type) Source # | |
Defined in Circuit.Diff.Circuit | |
| Merge (->) a => Copy (Diff p) a Source # | Copy in D: the pullback is
|
Defined in Circuit.Diff.Circuit | |
| Merge (->) a => Merge (Diff p) a Source # | Add in D: the pullback is
|
Defined in Circuit.Diff.Circuit | |
| Lit (Diff p Double Double) Source # | |
| (Num s, Num b) => Num (Diff p s b) Source # | Mechanical |
Defined in Circuit.Diff | |
| (Additive s, Additive b) => Additive (Diff p s b) Source # | Additive structure: sum rule.
|
| (Additive s, Subtractive s, Subtractive b) => Subtractive (Diff p s b) Source # | Subtractive structure: negation pushes through the pullback. |
| (ExpField b, Additive s, Subtractive s, Multiplicative b) => ExpField (Diff p s b) Source # | Exponential field: |
| (TrigField b, ExpField b, Additive s, Subtractive s, Multiplicative b, Divisive b) => TrigField (Diff p s b) Source # | Trigonometric field: the elementary transcendental family. |
Defined in Circuit.Diff Methods sin :: Diff p s b -> Diff p s b # cos :: Diff p s b -> Diff p s b # tan :: Diff p s b -> Diff p s b # asin :: Diff p s b -> Diff p s b # acos :: Diff p s b -> Diff p s b # atan :: Diff p s b -> Diff p s b # atan2 :: Diff p s b -> Diff p s b -> Diff p s b # sinh :: Diff p s b -> Diff p s b # cosh :: Diff p s b -> Diff p s b # tanh :: Diff p s b -> Diff p s b # asinh :: Diff p s b -> Diff p s b # | |
| (Additive s, Subtractive b, Multiplicative b, Divisive b) => Divisive (Diff p s b) Source # | Divisive structure: reciprocal rule. Division inherits the product rule via the default |
| (Additive s, Multiplicative b) => Multiplicative (Diff p s b) Source # | Multiplicative structure: product rule.
|