{-# LANGUAGE NoImplicitPrelude #-}moduleSynthesizer.Plain.Interpolation(T,func,offset,number,zeroPad,constantPad,cyclicPad,extrapolationPad,single,multiRelative,multiRelativeZeroPad,multiRelativeConstantPad,multiRelativeCyclicPad,multiRelativeExtrapolationPad,multiRelativeZeroPadConstant,multiRelativeZeroPadLinear,multiRelativeZeroPadCubic,constant,linear,cubic,piecewise,function,Interpolation.Margin,Interpolation.margin,singleRec,-- for testing)whereimportqualifiedSynthesizer.InterpolationasInterpolationimportSynthesizer.Interpolation(T,offset,number,)importSynthesizer.Interpolation.Module(constant,linear,cubic,piecewise,function,)importqualifiedSynthesizer.State.SignalasSigSimportqualifiedSynthesizer.Plain.SignalasSigimportqualifiedSynthesizer.Plain.Filter.NonRecursiveasFiltNRimportqualifiedAlgebra.ModuleasModuleimportqualifiedAlgebra.RealFieldasRealFieldimportqualifiedAlgebra.RingasRingimportqualifiedAlgebra.AdditiveasAdditiveimportAlgebra.Additive(zero)importData.Maybe(fromMaybe)importqualifiedData.List.HTasListHTimportControl.Monad(guard,)importPreludeBaseimportNumericPrelude{-* Interpolation with various padding methods -}zeroPad::(RealField.Ct)=>(Tty->t->Sig.Ty->a)->y->Tty->t->Sig.Ty->azeroPadinterpolatezipphasex=let(phInt,phFrac)=splitFractionphaseininterpolateipphFrac(FiltNR.delayPadz(offsetip-phInt)(x++repeatz))constantPad::(RealField.Ct)=>(Tty->t->Sig.Ty->a)->Tty->t->Sig.Ty->aconstantPadinterpolateipphasex=let(phInt,phFrac)=splitFractionphasexPad=do(xFirst,_)<-ListHT.viewLx(xBody,xLast)<-ListHT.viewRxreturn(FiltNR.delayPadxFirst(offsetip-phInt)(xBody++repeatxLast))ininterpolateipphFrac(fromMaybe[]xPad){- |
Only for finite input signals.
-}cyclicPad::(RealField.Ct)=>(Tty->t->Sig.Ty->a)->Tty->t->Sig.Ty->acyclicPadinterpolateipphasex=let(phInt,phFrac)=splitFractionphaseininterpolateipphFrac(drop(mod(phInt-offsetip)(lengthx))(cyclex)){- |
The extrapolation may miss some of the first and some of the last points
-}extrapolationPad::(RealField.Ct)=>(Tty->t->Sig.Ty->a)->Tty->t->Sig.Ty->aextrapolationPadinterpolateipphase=interpolateip(phase-fromIntegral(offsetip)){-
This example shows pikes, although there shouldn't be any:
plotList (take 100 $ interpolate (Zero (0::Double)) ipCubic (-0.9::Double) (repeat 0.03) [1,0,1,0.8])
-}{-* Interpolation of multiple values with various padding methods -}func::Tty->t->Sig.Ty->yfuncipphase=Interpolation.funcipphase.SigS.fromListskip::(RealField.Ct)=>Tty->(t,Sig.Ty)->(t,Sig.Ty)skipip(phase0,x0)=let(n,frac)=splitFractionphase0(m,x1)=Sig.dropMarginRem(numberip)nx0in(fromIntegralm+frac,x1)single::(RealField.Ct)=>Tty->t->Sig.Ty->ysingleipphase0x0=uncurry(funcip)$skipip(phase0,x0)-- curry (uncurry (func ip) . skip ip){-
GNUPlot.plotFunc [] (GNUPlot.linearScale 1000 (0,2)) (\t -> single linear (t::Double) [0,4,1::Double])
-}-- | alternative implementation of 'single'singleRec::(Ordt,Ring.Ct)=>Tty->t->Sig.Ty->ysingleRecipphasex=-- check if we are leaving the current intervalmaybe(funcipphasex)(singleRecip(phase-1))(do(_,xs)<-ListHT.viewLxguard(phase>=1&&Sig.lengthAtLeast(numberip)xs)returnxs){-* Interpolation of multiple values with various padding methods -}{- | All values of frequency control must be non-negative. -}multiRelative::(RealField.Ct)=>Tty->t->Sig.Ty->Sig.Tt->Sig.TymultiRelativeipphase0x0=map(uncurry(funcip)).scanl(\(phase,x)freq->skipip(phase+freq,x))(skipip(phase0,x0))multiRelativeZeroPad::(RealField.Ct)=>y->Tty->t->Sig.Tt->Sig.Ty->Sig.TymultiRelativeZeroPadzipphasefsx=zeroPadmultiRelativezipphasexfsmultiRelativeConstantPad::(RealField.Ct)=>Tty->t->Sig.Tt->Sig.Ty->Sig.TymultiRelativeConstantPadipphasefsx=constantPadmultiRelativeipphasexfsmultiRelativeCyclicPad::(RealField.Ct)=>Tty->t->Sig.Tt->Sig.Ty->Sig.TymultiRelativeCyclicPadipphasefsx=cyclicPadmultiRelativeipphasexfs{- |
The extrapolation may miss some of the first and some of the last points
-}multiRelativeExtrapolationPad::(RealField.Ct)=>Tty->t->Sig.Tt->Sig.Ty->Sig.TymultiRelativeExtrapolationPadipphasefsx=extrapolationPadmultiRelativeipphasexfs{-
This example shows pikes, although there shouldn't be any:
plotList (take 100 $ interpolate (Zero (0::Double)) ipCubic (-0.9::Double) (repeat 0.03) [1,0,1,0.8])
-}{-* All-in-one interpolation functions -}multiRelativeZeroPadConstant::(RealField.Ct,Additive.Cy)=>t->Sig.Tt->Sig.Ty->Sig.TymultiRelativeZeroPadConstant=multiRelativeZeroPadzeroconstantmultiRelativeZeroPadLinear::(RealField.Ct,Module.Cty)=>t->Sig.Tt->Sig.Ty->Sig.TymultiRelativeZeroPadLinear=multiRelativeZeroPadzerolinearmultiRelativeZeroPadCubic::(RealField.Ct,Module.Cty)=>t->Sig.Tt->Sig.Ty->Sig.TymultiRelativeZeroPadCubic=multiRelativeZeroPadzerocubic