-- | -- Module: FRP.NetWire.Calculus -- Copyright: (c) 2011 Ertugrul Soeylemez -- License: BSD3 -- Maintainer: Ertugrul Soeylemez -- -- Calculus functions. module FRP.NetWire.Calculus ( -- * Calculus over time derivative, derivativeFrom, integral ) where import Control.DeepSeq import Data.VectorSpace import FRP.NetWire.Wire -- | Differentiate over time. -- -- Inhibits at first instant. derivative :: (Monad m, NFData v, VectorSpace v, Scalar v ~ Double) => Wire m v v derivative = mkGen $ \_ y2 -> return (Left (inhibitEx "Derivative at first instant"), derivativeFrom y2) -- | Differentiate over time. The argument is the value before the -- first instant. -- -- Never inhibits. Feedback by delay. derivativeFrom :: forall m v. (Monad m, NFData v, VectorSpace v, Scalar v ~ Double) => v -> Wire m v v derivativeFrom y1 = derivativeFrom' zeroV y1 where derivativeFrom' :: v -> v -> Wire m v v derivativeFrom' dy' y1 = mkGen $ \(wsDTime -> dt) y2 -> do let dy = (y2 ^-^ y1) ^/ dt dy' `deepseq` return (Right dy, derivativeFrom' dy y2) -- | Integrate over time. The argument is the integration constant. -- -- Never inhibits. Feedback by delay. integral :: (Monad m, NFData v, VectorSpace v, Scalar v ~ Double) => v -> Wire m v v integral x1 = mkGen $ \ws dx -> do let dt = wsDTime ws x2 = x1 ^+^ dt *^ dx x1 `deepseq` return (Right x2, integral x2)