sde-solver-0.1.0.0: src/Numeric/DSDE/SDESolver.hs
{-# LANGUAGE MultiParamTypeClasses, TypeSynonymInstances, FlexibleInstances,
BangPatterns, ConstraintKinds #-}
module Numeric.DSDE.SDESolver where
import Numeric.DSDE.SDE.GeometricBrownian
import Numeric.DSDE.RNG
import Numeric.DSDE.SDE
import qualified System.Random.MWC as M
-- | The Euler-Maruyama solving method. Order 1/2.
data EulerMaruyama = EulerMaruyama
-- | The Milstein solving method. Order 1.
data Milstein = Milstein
-- | Type class describing a method of solving SDE problems.
-- Defined by the next value produced in a solving sequence.
class SDESolver a where
w_iplus1 :: (Monad m, SDE sde, RNGGen rng m p, Parameter p) =>
a -> sde p -> rng -> p -> p -> p -> m p
solverName :: a -> String
instance SDESolver EulerMaruyama where
{-# INLINE w_iplus1 #-}
{-# SPECIALIZE w_iplus1 :: EulerMaruyama -> GeometricBrownian Double -> M.GenIO -> Double -> Double -> Double -> IO Double #-}
w_iplus1 _ !sde !rng !t_i !w_i !deltat = getRand rng >>= \rand -> return $
w_i
+ f sde t_i w_i * deltat
+ g sde t_i w_i * deltaB rand
where deltaB r = sqrt deltat * r
solverName _ = "Euler-Maruyama"
instance SDESolver Milstein where
w_iplus1 _ !sde !rng !t_i !w_i !deltat = getRand rng >>= \rand -> return $
w_i
+ f sde t_i w_i * deltat
+ g' * deltaB rand
+ g'/2 * partgoverparty sde t_i w_i * (deltaB rand^^(2 :: Integer) - deltat)
where
deltaB r = sqrt deltat * r
g' = g sde t_i w_i
solverName _ = "Milstein"