{-# LANGUAGE NoImplicitPrelude #-}
{- |
Copyright   :  (c) Henning Thielemann 2009
License     :  GPL

Maintainer  :  synthesizer@henning-thielemann.de
Stability   :  provisional
Portability :  requires multi-parameter type classes

Filter operators from calculus
-}
module Synthesizer.Causal.Filter.Recursive.Integration where

import qualified Synthesizer.Causal.Process as Causal
import qualified Control.Monad.Trans.State as State

import qualified Algebra.Additive              as Additive

import NumericPrelude.Numeric
import NumericPrelude.Base



{- |
Integrate with initial value zero.
However the first emitted value is the value of the input signal.
It maintains the length of the signal.
-}
{-# INLINE run #-}
run :: Additive.C v => Causal.T v v
run :: forall v. C v => T v v
run = forall a s b. (a -> State s b) -> s -> T a b
Causal.fromState (\v
x -> forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
State.modify (v
xforall a. C a => a -> a -> a
+) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) s. Monad m => StateT s m s
State.get) forall a. C a => a
zero

{- |
Integrate with initial condition.
First emitted value is the initial condition.
The signal becomes one element longer.
-}
{-# INLINE runInit #-}
runInit :: Additive.C v => v -> Causal.T v v
runInit :: forall v. C v => v -> T v v
runInit = forall a s b. (a -> State s b) -> s -> T a b
Causal.fromState (\v
x -> forall (m :: * -> *) s a. Monad m => (s -> (a, s)) -> StateT s m a
State.state (\v
s -> (v
s, v
sforall a. C a => a -> a -> a
+v
x)))

{- other quadrature methods may follow -}