module Simulation.Aivika.Lattice.Estimate
(
Estimate,
EstimateLift(..),
runEstimateInStartTime,
estimateTime,
foldEstimate,
memoEstimate,
estimateUpSide,
estimateDownSide,
estimateFuture,
shiftEstimate,
estimateAt,
catchEstimate,
finallyEstimate,
throwEstimate,
traceEstimate) where
import Simulation.Aivika.Trans.Internal.Types
import Simulation.Aivika.Trans.Simulation
import Simulation.Aivika.Trans.Parameter
import Simulation.Aivika.Trans.Ref
import Simulation.Aivika.Trans.Observable
import Simulation.Aivika.Lattice.Internal.Estimate
import Simulation.Aivika.Lattice.Internal.LIO
import qualified Simulation.Aivika.Lattice.Internal.Ref as R
memoEstimate :: (Estimate LIO a -> Estimate LIO a)
-> Estimate LIO a
-> Simulation LIO (Estimate LIO a)
memoEstimate :: forall a.
(Estimate LIO a -> Estimate LIO a)
-> Estimate LIO a -> Simulation LIO (Estimate LIO a)
memoEstimate Estimate LIO a -> Estimate LIO a
f Estimate LIO a
m =
do Ref (Maybe a)
r <- forall a. a -> Simulation LIO (Ref a)
R.newRef forall a. Maybe a
Nothing
Double
t2 <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
ParameterLift t m =>
Parameter m a -> t m a
liftParameter forall (m :: * -> *). Monad m => Parameter m Double
stoptime
let loop :: Estimate LIO a
loop =
forall (m :: * -> *) a. (Point m -> m a) -> Estimate m a
Estimate forall a b. (a -> b) -> a -> b
$ \Point LIO
p ->
do Maybe a
b <- forall a. Ref a -> LIO a
R.readRef0 Ref (Maybe a)
r
case Maybe a
b of
Just a
a -> forall (m :: * -> *) a. Monad m => a -> m a
return a
a
Maybe a
Nothing ->
if forall (m :: * -> *). Point m -> Double
pointTime Point LIO
p forall a. Ord a => a -> a -> Bool
>= Double
t2
then do a
a <- forall (m :: * -> *) a. Point m -> Estimate m a -> m a
invokeEstimate Point LIO
p Estimate LIO a
m
forall a. Ref a -> a -> LIO ()
R.writeRef0 Ref (Maybe a)
r (forall a. a -> Maybe a
Just a
a)
forall (m :: * -> *) a. Monad m => a -> m a
return a
a
else do a
a <- forall (m :: * -> *) a. Point m -> Estimate m a -> m a
invokeEstimate Point LIO
p (Estimate LIO a -> Estimate LIO a
f Estimate LIO a
loop)
forall a. Ref a -> a -> LIO ()
R.writeRef0 Ref (Maybe a)
r (forall a. a -> Maybe a
Just a
a)
forall (m :: * -> *) a. Monad m => a -> m a
return a
a
forall (m :: * -> *) a. Monad m => a -> m a
return Estimate LIO a
loop
estimateUpSide :: Estimate LIO a -> Estimate LIO a
estimateUpSide :: forall a. Estimate LIO a -> Estimate LIO a
estimateUpSide Estimate LIO a
m =
forall (m :: * -> *) a. (Point m -> m a) -> Estimate m a
Estimate forall a b. (a -> b) -> a -> b
$ \Point LIO
p ->
forall a. (LIOParams -> IO a) -> LIO a
LIO forall a b. (a -> b) -> a -> b
$ \LIOParams
ps ->
do let ps' :: LIOParams
ps' = LIOParams -> LIOParams
upSideLIOParams LIOParams
ps
r :: Run LIO
r = forall (m :: * -> *). Point m -> Run m
pointRun Point LIO
p
Point LIO
p' <- forall a. LIOParams -> LIO a -> IO a
invokeLIO LIOParams
ps' forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) a. Run m -> Parameter m a -> m a
invokeParameter Run LIO
r
Parameter LIO (Point LIO)
latticePoint
forall a. LIOParams -> LIO a -> IO a
invokeLIO LIOParams
ps' forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) a. Point m -> Estimate m a -> m a
invokeEstimate Point LIO
p' Estimate LIO a
m
estimateDownSide :: Estimate LIO a -> Estimate LIO a
estimateDownSide :: forall a. Estimate LIO a -> Estimate LIO a
estimateDownSide Estimate LIO a
m =
forall (m :: * -> *) a. (Point m -> m a) -> Estimate m a
Estimate forall a b. (a -> b) -> a -> b
$ \Point LIO
p ->
forall a. (LIOParams -> IO a) -> LIO a
LIO forall a b. (a -> b) -> a -> b
$ \LIOParams
ps ->
do let ps' :: LIOParams
ps' = LIOParams -> LIOParams
downSideLIOParams LIOParams
ps
r :: Run LIO
r = forall (m :: * -> *). Point m -> Run m
pointRun Point LIO
p
Point LIO
p' <- forall a. LIOParams -> LIO a -> IO a
invokeLIO LIOParams
ps' forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) a. Run m -> Parameter m a -> m a
invokeParameter Run LIO
r
Parameter LIO (Point LIO)
latticePoint
forall a. LIOParams -> LIO a -> IO a
invokeLIO LIOParams
ps' forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) a. Point m -> Estimate m a -> m a
invokeEstimate Point LIO
p' Estimate LIO a
m
shiftEstimate :: Int
-> Int
-> Estimate LIO a
-> Estimate LIO a
shiftEstimate :: forall a. Int -> Int -> Estimate LIO a -> Estimate LIO a
shiftEstimate Int
di Int
dk Estimate LIO a
m =
forall (m :: * -> *) a. (Point m -> m a) -> Estimate m a
Estimate forall a b. (a -> b) -> a -> b
$ \Point LIO
p ->
forall a. (LIOParams -> IO a) -> LIO a
LIO forall a b. (a -> b) -> a -> b
$ \LIOParams
ps ->
do let ps' :: LIOParams
ps' = Int -> Int -> LIOParams -> LIOParams
shiftLIOParams Int
di Int
dk LIOParams
ps
r :: Run LIO
r = forall (m :: * -> *). Point m -> Run m
pointRun Point LIO
p
Point LIO
p' <- forall a. LIOParams -> LIO a -> IO a
invokeLIO LIOParams
ps' forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) a. Run m -> Parameter m a -> m a
invokeParameter Run LIO
r
Parameter LIO (Point LIO)
latticePoint
forall a. LIOParams -> LIO a -> IO a
invokeLIO LIOParams
ps' forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) a. Point m -> Estimate m a -> m a
invokeEstimate Point LIO
p' Estimate LIO a
m
estimateFuture :: Int
-> Int
-> Estimate LIO a
-> Estimate LIO a
estimateFuture :: forall a. Int -> Int -> Estimate LIO a -> Estimate LIO a
estimateFuture Int
di Int
dk Estimate LIO a
m
| Int
di forall a. Ord a => a -> a -> Bool
<= Int
0 = forall a. HasCallStack => [Char] -> a
error [Char]
"Expected to see a positive time index shift: estimateFuture"
| Bool
otherwise = forall a. Int -> Int -> Estimate LIO a -> Estimate LIO a
shiftEstimate Int
di Int
dk Estimate LIO a
m
estimateAt :: Int
-> Int
-> Estimate LIO a
-> Estimate LIO a
estimateAt :: forall a. Int -> Int -> Estimate LIO a -> Estimate LIO a
estimateAt Int
i Int
k Estimate LIO a
m =
forall (m :: * -> *) a. (Point m -> m a) -> Estimate m a
Estimate forall a b. (a -> b) -> a -> b
$ \Point LIO
p ->
forall a. (LIOParams -> IO a) -> LIO a
LIO forall a b. (a -> b) -> a -> b
$ \LIOParams
ps ->
do let ps' :: LIOParams
ps' = Int -> Int -> LIOParams -> LIOParams
lioParamsAt Int
i Int
k LIOParams
ps
r :: Run LIO
r = forall (m :: * -> *). Point m -> Run m
pointRun Point LIO
p
Point LIO
p' <- forall a. LIOParams -> LIO a -> IO a
invokeLIO LIOParams
ps' forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) a. Run m -> Parameter m a -> m a
invokeParameter Run LIO
r
Parameter LIO (Point LIO)
latticePoint
forall a. LIOParams -> LIO a -> IO a
invokeLIO LIOParams
ps' forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) a. Point m -> Estimate m a -> m a
invokeEstimate Point LIO
p' Estimate LIO a
m
foldEstimate :: (a -> a -> Estimate LIO a)
-> Estimate LIO a
-> Simulation LIO (Estimate LIO a)
foldEstimate :: forall a.
(a -> a -> Estimate LIO a)
-> Estimate LIO a -> Simulation LIO (Estimate LIO a)
foldEstimate a -> a -> Estimate LIO a
f = forall a.
(Estimate LIO a -> Estimate LIO a)
-> Estimate LIO a -> Simulation LIO (Estimate LIO a)
memoEstimate Estimate LIO a -> Estimate LIO a
g
where g :: Estimate LIO a -> Estimate LIO a
g Estimate LIO a
m =
do a
a1 <- forall a. Estimate LIO a -> Estimate LIO a
estimateUpSide Estimate LIO a
m
a
a2 <- forall a. Estimate LIO a -> Estimate LIO a
estimateDownSide Estimate LIO a
m
a -> a -> Estimate LIO a
f a
a1 a
a2