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

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

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

import qualified Synthesizer.State.Signal  as Sig
import qualified Synthesizer.Causal.Process as Causal

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 => Sig.T v -> Sig.T v
run :: forall v. C v => T v -> T v
run =
   forall x acc y. (x -> acc -> Maybe (y, acc)) -> acc -> T x -> T y
Sig.crochetL (\v
x v
acc -> let y :: v
y = v
xforall a. C a => a -> a -> a
+v
acc in forall a. a -> Maybe a
Just (v
y,v
y)) forall a. C a => a
zero
   -- scanl1 (+)

{- |
Integrate with initial condition.
First emitted value is the initial condition.
The signal become one element longer.
-}
{-# INLINE runInit #-}
runInit :: Additive.C v => v -> Sig.T v -> Sig.T v
runInit :: forall v. C v => v -> T v -> T v
runInit = forall acc x. (acc -> x -> acc) -> acc -> T x -> T acc
Sig.scanL forall a. C a => a -> a -> a
(+)


{-# INLINE causal #-}
causal :: Additive.C v => Causal.T v v
causal :: forall v. C v => T v v
causal = forall x. (x -> x -> x) -> T x x
Causal.scanL1 forall a. C a => a -> a -> a
(+)

{- |
Integrate with initial condition.
First emitted value is the initial condition.
The signal become one element longer.
-}
{-# INLINE causalInit #-}
causalInit :: Additive.C v => v -> Causal.T v v
causalInit :: forall v. C v => v -> T v v
causalInit = forall acc x. (acc -> x -> acc) -> acc -> T x acc
Causal.scanL forall a. C a => a -> a -> a
(+)

{- other quadrature methods may follow -}