module FRP.Yampa.Integration (
integral,
imIntegral,
impulseIntegral,
count,
derivative,
iterFrom
) where
import Control.Arrow
import Data.VectorSpace
import FRP.Yampa.Event
import FRP.Yampa.Hybrid
import FRP.Yampa.InternalCore (SF(..), SF'(..), DTime)
{-# INLINE integral #-}
integral :: VectorSpace a s => SF a a
integral :: SF a a
integral = SF :: forall a b. (a -> Transition a b) -> SF a b
SF {sfTF :: a -> Transition a a
sfTF = a -> Transition a a
forall a. VectorSpace a a => a -> Transition a a
tf0}
where
tf0 :: a -> Transition a a
tf0 a
a0 = (a -> a -> SF' a a
forall b a. VectorSpace b a => b -> b -> SF' b b
integralAux a
igrl0 a
a0, a
igrl0)
igrl0 :: a
igrl0 = a
forall v a. VectorSpace v a => v
zeroVector
integralAux :: b -> b -> SF' b b
integralAux b
igrl b
a_prev = (DTime -> b -> Transition b b) -> SF' b b
forall a b. (DTime -> a -> Transition a b) -> SF' a b
SF' DTime -> b -> Transition b b
forall a a. (VectorSpace b a, Real a) => a -> b -> Transition b b
tf
where
tf :: a -> b -> Transition b b
tf a
dt b
a = (b -> b -> SF' b b
integralAux b
igrl' b
a, b
igrl')
where
igrl' :: b
igrl' = b
igrl b -> b -> b
forall v a. VectorSpace v a => v -> v -> v
^+^ a -> a
forall a b. (Real a, Fractional b) => a -> b
realToFrac a
dt a -> b -> b
forall v a. VectorSpace v a => a -> v -> v
*^ b
a_prev
imIntegral :: VectorSpace a s => a -> SF a a
imIntegral :: a -> SF a a
imIntegral = ((\ a
_ a
a' DTime
dt a
v -> a
v a -> a -> a
forall v a. VectorSpace v a => v -> v -> v
^+^ DTime -> s
forall a b. (Real a, Fractional b) => a -> b
realToFrac DTime
dt s -> a -> a
forall v a. VectorSpace v a => a -> v -> v
*^ a
a') (a -> a -> DTime -> a -> a) -> a -> SF a a
forall a b. (a -> a -> DTime -> b -> b) -> b -> SF a b
`iterFrom`)
iterFrom :: (a -> a -> DTime -> b -> b) -> b -> SF a b
a -> a -> DTime -> b -> b
f iterFrom :: (a -> a -> DTime -> b -> b) -> b -> SF a b
`iterFrom` b
b = (a -> Transition a b) -> SF a b
forall a b. (a -> Transition a b) -> SF a b
SF (b -> a -> Transition a b
iterAux b
b)
where
iterAux :: b -> a -> Transition a b
iterAux b
b a
a = ((DTime -> a -> Transition a b) -> SF' a b
forall a b. (DTime -> a -> Transition a b) -> SF' a b
SF' (\ DTime
dt a
a' -> b -> a -> Transition a b
iterAux (a -> a -> DTime -> b -> b
f a
a a
a' DTime
dt b
b) a
a'), b
b)
derivative :: VectorSpace a s => SF a a
derivative :: SF a a
derivative = SF :: forall a b. (a -> Transition a b) -> SF a b
SF {sfTF :: a -> Transition a a
sfTF = a -> Transition a a
forall b a b a.
(VectorSpace b a, VectorSpace b a) =>
b -> (SF' b b, b)
tf0}
where
tf0 :: b -> (SF' b b, b)
tf0 b
a0 = (b -> SF' b b
forall b a. VectorSpace b a => b -> SF' b b
derivativeAux b
a0, b
forall v a. VectorSpace v a => v
zeroVector)
derivativeAux :: b -> SF' b b
derivativeAux b
a_prev = (DTime -> b -> Transition b b) -> SF' b b
forall a b. (DTime -> a -> Transition a b) -> SF' a b
SF' DTime -> b -> Transition b b
forall a a. (VectorSpace b a, Real a) => a -> b -> Transition b b
tf
where
tf :: a -> b -> Transition b b
tf a
dt b
a = (b -> SF' b b
derivativeAux b
a, (b
a b -> b -> b
forall v a. VectorSpace v a => v -> v -> v
^-^ b
a_prev) b -> a -> b
forall v a. VectorSpace v a => v -> a -> v
^/ a -> a
forall a b. (Real a, Fractional b) => a -> b
realToFrac a
dt)
impulseIntegral :: VectorSpace a k => SF (a, Event a) a
impulseIntegral :: SF (a, Event a) a
impulseIntegral = (SF a a
forall a s. VectorSpace a s => SF a a
integral SF a a -> SF (Event a) a -> SF (a, Event a) (a, a)
forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** (a -> a -> a) -> a -> SF (Event a) a
forall b a. (b -> a -> b) -> b -> SF (Event a) b
accumHoldBy a -> a -> a
forall v a. VectorSpace v a => v -> v -> v
(^+^) a
forall v a. VectorSpace v a => v
zeroVector) SF (a, Event a) (a, a) -> ((a, a) -> a) -> SF (a, Event a) a
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> (c -> d) -> a b d
>>^ (a -> a -> a) -> (a, a) -> a
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry a -> a -> a
forall v a. VectorSpace v a => v -> v -> v
(^+^)
count :: Integral b => SF (Event a) (Event b)
count :: SF (Event a) (Event b)
count = (b -> a -> b) -> b -> SF (Event a) (Event b)
forall b a. (b -> a -> b) -> b -> SF (Event a) (Event b)
accumBy (\b
n a
_ -> b
n b -> b -> b
forall a. Num a => a -> a -> a
+ b
1) b
0