{-# LANGUAGE GADTs #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE FlexibleContexts #-} module Numeric.DDE.Types ( RHS (..) , HistorySnapshot (..) , Input (..) , InputSnapshot (..) , Stepper (..) ) where import Foreign.Storable ( Storable (..) ) import qualified Data.VectorSpace.Free as Free import qualified Data.Vector.Storable as V -- | DDE right-hand side. -- -- Parameter @state@ is and abstraction of a dynamical system's state, -- i.e. it can be a vector of any length (x(t), y(t), ...). newtype RHS state = RHS { _state :: (state, HistorySnapshot state, InputSnapshot) -> state } -- | Input u(t) is one-dimensional newtype InputSnapshot = Inp { _insnap :: Double } -- | Vector of input data points newtype Input = Input { _input :: V.Vector Double } -- | Contains only the required snapshot of history to make steppers (e.g. Heun) work. -- There could be several delay variables newtype HistorySnapshot state = Hist { _histsnap :: state } -- | DDE stepper (all delays are equal). -- -- Stepper is a function of the following arguments: -- -- * Integration step -- * DDE right-hand side -- * Current state vector @(x(t), y(t), ...)@ -- * Two subsequent history snapshots -- * Two subsequent inputs -- -- The result (step) is a new state vector. type Stepper = forall state. ( Functor state, Free.VectorSpace (state Double) , Num (Free.Scalar (state Double)) ) => Free.Scalar (state Double) -> RHS (state Double) -> state Double -> (HistorySnapshot (state Double), HistorySnapshot (state Double)) -> (Double, Double) -> state Double -- NB: to allow multiple delay times, instead of -- (HistorySnapshot state, HistorySnapshot state) -- there should be -- (HistorySnapshot delaystate, HistorySnapshot delaystate). -- i.e. a vector of required delayed values (e.g. x(t-tau1), x(t-tau2), y(t-tau3))