{-# LANGUAGE RebindableSyntax #-}
module Circuit.Diff.Metric
(
adjointWith,
raiseWith,
lowerWith,
diagonalMetric,
euclideanMetric,
)
where
import Circuit.Diff (Diff (..), Diff', runDiff)
import NumHask.Prelude
adjointWith ::
Diff' (a, a) a ->
Diff' (b, b) b ->
Diff' a b ->
Diff' a b
adjointWith :: forall a b.
Diff' (a, a) a -> Diff' (b, b) b -> Diff' a b -> Diff' a b
adjointWith Diff' (a, a) a
raiseA Diff' (b, b) b
lowerB (Diff a -> (b, b -> a)
f) = (a -> (b, b -> a)) -> Diff () a b
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff ((a -> (b, b -> a)) -> Diff () a b)
-> (a -> (b, b -> a)) -> Diff () a b
forall a b. (a -> b) -> a -> b
$ \a
x ->
let (b
y, b -> a
jt) = a -> (b, b -> a)
f a
x
in ( b
y,
\b
db ->
let (b
lowered, b -> (b, b)
_) = Diff' (b, b) b -> (b, b) -> (b, b -> (b, b))
forall k (p :: k) a b. Diff p a b -> a -> (b, b -> a)
runDiff Diff' (b, b) b
lowerB (b
y, b
db)
covectorA :: a
covectorA = b -> a
jt b
lowered
(a
raised, a -> (a, a)
_) = Diff' (a, a) a -> (a, a) -> (a, a -> (a, a))
forall k (p :: k) a b. Diff p a b -> a -> (b, b -> a)
runDiff Diff' (a, a) a
raiseA (a
x, a
covectorA)
in a
raised
)
raiseWith :: Diff' (s, a) a -> s -> a -> a
raiseWith :: forall s a. Diff' (s, a) a -> s -> a -> a
raiseWith Diff' (s, a) a
g s
s a
covec = (a, a -> (s, a)) -> a
forall a b. (a, b) -> a
fst (Diff' (s, a) a -> (s, a) -> (a, a -> (s, a))
forall k (p :: k) a b. Diff p a b -> a -> (b, b -> a)
runDiff Diff' (s, a) a
g (s
s, a
covec))
lowerWith :: Diff' (s, a) a -> s -> a -> a
lowerWith :: forall s a. Diff' (s, a) a -> s -> a -> a
lowerWith Diff' (s, a) a
g s
s a
vec = (a, a -> (s, a)) -> a
forall a b. (a, b) -> a
fst (Diff' (s, a) a -> (s, a) -> (a, a -> (s, a))
forall k (p :: k) a b. Diff p a b -> a -> (b, b -> a)
runDiff Diff' (s, a) a
g (s
s, a
vec))
euclideanMetric :: (Additive a) => Diff' (a, a) a
euclideanMetric :: forall a. Additive a => Diff' (a, a) a
euclideanMetric = ((a, a) -> (a, a -> (a, a))) -> Diff () (a, a) a
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff (((a, a) -> (a, a -> (a, a))) -> Diff () (a, a) a)
-> ((a, a) -> (a, a -> (a, a))) -> Diff () (a, a) a
forall a b. (a -> b) -> a -> b
$ \(a
_, a
v) -> (a
v, (a, a) -> a -> (a, a)
forall a b. a -> b -> a
const (a
forall a. Additive a => a
zero, a
forall a. Additive a => a
zero))
diagonalMetric ::
(Additive s) =>
(s -> a -> a) ->
Diff' (s, a) a
diagonalMetric :: forall s a. Additive s => (s -> a -> a) -> Diff' (s, a) a
diagonalMetric s -> a -> a
f = ((s, a) -> (a, a -> (s, a))) -> Diff () (s, a) a
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff (((s, a) -> (a, a -> (s, a))) -> Diff () (s, a) a)
-> ((s, a) -> (a, a -> (s, a))) -> Diff () (s, a) a
forall a b. (a -> b) -> a -> b
$ \(s
s, a
x) ->
let gx :: a
gx = s -> a -> a
f s
s a
x
in ( a
gx,
\a
dc -> (s
forall a. Additive a => a
zero, s -> a -> a
f s
s a
dc)
)