-- |
-- Module     : Simulation.Aivika.Trans.Transform.Memo
-- Copyright  : Copyright (c) 2009-2017, David Sorokin <david.sorokin@gmail.com>
-- License    : BSD3
-- Maintainer : David Sorokin <david.sorokin@gmail.com>
-- Stability  : experimental
-- Tested with: GHC 8.0.1
--
-- This module defines memoization transforms. The memoization creates such 'Dynamics'
-- computations, which values are cached in the integration time points. Then
-- these values are interpolated in all other time points.
--

module Simulation.Aivika.Trans.Transform.Memo
       (memoTransform,
        memo0Transform,
        iteratingTransform) where

import Simulation.Aivika.Trans.Dynamics
import Simulation.Aivika.Trans.Dynamics.Memo
import Simulation.Aivika.Trans.Transform
import Simulation.Aivika.Trans.SD

-- | A transform that memoizes and order the computation in the integration time points
-- using the interpolation that knows of the Runge-Kutta method. The values are
-- calculated sequentially starting from 'starttime'.
memoTransform :: MonadSD m => Transform m e e
{-# INLINE memoTransform #-}
memoTransform = Transform memoDynamics 

-- | A transform that memoizes and order the computation in the integration time points using 
-- the 'discreteDynamics' interpolation. It consumes less memory than the 'memoTransform'
-- computation but it is not aware of the Runge-Kutta method. There is a subtle
-- difference when we request for values in the intermediate time points
-- that are used by this method to integrate. In general case you should 
-- prefer the 'memo0Transform' computation above 'memoTransform'.
memo0Transform :: MonadSD m => Transform m e e
{-# INLINE memo0Transform #-}
memo0Transform =  Transform memo0Dynamics

-- | A transform that iterates sequentially the dynamic process with side effects in 
-- the integration time points. It is equivalent to the 'memo0Transform' computation
-- but significantly more efficient, for the internal array is not created.
iteratingTransform :: MonadSD m => Transform m () ()
{-# INLINE iteratingTransform #-}
iteratingTransform = Transform iterateDynamics