module Synthesizer.Plain.Filter.LinearPredictive where import qualified Algebra.Field as Field import qualified Algebra.Ring as Ring import qualified Algebra.Additive as Additive import Synthesizer.Plain.Analysis (scalarProduct) import qualified Data.List.Match as ListMatch import qualified Data.List as List import NumericPrelude import PreludeBase import Prelude () {- | Determine optimal filter coefficients and residue by adaptive approximation. The number of initial filter coefficients is used as filter order. -} approxCoefficients :: Field.C a => a -> [a] -> [a] -> [(a,[a])] approxCoefficients k mask0 xs = let infixes = map (ListMatch.take mask0) (List.tails xs) targets = ListMatch.drop mask0 xs in scanl (\(_,mask) (infx,target) -> let residue = target - scalarProduct mask infx norm2 = scalarProduct infx infx in (residue, mask + map ((k*residue/norm2)*) infx)) (zero,mask0) (zip infixes targets) {- mapM print $ take 20 $ drop 2000 $ approxCoefficients (1::Double) [0,0,0,0.1] (iterate (1+) 100) mapM print $ take 20 $ drop 10000 $ approxCoefficients (0.2::Double) [0.1,0] (map sin (iterate (0.03+) 0)) must yield coefficients [-1, 2*cos(0.03::Double)] -}