packages feed

emd 0.1.3.0 → 0.1.4.0

raw patch · 5 files changed

+131/−11 lines, 5 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ Numeric.HHT: dominantFreq :: forall v n a. (Vector v a, KnownNat n, Ord a) => HHT v n a -> Vector v n a
+ Numeric.HHT: expectedFreq :: forall v n a. (Vector v a, KnownNat n, Fractional a) => HHT v n a -> Vector v n a
+ Numeric.HHT: hhtDenseSpectrum :: forall v n m a. (Vector v a, KnownNat n, KnownNat m, Num a) => (a -> Finite m) -> HHT v n a -> Vector n (Vector m a)
+ Numeric.HHT: hhtSparseSpectrum :: forall v n a k. (Vector v a, KnownNat n, Ord k, Num a) => (a -> k) -> HHT v n a -> Map (Finite n, k) a
- Numeric.HHT: hhtSpectrum :: forall n a k. (KnownNat n, Ord k, Num a) => (a -> k) -> HHT Vector n a -> Vector n (Map k a)
+ Numeric.HHT: hhtSpectrum :: forall v n a k. (Vector v a, KnownNat n, Ord k, Num a) => (a -> k) -> HHT v n a -> Vector n (Map k a)

Files

CHANGELOG.md view
@@ -1,6 +1,22 @@ Changelog ========= +Version 0.1.4.0+---------------++*August 20, 2018*++<https://github.com/mstksg/emd/releases/tag/v0.1.4.0>++*   `hhtSparseSpectrum` added to *Numeric.HHT* module, for an alternate sparser+    representation of the Hilbert Spectrum.+*   `hhtDenseSpectrum` also added to *Numeric.HHT*, for an alternative denser+    representation.+*   `expectedFrequency` added to *Numeric.HHT* module, to calculate weighted+    average of frequency contributions at each step in time.+*   `dominantFrequency` also added to *Numeric.HHT* to calculate strongest+    frequency at each step in time.+ Version 0.1.3.0 --------------- 
emd.cabal view
@@ -2,10 +2,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 8146e6229308d428ec6ca649537a3ddf860fe609d1d2de6ea2aff6536e75ae9e+-- hash: cae340ee4756e6a3c4e72c728779352322ea841f2e7230892d25b139b413e5f1  name:           emd-version:        0.1.3.0+version:        0.1.4.0 synopsis:       Empirical Mode Decomposition and Hilbert-Huang Transform description:    Please see the README on GitHub at <https://github.com/mstksg/emd#readme> category:       Math
src/Numeric/EMD.hs view
@@ -82,7 +82,10 @@     -- -- | Extend boundaries assuming global periodicity     -- -- | BHPeriodic +-- | @since 0.1.3.0 instance Bi.Binary BoundaryHandler++-- | @since 0.1.3.0 instance Bi.Binary a => Bi.Binary (EMDOpts a)  -- | Default 'EMDOpts'@@ -92,6 +95,7 @@                , eoBoundaryHandler = Just BHSymmetric                } +-- | @since 0.1.3.0 instance Fractional a => Default (EMDOpts a) where     def = defaultEO @@ -119,7 +123,10 @@     | SCAnd (SiftCondition a) (SiftCondition a)   deriving (Show, Eq, Ord, Generic) +-- | @since 0.1.3.0 instance Bi.Binary a => Bi.Binary (SiftCondition a)++-- | @since 0.1.3.0 instance Fractional a => Default (SiftCondition a) where     def = defaultSC @@ -156,6 +163,7 @@                      }   deriving (Show, Generic, Eq, Ord) +-- | @since 0.1.3.0 instance (VG.Vector v a, KnownNat n, Bi.Binary (v a)) => Bi.Binary (EMD v n a) where     put EMD{..} = Bi.put (SVG.fromSized <$> emdIMFs)                *> Bi.put (SVG.fromSized emdResidual)
src/Numeric/EMD/Internal/Spline.hs view
@@ -56,6 +56,7 @@     | SEClamped a a   deriving (Show, Eq, Ord, Generic) +-- | @since 0.1.3.0 instance Bi.Binary a => Bi.Binary (SplineEnd a)  data SplineCoef a = SC { _scAlpha  :: !a      -- ^ a
src/Numeric/HHT.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE BangPatterns                             #-} {-# LANGUAGE DataKinds                                #-} {-# LANGUAGE DeriveGeneric                            #-} {-# LANGUAGE FlexibleContexts                         #-}@@ -26,11 +27,16 @@ -- @since 0.1.2.0  module Numeric.HHT (-    hhtEmd+  -- * Hilbert-Huang Transform+    HHT(..), HHTLine(..)+  , hhtEmd   , hht-  , hhtSpectrum+  -- ** Hilbert-Huang Spectrum+  , hhtSpectrum, hhtSparseSpectrum, hhtDenseSpectrum+  -- ** Properties of spectrum   , marginal, instantaneousEnergy, degreeOfStationarity-  , HHT(..), HHTLine(..)+  , expectedFreq, dominantFreq+  -- ** Options   , EMDOpts(..), defaultEO, BoundaryHandler(..), SiftCondition(..), defaultSC, SplineEnd(..)   -- * Hilbert transforms (internal usage)   , hilbert@@ -41,15 +47,16 @@ import           Data.Complex import           Data.Finite import           Data.Fixed-import           Data.List+import           Data.Foldable+import           Data.Maybe import           Data.Proxy import           Data.Semigroup import           GHC.Generics              (Generic) import           GHC.TypeNats import           Numeric.EMD import qualified Data.Binary               as Bi+import qualified Data.List.NonEmpty        as NE import qualified Data.Map                  as M-import qualified Data.Vector               as V import qualified Data.Vector.Generic       as VG import qualified Data.Vector.Generic.Sized as SVG import qualified Data.Vector.Sized         as SV@@ -63,6 +70,7 @@     }   deriving (Show, Eq, Ord, Generic) +-- | @since 0.1.3.0 instance (VG.Vector v a, KnownNat n, Bi.Binary (v a)) => Bi.Binary (HHTLine v n a) where     put HHTLine{..} = Bi.put (SVG.fromSized hlMags )                    *> Bi.put (SVG.fromSized hlFreqs)@@ -79,6 +87,7 @@ newtype HHT v n a = HHT { hhtLines :: [HHTLine v n a] }   deriving (Show, Eq, Ord, Generic) +-- | @since 0.1.3.0 instance (VG.Vector v a, KnownNat n, Bi.Binary (v a)) => Bi.Binary (HHT v n a)  -- | Directly compute the Hilbert-Huang transform of a given time series.@@ -108,18 +117,62 @@ -- -- Takes a "binning" function to allow you to specify how specific you want -- your frequencies to be.+--+-- See 'hhtSparseSpetrum' for a sparser version, and 'hhtDenseSpectrum' for+-- a denser version. hhtSpectrum-    :: forall n a k. (KnownNat n, Ord k, Num a)+    :: forall v n a k. (VG.Vector v a, KnownNat n, Ord k, Num a)     => (a -> k)     -- ^ binning function.  takes rev/tick freq between 0 and 1.-    -> HHT V.Vector n a+    -> HHT v n a     -> SV.Vector n (M.Map k a) hhtSpectrum f = foldl' ((SV.zipWith . M.unionWith) (+)) (pure mempty) . map go . hhtLines   where-    go :: HHTLine V.Vector n a -> SV.Vector n (M.Map k a)+    go :: HHTLine v n a -> SV.Vector n (M.Map k a)     go HHTLine{..} = SV.generate $ \i ->       M.singleton (f $ hlFreqs `SVG.index` i) (hlMags `SVG.index` i) --- | Compute the marginal spectrum given a Hilbert-Huang Transform.+-- | A sparser vesion of 'hhtSpectrum'.  Compute the full Hilbert-Huang+-- Transform spectrum.  Returns a /sparse/ matrix representing the power at+-- each time step (the @'Finite' n@) and frequency (the @k@).+--+-- Takes a "binning" function to allow you to specify how specific you want+-- your frequencies to be.+--+-- @since 0.1.4.0+hhtSparseSpectrum+    :: forall v n a k. (VG.Vector v a, KnownNat n, Ord k, Num a)+    => (a -> k)     -- ^ binning function.  takes rev/tick freq between 0 and 1.+    -> HHT v n a+    -> M.Map (Finite n, k) a+hhtSparseSpectrum f = M.unionsWith (+) . concatMap go . hhtLines+  where+    go :: HHTLine v n a -> [M.Map (Finite n, k) a]+    go HHTLine{..} = flip fmap (finites @n) $ \i ->+      M.singleton (i, f $ hlFreqs `SVG.index` i) $+        hlMags `SVG.index` i++-- | A denser version of 'hhtSpectrum'.  Compute the full  Hilbert-Huang+-- Transform spectrum, returning a dense matrix (as a vector of vectors)+-- representing the power at each time step and each frequency.+--+-- Takes a "binning" function that maps a frequency to one of @m@ discrete+-- slots, for accumulation in the dense matrix.+--+-- @since 0.1.4.0+hhtDenseSpectrum+    :: forall v n m a. (VG.Vector v a, KnownNat n, KnownNat m, Num a)+    => (a -> Finite m)     -- ^ binning function.  takes rev/tick freq between 0 and 1.+    -> HHT v n a+    -> SV.Vector n (SV.Vector m a)+hhtDenseSpectrum f h = SV.generate $ \i -> SV.generate $ \j ->+    M.findWithDefault 0 (i, j) ss+  where+    ss = hhtSparseSpectrum f h++-- | Compute the marginal spectrum given a Hilbert-Huang Transform. It is+-- similar to a Fourier Transform; it provides the "total power" over the+-- entire time series for each frequency component.+-- -- A binning function is accepted to allow you to specify how specific you -- want your frequencies to be. marginal@@ -132,6 +185,48 @@     go :: HHTLine v n a -> [M.Map k a]     go HHTLine{..} = flip fmap (finites @n) $ \i ->       M.singleton (f $ hlFreqs `SVG.index` i) (hlMags `SVG.index` i)++-- | Returns the "expected value" of frequency at each time step,+-- calculated as a weighted average of all contributions at every frequency+-- at that time step.+--+-- @since 0.1.4.0+expectedFreq+    :: forall v n a. (VG.Vector v a, KnownNat n, Fractional a)+    => HHT v n a+    -> SVG.Vector v n a+expectedFreq HHT{..} = SVG.generate $ \i -> weightedAverage . map (go i) $ hhtLines+  where+    go :: Finite n -> HHTLine v n a -> (a, a)+    go i HHTLine{..} = (hlFreqs `SVG.index` i, hlMags `SVG.index` i)++weightedAverage+    :: (Foldable t, Fractional a)+    => t (a, a)+    -> a+weightedAverage = uncurry (/) . foldl' go (0, 0)+  where+    go (!sx, !sw) (!x, !w) = (sx + x, sw + w)++-- | Returns the dominant frequency (frequency with largest magnitude+-- contribution) at each time step.+-- +-- @since 0.1.4.0+dominantFreq+    :: forall v n a. (VG.Vector v a, KnownNat n, Ord a)+    => HHT v n a+    -> SVG.Vector v n a+dominantFreq HHT{..} = SVG.generate $ \i -> (\(Max (Arg _ x)) -> x)+                                          . sconcat+                                          . fromMaybe err+                                          . NE.nonEmpty+                                          . map (go i)+                                          $ hhtLines+  where+    go :: Finite n -> HHTLine v n a -> ArgMax a a+    go i HHTLine{..} = Max $ Arg (hlMags  `SVG.index` i)+                                 (hlFreqs `SVG.index` i)+    err = errorWithoutStackTrace "Numeric.HHT.dominantFreq: HHT was formed with no Intrinsic Mode Functions"  -- | Compute the instantaneous energy of the time series at every step via -- the Hilbert-Huang Transform.