{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE RebindableSyntax #-}
{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -Wno-pattern-namespace-specifier #-}
module Circuit.Stats.ODE
(
vectorField,
eulerStep,
rk4Step,
euler,
rk4,
eulerProcess,
rk4Process,
)
where
import Circuit.Diff (Diff, Diff', runDiff, pattern Diff)
import Circuit.Stats (Process (..))
import Data.List (scanl')
import NumHask.Prelude
vectorField :: (Additive s) => (s -> s) -> Diff' s s
vectorField :: forall s. Additive s => (s -> s) -> Diff' s s
vectorField s -> s
f = (s -> (s, s -> s)) -> Diff () s s
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff ((s -> (s, s -> s)) -> Diff () s s)
-> (s -> (s, s -> s)) -> Diff () s s
forall a b. (a -> b) -> a -> b
$ \s
x -> (s -> s
f s
x, s -> s -> s
forall a b. a -> b -> a
const s
forall a. Additive a => a
zero)
evalField :: Diff' s s -> s -> s
evalField :: forall s. Diff' s s -> s -> s
evalField Diff' s s
f s
x = (s, s -> s) -> s
forall a b. (a, b) -> a
fst (Diff' s s -> s -> (s, s -> s)
forall k (p :: k) a b. Diff p a b -> a -> (b, b -> a)
runDiff Diff' s s
f s
x)
eulerStep ::
(Additive s, MultiplicativeAction s, Scalar s ~ h) =>
Diff' s s ->
s ->
h ->
s
eulerStep :: forall s h.
(Additive s, MultiplicativeAction s, Scalar s ~ h) =>
Diff' s s -> s -> h -> s
eulerStep Diff' s s
f s
y h
h = s
y s -> s -> s
forall a. Additive a => a -> a -> a
+ (h
Scalar s
h Scalar s -> s -> s
forall m. MultiplicativeAction m => Scalar m -> m -> m
*| Diff' s s -> s -> s
forall s. Diff' s s -> s -> s
evalField Diff' s s
f s
y)
rk4Step ::
(Additive s, Additive (Scalar s), DivisiveAction s, Scalar s ~ h) =>
Diff' s s ->
s ->
h ->
s
rk4Step :: forall s h.
(Additive s, Additive (Scalar s), DivisiveAction s,
Scalar s ~ h) =>
Diff' s s -> s -> h -> s
rk4Step Diff' s s
f s
y h
h =
let tw :: h
tw = h
forall a. Multiplicative a => a
one h -> h -> h
forall a. Additive a => a -> a -> a
+ h
forall a. Multiplicative a => a
one
sx :: h
sx = h
forall a. Multiplicative a => a
one h -> h -> h
forall a. Additive a => a -> a -> a
+ h
forall a. Multiplicative a => a
one h -> h -> h
forall a. Additive a => a -> a -> a
+ h
forall a. Multiplicative a => a
one h -> h -> h
forall a. Additive a => a -> a -> a
+ h
forall a. Multiplicative a => a
one h -> h -> h
forall a. Additive a => a -> a -> a
+ h
forall a. Multiplicative a => a
one h -> h -> h
forall a. Additive a => a -> a -> a
+ h
forall a. Multiplicative a => a
one
k1 :: s
k1 = h
Scalar s
h Scalar s -> s -> s
forall m. MultiplicativeAction m => Scalar m -> m -> m
*| Diff' s s -> s -> s
forall s. Diff' s s -> s -> s
evalField Diff' s s
f s
y
k2 :: s
k2 = h
Scalar s
h Scalar s -> s -> s
forall m. MultiplicativeAction m => Scalar m -> m -> m
*| Diff' s s -> s -> s
forall s. Diff' s s -> s -> s
evalField Diff' s s
f (s
y s -> s -> s
forall a. Additive a => a -> a -> a
+ s
k1 s -> Scalar s -> s
forall m. DivisiveAction m => m -> Scalar m -> m
|/ h
Scalar s
tw)
k3 :: s
k3 = h
Scalar s
h Scalar s -> s -> s
forall m. MultiplicativeAction m => Scalar m -> m -> m
*| Diff' s s -> s -> s
forall s. Diff' s s -> s -> s
evalField Diff' s s
f (s
y s -> s -> s
forall a. Additive a => a -> a -> a
+ s
k2 s -> Scalar s -> s
forall m. DivisiveAction m => m -> Scalar m -> m
|/ h
Scalar s
tw)
k4 :: s
k4 = h
Scalar s
h Scalar s -> s -> s
forall m. MultiplicativeAction m => Scalar m -> m -> m
*| Diff' s s -> s -> s
forall s. Diff' s s -> s -> s
evalField Diff' s s
f (s
y s -> s -> s
forall a. Additive a => a -> a -> a
+ s
k3)
in s
y s -> s -> s
forall a. Additive a => a -> a -> a
+ (s
k1 s -> s -> s
forall a. Additive a => a -> a -> a
+ h
Scalar s
tw Scalar s -> s -> s
forall m. MultiplicativeAction m => Scalar m -> m -> m
*| s
k2 s -> s -> s
forall a. Additive a => a -> a -> a
+ h
Scalar s
tw Scalar s -> s -> s
forall m. MultiplicativeAction m => Scalar m -> m -> m
*| s
k3 s -> s -> s
forall a. Additive a => a -> a -> a
+ s
k4) s -> Scalar s -> s
forall m. DivisiveAction m => m -> Scalar m -> m
|/ h
Scalar s
sx
euler ::
(Additive s, MultiplicativeAction s, Scalar s ~ h) =>
Diff' s s ->
s ->
[h] ->
[s]
euler :: forall s h.
(Additive s, MultiplicativeAction s, Scalar s ~ h) =>
Diff' s s -> s -> [h] -> [s]
euler Diff' s s
f = (s -> h -> s) -> s -> [h] -> [s]
forall b a. (b -> a -> b) -> b -> [a] -> [b]
scanl' (Diff' s s -> s -> h -> s
forall s h.
(Additive s, MultiplicativeAction s, Scalar s ~ h) =>
Diff' s s -> s -> h -> s
eulerStep Diff' s s
f)
rk4 ::
(Additive s, Additive (Scalar s), DivisiveAction s, Scalar s ~ h) =>
Diff' s s ->
s ->
[h] ->
[s]
rk4 :: forall s h.
(Additive s, Additive (Scalar s), DivisiveAction s,
Scalar s ~ h) =>
Diff' s s -> s -> [h] -> [s]
rk4 Diff' s s
f = (s -> h -> s) -> s -> [h] -> [s]
forall b a. (b -> a -> b) -> b -> [a] -> [b]
scanl' (Diff' s s -> s -> h -> s
forall s h.
(Additive s, Additive (Scalar s), DivisiveAction s,
Scalar s ~ h) =>
Diff' s s -> s -> h -> s
rk4Step Diff' s s
f)
eulerProcess ::
(Additive s, MultiplicativeAction s, Scalar s ~ h) =>
Diff' s s ->
s ->
Process h s
eulerProcess :: forall s h.
(Additive s, MultiplicativeAction s, Scalar s ~ h) =>
Diff' s s -> s -> Process h s
eulerProcess Diff' s s
f s
y0 = (h -> s) -> (s -> h -> s) -> (s -> s) -> Process h s
forall s a b. (a -> s) -> (s -> a -> s) -> (s -> b) -> Process a b
Process (s -> h -> s
forall a b. a -> b -> a
const s
y0) (Diff' s s -> s -> h -> s
forall s h.
(Additive s, MultiplicativeAction s, Scalar s ~ h) =>
Diff' s s -> s -> h -> s
eulerStep Diff' s s
f) s -> s
forall a. a -> a
forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id
rk4Process ::
(Additive s, Additive (Scalar s), DivisiveAction s, Scalar s ~ h) =>
Diff' s s ->
s ->
Process h s
rk4Process :: forall s h.
(Additive s, Additive (Scalar s), DivisiveAction s,
Scalar s ~ h) =>
Diff' s s -> s -> Process h s
rk4Process Diff' s s
f s
y0 = (h -> s) -> (s -> h -> s) -> (s -> s) -> Process h s
forall s a b. (a -> s) -> (s -> a -> s) -> (s -> b) -> Process a b
Process (s -> h -> s
forall a b. a -> b -> a
const s
y0) (Diff' s s -> s -> h -> s
forall s h.
(Additive s, Additive (Scalar s), DivisiveAction s,
Scalar s ~ h) =>
Diff' s s -> s -> h -> s
rk4Step Diff' s s
f) s -> s
forall a. a -> a
forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id