{-# LANGUAGE RecursiveDo #-}
module Simulation.Aivika.Trans.Dynamics.Extra
(
initDynamics,
discreteDynamics,
interpolateDynamics,
scanDynamics,
scan1Dynamics) where
import Control.Monad.Fix
import Simulation.Aivika.Trans.Comp
import Simulation.Aivika.Trans.Internal.Specs
import Simulation.Aivika.Trans.Internal.Simulation
import Simulation.Aivika.Trans.Internal.Dynamics
initDynamics :: Dynamics m a -> Dynamics m a
{-# INLINE initDynamics #-}
initDynamics (Dynamics m) =
Dynamics $ \p ->
let sc = pointSpecs p
in m $ p { pointTime = basicTime sc 0 0,
pointIteration = 0,
pointPhase = 0 }
discreteDynamics :: Dynamics m a -> Dynamics m a
{-# INLINE discreteDynamics #-}
discreteDynamics (Dynamics m) =
Dynamics $ \p ->
if pointPhase p == 0 then
m p
else
let sc = pointSpecs p
n = pointIteration p
in m $ p { pointTime = basicTime sc n 0,
pointPhase = 0 }
interpolateDynamics :: Dynamics m a -> Dynamics m a
{-# INLINE interpolateDynamics #-}
interpolateDynamics (Dynamics m) =
Dynamics $ \p ->
if pointPhase p >= 0 then
m p
else
let sc = pointSpecs p
n = pointIteration p
in m $ p { pointTime = basicTime sc n 0,
pointPhase = 0 }
scan1Dynamics :: MonadFix m
=> (a -> a -> a)
-> (Dynamics m a -> Simulation m (Dynamics m a))
-> (Dynamics m a -> Simulation m (Dynamics m a))
{-# INLINABLE scan1Dynamics #-}
scan1Dynamics f tr m =
mdo y <- tr $ Dynamics $ \p ->
case pointIteration p of
0 ->
invokeDynamics p m
n -> do
let sc = pointSpecs p
ty = basicTime sc (n - 1) 0
py = p { pointTime = ty, pointIteration = n - 1, pointPhase = 0 }
s <- invokeDynamics py y
x <- invokeDynamics p m
return $! f s x
return y
scanDynamics :: MonadFix m
=> (a -> b -> a)
-> a
-> (Dynamics m a -> Simulation m (Dynamics m a))
-> (Dynamics m b -> Simulation m (Dynamics m a))
{-# INLINABLE scanDynamics #-}
scanDynamics f acc tr m =
mdo y <- tr $ Dynamics $ \p ->
case pointIteration p of
0 -> do
x <- invokeDynamics p m
return $! f acc x
n -> do
let sc = pointSpecs p
ty = basicTime sc (n - 1) 0
py = p { pointTime = ty, pointIteration = n - 1, pointPhase = 0 }
s <- invokeDynamics py y
x <- invokeDynamics p m
return $! f s x
return y