module Synthesizer.Causal.Analysis where
import qualified Synthesizer.Causal.Filter.Recursive.Integration as Integration
import qualified Synthesizer.Causal.Process as Causal
import qualified Synthesizer.Plain.Analysis as Ana
import qualified Algebra.RealRing as RealRing
import Control.Arrow (second, (^<<), (<<^), )
import qualified Data.Map as Map
import NumericPrelude.Numeric
import NumericPrelude.Base
flipFlopHysteresis ::
(Ord y) => (y,y) -> Ana.BinaryLevel -> Causal.T y Ana.BinaryLevel
flipFlopHysteresis bnds = Causal.scanL (Ana.flipFlopHysteresisStep bnds)
deltaSigmaModulation ::
RealRing.C y => Causal.T y Ana.BinaryLevel
deltaSigmaModulation =
Causal.feedback
((Ana.binaryLevelFromBool . (zero <=)) ^<<
Integration.run <<^
uncurry ())
(Causal.consInit zero <<^ Ana.binaryLevelToNumber)
deltaSigmaModulationPositive ::
RealRing.C y => Causal.T (y, y) y
deltaSigmaModulationPositive =
Causal.feedback
((\(threshold,xi) -> if threshold<=xi then threshold else zero) ^<<
second Integration.run <<^
(\((threshold,xi),cum) -> (threshold,xicum)))
(Causal.consInit zero)
movingMedian :: (Ord a) => Int -> Causal.T a a
movingMedian n =
Causal.mapAccumL
(\new (k,queue,oldSet) ->
let set =
Map.insert (new,k) () $
maybe id (\old -> Map.delete (old,k)) (Map.lookup k queue) oldSet
in (fst $ fst $ Map.elemAt (div (Map.size set) 2) set,
(mod (k+1) n, Map.insert k new queue, set)))
(0, Map.empty, Map.empty)