| Title: | eXtended Empirical Mode Decomposition |
|---|---|
| Description: | Signals are decomposed into oscillatory modes by empirical mode decomposition and its ensemble, complementary ensemble, complete ensemble, masked, bivariate and multivariate variants, by variational mode decomposition and its multivariate and successive variants, and by local mean decomposition, iterative filtering, time varying filter empirical mode decomposition and the empirical wavelet transform; the synchrosqueezed wavelet transform is also provided. Empirical mode decomposition is due to Huang et al. (1998) <doi:10.1098/rspa.1998.0193>, its ensemble variant to Wu and Huang (2009) <doi:10.1142/S1793536909000047> and variational mode decomposition to Dragomiretskiy and Zosso (2014) <doi:10.1109/TSP.2013.2288675>. The modes can be described by their instantaneous amplitude and frequency and their Hilbert spectrum, tested as intrinsic mode functions or against white noise, selected by energy and compared through orthogonality, mode splitting, reconstruction quality, ensemble dispersion and similarity measures. Acceleration, velocity and displacement records stored as a long table of time, value, quantity and component are decomposed for every record and quantity in one call, with a warning and a regularization of the time grid when it is not uniform. |
| Authors: | Alejandro Verri Kozlowski [aut, cre, cph, trl] (ORCID: <https://orcid.org/0000-0002-8535-1170>), G. Rilling [ctb] (emd.m code), Marcelo A. Colominas [cph] (CEEMDAN distribution of emd.m), Pierre Masselot [ctb] (emdr code), Vinícius Rezende Carvalho [ctb, cph] (ewtpy code), Eduardo Mazoni [cph] (ewtpy code), Jerome Gilles [ctb, cph] (pyewt code; MATLAB EWT code translated in ewtpy), Kathryn Heal [ctb] (MATLAB EWT boundary detection translated in ewtpy), Emanuele Papini [ctb, cph] (fifpy code), Antonio Cicone [ctb] (MATLAB iterative filtering code translated in fifpy), Shubhra Prakash [ctb] (LMD code), Stefano Bianchi [ctb, cph] (pytvfemd code), Alessandro Longo [ctb, cph] (pytvfemd code), Eugene Brevdo [ctb] (Synchrosqueezing Toolbox code ported in SynchWave), Hau-Tieng Wu [ctb] (Synchrosqueezing Toolbox code ported in SynchWave), Jianfeng Lu [ctb] (curve_ext of the Synchrosqueezing Toolbox, ported in SynchWave), Dongik Jang [ctb] (SynchWave code), Hee-Seok Oh [ctb] (SynchWave code), Donghoh Kim [ctb] (SynchWave code) |
| Maintainer: | Alejandro Verri Kozlowski <[email protected]> |
| License: | GPL-3 |
| Version: | 0.1.5 |
| Built: | 2026-11-08 20:51:19 UTC |
| Source: | https://github.com/cran/xemd |
Compares the energy of each intrinsic mode function, from the second on, with the threshold that fractional Gaussian noise of a tabulated Hurst exponent gives at a tabulated level, with the first function as the noise scale.
assessFractionalNoise(modes, hurst, probability)assessFractionalNoise(modes, hurst, probability)
modes |
Finite numeric matrix of 2048 samples by at least two intrinsic mode functions, in their order of extraction and without the residue. |
hurst |
Hurst exponent |
probability |
Level |
The energy of function is . From
on, the reference energy is
and the threshold is
, with
, and of table 3.1 of Flandrin et
al. (2005). A function lies outside when . The
coefficients come from simulations of 10000 realizations of 2048 samples
and are not interpolated to other exponents nor recalibrated for other
lengths. The first function is taken to carry mainly noise; the function
does not verify it.
The result is conditional on that noise model and calibration. Exceeding the threshold does not prove that a component is free of noise or identify its physical source.
A list of vectors with one element per function:
energy |
The energies |
reference |
The reference energies |
upper |
The thresholds |
outside |
Logical, |
A first function of zero energy stops the function with an error of class
xemdZeroEnergy.
Flandrin, P., Gonçalvès, P. and Rilling, G. (2004). Detrending and denoising with empirical mode decompositions. EUSIPCO 2004, 1581–1584.
Flandrin, P., Gonçalvès, P. and Rilling, G. (2005). EMD equivalent filter banks, from interpretation to applications. In N. E. Huang and S. S. P. Shen (eds.), Hilbert-Huang Transform and Its Applications, World Scientific, 57–74.
assessWhiteNoise, decomposeEMD
Time <- seq_len(2048) / 1000 Tones <- cbind(cos(2 * pi * 2 * Time), 0.25 * cos(2 * pi * 24 * Time), 0.0625 * cos(2 * pi * 288 * Time)) assessFractionalNoise(Tones, hurst = 0.5, probability = 0.95) # The third tone as the noise scale. assessFractionalNoise(Tones[, c(3, 1, 2)], hurst = 0.5, probability = 0.95)$outsideTime <- seq_len(2048) / 1000 Tones <- cbind(cos(2 * pi * 2 * Time), 0.25 * cos(2 * pi * 24 * Time), 0.0625 * cos(2 * pi * 288 * Time)) assessFractionalNoise(Tones, hurst = 0.5, probability = 0.95) # The third tone as the noise scale. assessFractionalNoise(Tones[, c(3, 1, 2)], hurst = 0.5, probability = 0.95)$outside
Evaluates numerical diagnostics of the intrinsic mode function conditions for each column of a matrix: the balance of extrema and zero crossings, and a double threshold on the envelope mean relative to its amplitude.
assessIMF(modes, thresholds = c(0.05, 0.5), fraction = 0.05, boundary = "reflection")assessIMF(modes, thresholds = c(0.05, 0.5), fraction = 0.05, boundary = "reflection")
modes |
Finite numeric matrix, samples by columns. Attributes other
than |
thresholds |
Two dimensionless numbers |
fraction |
The admitted fraction |
boundary |
|
The ideal envelope condition is a zero local mean. This diagnostic uses tolerances and a specified boundary rule; passing it does not establish recovery of a physical component. For methods defined by other conditions, such as a bandwidth objective, it is an additional EMD-based diagnostic.
count tests , with the extrema and
zero crossings counted as in decomposeEMD.
deviation applies to
and the half sum and the half difference of the
envelopes, the double threshold that accepts a mode under
stopRule = "doubleThreshold": the fraction of samples with
is at most and no sample has
.
A list of two logical vectors with one element per column:
count |
The counting condition. |
deviation |
The double threshold, |
The selection of the reflected extrema and the spline interpolation of the envelope nodes are adapted from emd.m (G. Rilling, March 2007), distributed with CEEMDAN revision af9a0f83, copyright (c) 2020 Marcelo A. Colominas, MIT License; see the NOTICE file of the installed package.
decomposeEMD, assessWhiteNoise
Time <- seq(0, 9, length.out = 3000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time OUT <- decomposeEMD(Signal, sifting = list(stopRule = "doubleThreshold")) # The signal, its modes and its residue as columns. assessIMF(cbind(Signal, OUT$modes, OUT$residue))Time <- seq(0, 9, length.out = 3000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time OUT <- decomposeEMD(Signal, sifting = list(stopRule = "doubleThreshold")) # The signal, its modes and its residue as columns. assessIMF(cbind(Signal, OUT$modes, OUT$residue))
Compares the energy of each mode with reference bounds from a white-noise model at the mode's mean period (test of Wu and Huang).
assessWhiteNoise(modes, probabilities, bound, rescalingMode)assessWhiteNoise(modes, probabilities, bound, rescalingMode)
modes |
Finite numeric matrix, samples by modes. The caller supplies the components of a normalized signal; see Details for the assumptions of the reference distribution. |
probabilities |
Two numbers |
bound |
|
rescalingMode |
|
The energy of mode is and its mean
period is divided by its number of maxima, or
without maxima. The bound of probability is, with
"gaussian" and the standard normal quantile,
and with "chiSquare" , the chi-square
quantile with degrees of freedom. With
rescalingMode = r, the energy of component is placed on its
upper bound and every other energy is multiplied by
. A mode lies outside when its energy is below the
lower bound or above the upper one.
The reference distribution is conditional on the noise model,
normalization and EMD procedure. Interpreting the rescaled test assumes
that the component selected by rescalingMode is dominated by noise;
its mode index does not establish that assumption. Exceeding
a bound does not identify a physical source or prove that a component is
free of noise. A white-noise interpretation of an acceleration record does
not transfer unchanged to modes of its integrated displacement.
A list of vectors with one element per mode:
energy |
The energies, rescaled when |
period |
The mean periods, in samples. |
lower, upper
|
The bounds at those periods. |
outside |
Logical, |
A column of zero energy stops the function with an error of class
xemdZeroEnergy.
Time <- seq(0, 9, length.out = 3000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time # The four summands of the signal, divided by its population deviation. Summands <- cbind(sin(pi * Time), sin(2 * pi * Time), sin(6 * pi * Time), 0.5 * Time) / sqrt(mean((Signal - mean(Signal))^2)) assessWhiteNoise(Summands, probabilities = c(0.025, 0.975), bound = "gaussian", rescalingMode = NULL)$outside assessWhiteNoise(Summands, probabilities = c(0.025, 0.975), bound = "chiSquare", rescalingMode = 1)$outsideTime <- seq(0, 9, length.out = 3000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time # The four summands of the signal, divided by its population deviation. Summands <- cbind(sin(pi * Time), sin(2 * pi * Time), sin(6 * pi * Time), 0.5 * Time) / sqrt(mean((Signal - mean(Signal))^2)) assessWhiteNoise(Summands, probabilities = c(0.025, 0.975), bound = "gaussian", rescalingMode = NULL)$outside assessWhiteNoise(Summands, probabilities = c(0.025, 0.975), bound = "chiSquare", rescalingMode = 1)$outside
Accumulates the instantaneous amplitude, or its square, of every mode in the frequency cell of its instantaneous frequency, sample by sample, and integrates the result over time.
buildHilbertSpectrum(frequency, amplitude, edges, exponent, samplingInterval)buildHilbertSpectrum(frequency, amplitude, edges, exponent, samplingInterval)
frequency |
Numeric matrix, samples by modes, of instantaneous
frequencies in Hz, finite or |
amplitude |
Finite non-negative matrix with the dimensions of
|
edges |
At least two finite, strictly increasing cell edges in Hz;
cell |
exponent |
The power |
samplingInterval |
Sampling interval |
The spectrum holds the mass of each cell,
in units of the signal to the power . A frequency outside the edges
or NA adds nothing. The marginal spectrum of a cell is the time
integral . No scaling or division by the cell
width is applied: the values are masses, not densities. The inputs are
usually the frequency and amplitude of
computeInstantaneousAttributes.
A list with
spectrum |
Double matrix, samples by cells, in units of the signal to
the power |
marginal |
Numeric vector by cell, in units of the signal to the power
|
computeInstantaneousAttributes, decomposeEMD
Time <- seq(0, 9, length.out = 3000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time Modes <- decomposeEMD(Signal, sifting = list(stopRule = "doubleThreshold"))$modes Attributes <- computeInstantaneousAttributes(Modes, samplingInterval = 9 / 2999) OUT <- buildHilbertSpectrum(Attributes$frequency, Attributes$amplitude, edges = c(1, 2, 3, 4, 5), exponent = 2, samplingInterval = 9 / 2999) dim(OUT$spectrum) OUT$marginalTime <- seq(0, 9, length.out = 3000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time Modes <- decomposeEMD(Signal, sifting = list(stopRule = "doubleThreshold"))$modes Attributes <- computeInstantaneousAttributes(Modes, samplingInterval = 9 / 2999) OUT <- buildHilbertSpectrum(Attributes$frequency, Attributes$amplitude, edges = c(1, 2, 3, 4, 5), exponent = 2, samplingInterval = 9 / 2999) dim(OUT$spectrum) OUT$marginal
Computes, for each column of a matrix of modes, the analytic signal and its instantaneous amplitude, continuous phase and frequency.
computeInstantaneousAttributes(modes, samplingInterval)computeInstantaneousAttributes(modes, samplingInterval)
modes |
Finite double matrix, samples by modes, with at least three
rows; it may have zero columns. Attributes other than |
samplingInterval |
Sampling interval |
The analytic signal of each column is
computed with the discrete Fourier transform, multiplying each bin by
: positive frequencies are doubled, negative
ones removed, and the zero bin and, for an even number of samples, the
Nyquist bin keep the factor 1, so . The transform
implies the periodic extension of the record. The amplitude is
. Within each run of samples with , the phase
starts at the principal value of and adds the increments
taken in ; a zero of
leaves its sample undefined (NA) and the next run starts again at
its principal value. The frequency is
in Hz, the central difference of ; it is NA where
one of the three phases is, and each border repeats its neighbour. These
local undefined values raise no condition.
A list of three matrices, samples by modes:
amplitude |
Instantaneous amplitude, in the units of the modes. |
phase |
Continuous phase in radians, |
frequency |
Instantaneous frequency in Hz, |
buildHilbertSpectrum, decomposeEMD,
estimateMaskFrequency
SamplingInterval <- 1 / 1000 Time <- seq_len(1000) * SamplingInterval # Three tones of 2, 24 and 288 Hz as columns. Tones <- cbind(cos(2 * pi * 2 * Time), 0.25 * cos(2 * pi * 24 * Time), 0.0625 * cos(2 * pi * 288 * Time)) OUT <- computeInstantaneousAttributes(Tones, samplingInterval = SamplingInterval) apply(OUT$amplitude, 2, range) apply(OUT$frequency, 2, range)SamplingInterval <- 1 / 1000 Time <- seq_len(1000) * SamplingInterval # Three tones of 2, 24 and 288 Hz as columns. Tones <- cbind(cos(2 * pi * 2 * Time), 0.25 * cos(2 * pi * 24 * Time), 0.0625 * cos(2 * pi * 288 * Time)) OUT <- computeInstantaneousAttributes(Tones, samplingInterval = SamplingInterval) apply(OUT$amplitude, 2, range) apply(OUT$frequency, 2, range)
Decomposes a two-channel signal, read as the complex signal
, by successive extraction of bivariate modes with
envelopes built on projections onto equally spaced directions of the plane.
decomposeBEMD(signal, directionCount = 64, envelope, sifting)decomposeBEMD(signal, directionCount = 64, envelope, sifting)
signal |
Numeric matrix of finite real values with two columns, the real and the imaginary parts, samples in rows. |
directionCount |
Whole number |
envelope |
Mean of the sifting, without default:
|
sifting |
Named list of sifting controls, as in
|
The projection on direction is
. With
"trajectory", interpolates the two-dimensional samples at
the maxima of and the mean is
with "projection", the scalar upper envelope of is
oriented on and the sum is scaled by
. Each extraction subtracts the mean fixedSift times. Before
extraction the decomposition ends with "terminalResidue"
when every projection of has at most one extremum, with
"modeLimit" when equals sifting$maxModes, and with
"insufficientExtrema" when a direction has no envelope. One
extraction serves both channels, so they share the number of modes.
If a direction loses its envelope before fixed sifting completes, the
decomposition stops before adding that vector candidate and preserves
the residue from before the attempt. A candidate that reaches the
iteration limit of an adaptive rule is kept and flagged FALSE. Directions are not dropped from the mean.
A list with
modes |
Double array, samples by modes by channels. |
residue |
Numeric matrix, samples by channels. |
iterations |
Integer vector, the subtractions of each mode. |
converged |
Logical vector by mode: |
stopReason |
|
termination |
Data frame with one row: |
Rilling, G., Flandrin, P., Gonçalves, P. and Lilly, J. M. (2007). Bivariate Empirical Mode Decomposition. IEEE Signal Processing Letters, 14, 936–939.
The selection of the reflected extrema and the spline interpolation of the envelope nodes are adapted from emd.m (G. Rilling, March 2007), distributed with CEEMDAN revision af9a0f83, copyright (c) 2020 Marcelo A. Colominas, MIT License; see the NOTICE file of the installed package.
Time <- 2 * pi * (0:511) / 512 z <- cos(0.3 * Time) * exp(2i * Time) + 0.3 * abs(sin(2.3 * Time)) * exp(17i * Time) Signal <- cbind(Re(z), Im(z)) OUT <- decomposeBEMD(Signal, directionCount = 64, envelope = "projection", sifting = list(stopRule = "fixed", fixedSift = 10, boundary = "extrapolation", maxModes = 3)) dim(OUT$modes) OUT$stopReason max(abs(apply(OUT$modes, c(1, 3), sum) + OUT$residue - Signal))Time <- 2 * pi * (0:511) / 512 z <- cos(0.3 * Time) * exp(2i * Time) + 0.3 * abs(sin(2.3 * Time)) * exp(17i * Time) Signal <- cbind(Re(z), Im(z)) OUT <- decomposeBEMD(Signal, directionCount = 64, envelope = "projection", sifting = list(stopRule = "fixed", fixedSift = 10, boundary = "extrapolation", maxModes = 3)) dim(OUT$modes) OUT$stopReason max(abs(apply(OUT$modes, c(1, 3), sum) + OUT$residue - Signal))
Decomposes pairs of copies of a signal perturbed with the same noise realization of opposite signs and averages the modes of all the copies by extraction order.
decomposeCEEMD(signal, noise, amplitudeRatio = 0.2, sifting)decomposeCEEMD(signal, noise, amplitudeRatio = 0.2, sifting)
signal |
Numeric vector of at least two finite values without
|
noise |
Finite numeric matrix with one row per sample of |
amplitudeRatio |
Dimensionless ratio |
sifting |
Named list of sifting controls, as in
|
For each column, the inputs and are
decomposed by scalar sifting, the positive input first. Each stops before
adding an extraction whose sifting lost its envelopes and keeps its input
in the residue. Accepted adaptive extractions, completed fixed sifting and
extractions that reached the iteration limit are retained.
The decompositions are extended with zero modes to the
largest number of modes and averaged by extraction order,
and the residue is the mean of the residues, so the perturbations
cancel in the reconstruction: rowSums(modes) + residue equals
signal up to rounding. The method has no outer termination and
returns neither meanNoise nor stopReason.
A list with
modes |
Double matrix, samples by modes. |
residue |
Numeric vector, the mean residue of the |
iterations |
Integer vector by mode, the sum of the subtractions of the decompositions that have the mode. |
converged |
Logical vector by mode: |
termination |
Data frame with one row per signed realization:
|
Yeh, J.-R., Shieh, J.-S. and Huang, N. E. (2010). Complementary ensemble empirical mode decomposition: A novel noise enhanced data analysis method. Advances in Adaptive Data Analysis, 2(2), 135–156. doi:10.1142/S1793536910000422
The selection of the reflected extrema and the spline interpolation of the envelope nodes are adapted from emd.m (G. Rilling, March 2007), distributed with CEEMDAN revision af9a0f83, copyright (c) 2020 Marcelo A. Colominas, MIT License; see the NOTICE file of the installed package.
decomposeEEMD, decomposeCEEMDAN,
decomposeICEEMDAN
Time <- seq(0, 9, length.out = 1000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time set.seed(628) Noise <- t(matrix(stats::rnorm(10L * length(Signal)), nrow = 10L, byrow = TRUE)) Sifting <- list(stopRule = "doubleThreshold", thresholds = c(0.05, 0.5), fraction = 0.05, maxSift = 2000, boundary = "reflection", maxModes = Inf) # Two of the ten realizations keep the example short. OUT <- decomposeCEEMD(Signal, noise = Noise[, 1:2], amplitudeRatio = 0.2, sifting = Sifting) dim(OUT$modes) max(abs(rowSums(OUT$modes) + OUT$residue - Signal))Time <- seq(0, 9, length.out = 1000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time set.seed(628) Noise <- t(matrix(stats::rnorm(10L * length(Signal)), nrow = 10L, byrow = TRUE)) Sifting <- list(stopRule = "doubleThreshold", thresholds = c(0.05, 0.5), fraction = 0.05, maxSift = 2000, boundary = "reflection", maxModes = Inf) # Two of the ten realizations keep the example short. OUT <- decomposeCEEMD(Signal, noise = Noise[, 1:2], amplitudeRatio = 0.2, sifting = Sifting) dim(OUT$modes) max(abs(rowSums(OUT$modes) + OUT$residue - Signal))
Extracts each mode as the average first mode of the common residue perturbed by the modes of supplied noise realizations, with a constant ratio of the noise to the residue at each stage.
decomposeCEEMDAN(signal, noise, amplitudeRatio = 0.2, sifting)decomposeCEEMDAN(signal, noise, amplitudeRatio = 0.2, sifting)
signal |
Numeric vector of at least two finite values without
|
noise |
Finite numeric matrix with one row per sample of |
amplitudeRatio |
Dimensionless ratio |
sifting |
Named list of sifting controls, as in
|
Each column of noise is decomposed once with sifting,
, and . From
, before stage the common residue ends
the decomposition, in this order, with "terminalResidue" when it has
at most one extremum, with "modeLimit" when equals
sifting$maxModes and with "insufficientExtrema" when its
envelopes cannot be built. Stage perturbs with
,
,
and computes
A realization without contributes a null perturbation, and
a perturbed residue without a first mode contributes zero; both stay in the
divisor .
A list with
modes |
Double matrix, samples by modes. |
residue |
Numeric vector, the final common residue. |
iterations |
Integer vector by mode, the sum of the subtractions of
the |
converged |
Logical vector by mode: |
stopReason |
|
A noise mode of zero standard deviation leaves its scale undefined and
stops the function with an error of class xemdZeroEnergy.
Torres, M. E., Colominas, M. A., Schlotthauer, G. and Flandrin, P. (2011). A complete ensemble empirical mode decomposition with adaptive noise. In 2011 IEEE International Conference on Acoustics, Speech and Signal Processing (ICASSP), 4144–4147. doi:10.1109/ICASSP.2011.5947265
The selection of the reflected extrema and the spline interpolation of the envelope nodes are adapted from emd.m (G. Rilling, March 2007), distributed with CEEMDAN revision af9a0f83, copyright (c) 2020 Marcelo A. Colominas, MIT License; see the NOTICE file of the installed package.
decomposeICEEMDAN, decomposeEEMD,
decomposeCEEMD
Time <- seq(0, 9, length.out = 1000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time set.seed(628) Noise <- t(matrix(stats::rnorm(10L * length(Signal)), nrow = 10L, byrow = TRUE)) # Two of the ten realizations and three modes keep the example short. Sifting <- list(stopRule = "doubleThreshold", thresholds = c(0.05, 0.5), fraction = 0.05, maxSift = 2000, boundary = "reflection", maxModes = 3) OUT <- decomposeCEEMDAN(Signal, noise = Noise[, 1:2], amplitudeRatio = 0.2, sifting = Sifting) dim(OUT$modes) OUT$stopReason max(abs(rowSums(OUT$modes) + OUT$residue - Signal))Time <- seq(0, 9, length.out = 1000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time set.seed(628) Noise <- t(matrix(stats::rnorm(10L * length(Signal)), nrow = 10L, byrow = TRUE)) # Two of the ten realizations and three modes keep the example short. Sifting <- list(stopRule = "doubleThreshold", thresholds = c(0.05, 0.5), fraction = 0.05, maxSift = 2000, boundary = "reflection", maxModes = 3) OUT <- decomposeCEEMDAN(Signal, noise = Noise[, 1:2], amplitudeRatio = 0.2, sifting = Sifting) dim(OUT$modes) OUT$stopReason max(abs(rowSums(OUT$modes) + OUT$residue - Signal))
Decomposes noise-perturbed copies of a signal by scalar sifting and averages their completed modes by extraction order.
decomposeEEMD(signal, noise, amplitudeRatio = 0.2, divisor, sifting)decomposeEEMD(signal, noise, amplitudeRatio = 0.2, divisor, sifting)
signal |
Numeric vector of at least two finite values without
|
noise |
Finite numeric matrix with one row per sample of |
amplitudeRatio |
Dimensionless ratio |
divisor |
Categorical, without default: |
sifting |
Named list of sifting controls, as in
|
Realization is with
; it is decomposed
by scalar sifting with sifting, in the order of the columns of
noise. Each realization stops before adding an extraction whose sifting lost
its envelopes and keeps the input of that attempt in its residue. Accepted
adaptive extractions, completed fixed sifting and extractions that reached
the iteration limit are retained, the last ones flagged FALSE. Absent modes are extended with zeros, and
mode is
with "realizations", or the same sum divided by with
"available". The residue is the mean of the final residues
and meanNoise the mean of the added perturbations, so that with
"realizations" the modes, the residue and signal satisfy
rowSums(modes) + residue = signal + meanNoise up to rounding. A
realization without modes contributes zeros to the modes and its input to
the residue. Matching by extraction order does not establish a physical
correspondence between the modes of different realizations.
The method has no outer termination, so the result has no
stopReason. The number of realizations has no default; the audited
libraries use 100 (PyEMD), 250 (libeemd) and 4 (emd 0.8.1). hht divides by
and PyEMD by .
A list with
modes |
Double matrix, samples by modes, with as many columns as the largest number of modes among the realizations. |
residue |
Numeric vector, the mean final residue. |
meanNoise |
Numeric vector, the mean added perturbation, in the units
of |
iterations |
Integer vector by mode, the sum of the subtractions of the realizations that have the mode. |
converged |
Logical vector by mode: |
termination |
Data frame with one row per realization:
|
Wu, Z. and Huang, N. E. (2009). Ensemble empirical mode decomposition: A noise-assisted data analysis method. Advances in Adaptive Data Analysis, 1(1), 1–41. doi:10.1142/S1793536909000047
The selection of the reflected extrema and the spline interpolation of the envelope nodes are adapted from emd.m (G. Rilling, March 2007), distributed with CEEMDAN revision af9a0f83, copyright (c) 2020 Marcelo A. Colominas, MIT License; see the NOTICE file of the installed package.
decomposeCEEMD, decomposeCEEMDAN,
decomposeICEEMDAN, resiftModes,
measureDispersion
Time <- seq(0, 9, length.out = 1000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time set.seed(628) Noise <- t(matrix(stats::rnorm(10L * length(Signal)), nrow = 10L, byrow = TRUE)) Sifting <- list(stopRule = "doubleThreshold", thresholds = c(0.05, 0.5), fraction = 0.05, maxSift = 2000, boundary = "reflection", maxModes = Inf) # Two of the ten realizations keep the example short. OUT <- decomposeEEMD(Signal, noise = Noise[, 1:2], amplitudeRatio = 0.2, divisor = "realizations", sifting = Sifting) dim(OUT$modes) OUT$iterations max(abs(rowSums(OUT$modes) + OUT$residue - Signal - OUT$meanNoise))Time <- seq(0, 9, length.out = 1000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time set.seed(628) Noise <- t(matrix(stats::rnorm(10L * length(Signal)), nrow = 10L, byrow = TRUE)) Sifting <- list(stopRule = "doubleThreshold", thresholds = c(0.05, 0.5), fraction = 0.05, maxSift = 2000, boundary = "reflection", maxModes = Inf) # Two of the ten realizations keep the example short. OUT <- decomposeEEMD(Signal, noise = Noise[, 1:2], amplitudeRatio = 0.2, divisor = "realizations", sifting = Sifting) dim(OUT$modes) OUT$iterations max(abs(rowSums(OUT$modes) + OUT$residue - Signal - OUT$meanNoise))
Decomposes a signal by successive extraction: each component is obtained by sifting the current residue and is subtracted from that residue. Its numerical acceptance depends on the selected stopping rule.
decomposeEMD(signal, sifting)decomposeEMD(signal, sifting)
signal |
Numeric vector of finite real values without |
sifting |
Named list of sifting controls: |
With , extraction computes the mode
by sifting and updates the residue
so that up to rounding. Before
extraction the decomposition ends, in this order, with
"terminalResidue" when has at most one extremum, with
"modeLimit" when equals sifting$maxModes, and with
"insufficientExtrema" when the boundary rule cannot build the
envelopes of .
Sifting starts from and repeats
, where is the mean of the upper and
lower envelopes of . The envelopes interpolate the maxima and the
minima, extended at both borders by sifting$boundary: a cubic spline
with not-a-knot end conditions through four or more nodes, the parabola
through three and the line through two. A run of equal interior samples
is one extremum at the exact centre of the run. Each state is
examined once, in this order: the stopping rule accepts it
(converged TRUE); equals fixedSift under
"fixed" (converged NA); equals maxSift
under an adaptive rule, or the envelopes of cannot be built
(converged FALSE); otherwise one more subtraction follows.
Non-convergence is reported in converged, without a warning.
A list with
modes |
Double matrix, samples by modes, in the units of
|
residue |
Numeric vector |
iterations |
Integer vector with the number of subtractions of each mode. |
converged |
Logical vector by mode: |
stopReason |
|
The same list configures the extractor of decomposeEEMD,
decomposeCEEMD, decomposeCEEMDAN,
decomposeICEEMDAN, resiftModes,
decomposeMaskedEMD, decomposeIteratedMaskedEMD,
estimateMaskFrequency and, with the restrictions stated in
their help pages, decomposeBEMD, decomposeMEMD
and decomposeNAMEMD. Counts are accepted as doubles with a
whole value.
stopRuleCategorical, without default: "SD",
"Snumber", "doubleThreshold" or "fixed". The rule
"consecutive" belongs to the vector sifting of
decomposeMEMD and is rejected here.
toleranceUnder "SD": dimensionless threshold,
greater than zero, without default. From the state is accepted
when is finite and
below it; the sum runs over all samples, without the factor , and
a null denominator is not regularized. The 1998 formulation proposes
values from 0.2 to 0.3.
stableSiftUnder "Snumber": the count ,
without default. From the state is accepted when the counts of
extrema and zero crossings have stayed equal over
consecutive states and . The 2003 formulation reports
typical values from three to five.
thresholdsUnder "doubleThreshold": two dimensionless
numbers ; default c(0.05, 0.5).
fractionUnder "doubleThreshold": the admitted
fraction in ; default 0.05. With
, the half sum and the half
difference of the envelopes, the state, the signal included, is accepted
when , the fraction of samples with
is at most and no sample has
. Where the ratio is undefined and
counts as no exceedance; where only it is infinite.
fixedSiftUnder "fixed": the count of
subtractions of every extraction, without default.
maxSiftUnder "SD", "Snumber" and
"doubleThreshold": the count of subtractions after
which an extraction ends without acceptance; under "Snumber"
. Default 2000 under "doubleThreshold", none
under the other rules. The rule "fixed" has no maxSift.
maxModesCount or Inf, the limit of
extractions; default Inf, which extracts until the residue ends the
decomposition.
boundaryCategorical: "reflection" or
"extrapolation"; default "reflection" under
"doubleThreshold" and "fixed", none under "SD" and
"Snumber". "reflection" mirrors two extrema of each family
per side about the first extremum or the border sample and needs three
extrema; "extrapolation" anchors the upper envelope at each border
at the larger of the border sample and the line through the two nearest
maxima, and the lower envelope at the smaller of the border sample and the
line through the two nearest minima.
Huang, N. E., Shen, Z., Long, S. R., Wu, M. C., Shih, H. H., Zheng, Q., Yen, N.-C., Tung, C. C. and Liu, H. H. (1998). The empirical mode decomposition and the Hilbert spectrum for nonlinear and non-stationary time series analysis. Proceedings of the Royal Society of London. Series A, 454, 903–995. doi:10.1098/rspa.1998.0193
The selection of the reflected extrema and the spline interpolation of the envelope nodes are adapted from emd.m (G. Rilling, March 2007), distributed with CEEMDAN revision af9a0f83, copyright Marcelo A. Colominas, MIT License; see the NOTICE file of the installed package.
assessIMF, decomposeEEMD,
decomposeTSL
Time <- seq(0, 9, length.out = 3000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time Sifting <- list(stopRule = "doubleThreshold", thresholds = c(0.05, 0.5), fraction = 0.05, maxSift = 2000, boundary = "reflection", maxModes = Inf) OUT <- decomposeEMD(Signal, sifting = Sifting) dim(OUT$modes) OUT$iterations OUT$stopReason max(abs(rowSums(OUT$modes) + OUT$residue - Signal)) # The rule alone: the other fields take their defaults. identical(decomposeEMD(Signal, sifting = list(stopRule = "doubleThreshold")), OUT) # Ten fixed subtractions per mode, at most three modes. Fixed <- decomposeEMD(Signal, sifting = list(stopRule = "fixed", fixedSift = 10, maxModes = 3)) Fixed$converged Fixed$stopReasonTime <- seq(0, 9, length.out = 3000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time Sifting <- list(stopRule = "doubleThreshold", thresholds = c(0.05, 0.5), fraction = 0.05, maxSift = 2000, boundary = "reflection", maxModes = Inf) OUT <- decomposeEMD(Signal, sifting = Sifting) dim(OUT$modes) OUT$iterations OUT$stopReason max(abs(rowSums(OUT$modes) + OUT$residue - Signal)) # The rule alone: the other fields take their defaults. identical(decomposeEMD(Signal, sifting = list(stopRule = "doubleThreshold")), OUT) # Ten fixed subtractions per mode, at most three modes. Fixed <- decomposeEMD(Signal, sifting = list(stopRule = "fixed", fixedSift = 10, maxModes = 3)) Fixed$converged Fixed$stopReason
Splits the spectrum of a sampled signal at the midpoints between its dominant spectral maxima, or at the boundaries of a detection rule of the EWT code of Gilles, and returns the components of an adapted filter bank, which add up to the signal.
decomposeEWT(signal, samplingInterval, bandCount, detection = NULL)decomposeEWT(signal, samplingInterval, bandCount, detection = NULL)
signal |
Numeric vector of at least four finite values without
|
samplingInterval |
Sampling interval |
bandCount |
Whole number |
detection |
The defaults are the initial values of the EWT code of Gilles; its initial
detector, |
The maxima of the one-sided magnitude of the discrete Fourier transform are
ranked, and the bandCount - 1 largest are retained, or all of them
when fewer exist, so the number of bands adapts to the spectrum. With
and the bins of the retained
maxima, the boundaries are the midpoints
rad per sample, and the last band
closes at . The record is extended by mirroring
samples before it and
after it. On that extension the bank holds an approximation filter and
band filters with cosine transitions of half width ,
below the bound that keeps neighbouring transitions apart. The
analysis coefficients are
, and each component
applies the dual filter ,
restricted to the record, so the components add up to the signal. The components are defined by the filter bank, without imposing the IMF conditions of EMD. The method has no iterative stopping rule.
A detection list works on the one-sided magnitude , or on its
natural logarithm, and on its regularization , the central
values of the full convolution of with the weights ,
, from position
: for
"average" and
,
, for "gaussian"; "none" keeps
. "locmax" places the midpoints above on the maxima of
. "locmaxmin" and "locmaxminf" need
bandCount - 1 positive maxima of and retain the largest; on
the interval from the first cell to the first retained maximum and on those
between consecutive retained maxima, endpoints included, the boundary is
the lowest minimum of for "locmaxmin" or of for
"locmaxminf", the upper central one among equal minima, and a
minimum at position gives . No
boundary is completed. With bandCount = NULL, the number of bands is
the number of maxima of the magnitude whose height exceeds
, and
the largest and smallest heights, and the midpoint boundaries
follow; one band returns the signal.
A list with
modes |
Double matrix, samples by bands. |
boundaries |
Numeric vector of the |
Equal magnitudes at the last retained maximum and the first discarded one
leave the selection undefined and stop with an error, as does a frequency
where every filter of the bank vanishes. With a detection list, a zero
magnitude under logarithm = TRUE, fewer than bandCount - 1
positive maxima of or an interval without minimum for
"locmaxmin" and "locmaxminf", boundaries that do not increase
and an automatic count of zero bands stop with an error.
Gilles, J. (2013). Empirical wavelet transform. IEEE Transactions on Signal Processing, 61(16), 3999–4010.
Gilles, J. Empirical Wavelets, MATLAB toolbox, revision 0381208d40352237876b79912013b0f68337133c, https://github.com/jegilles/Empirical-Wavelets.
The detection of the boundaries, the mirror extension and the filter bank are adapted from ewtpy, revision f9ff38bc5cd7859eea58c5b29099f8a503792b63, copyright (c) 2019 Vinícius Carvalho and Eduardo Mazoni, MIT License; the synthesis through the dual bank is adapted from pyewt, revision 9d60a340f34e92356ed4f7a6a8b7044f524455e3, copyright (c) 2024 Jerome Gilles, MIT License. See the NOTICE file of the installed package.
SamplingInterval <- 1 / 1000 Time <- seq_len(1000) * SamplingInterval Signal <- cos(2 * pi * 2 * Time) + 0.25 * cos(2 * pi * 24 * Time) + 0.0625 * cos(2 * pi * 288 * Time) OUT <- decomposeEWT(Signal, samplingInterval = SamplingInterval, bandCount = 3) OUT$boundaries dim(OUT$modes) max(abs(rowSums(OUT$modes) - Signal)) # Automatic count: only the 2 Hz maximum exceeds the threshold of 0.3. dim(decomposeEWT(Signal, samplingInterval = SamplingInterval, bandCount = NULL, detection = list(detector = "locmax", regularization = "none", thresholdRatio = 0.3))$modes) # Lowest minima between the maxima of the regularized magnitude. Time <- seq(0, 9, length.out = 3000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time decomposeEWT(Signal, samplingInterval = 9 / 2999, bandCount = 3, detection = list(detector = "locmaxmin"))$boundariesSamplingInterval <- 1 / 1000 Time <- seq_len(1000) * SamplingInterval Signal <- cos(2 * pi * 2 * Time) + 0.25 * cos(2 * pi * 24 * Time) + 0.0625 * cos(2 * pi * 288 * Time) OUT <- decomposeEWT(Signal, samplingInterval = SamplingInterval, bandCount = 3) OUT$boundaries dim(OUT$modes) max(abs(rowSums(OUT$modes) - Signal)) # Automatic count: only the 2 Hz maximum exceeds the threshold of 0.3. dim(decomposeEWT(Signal, samplingInterval = SamplingInterval, bandCount = NULL, detection = list(detector = "locmax", regularization = "none", thresholdRatio = 0.3))$modes) # Lowest minima between the maxima of the regularized magnitude. Time <- seq(0, 9, length.out = 3000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time decomposeEWT(Signal, samplingInterval = 9 / 2999, bandCount = 3, detection = list(detector = "locmaxmin"))$boundaries
Computes each residue as the average local mean of the previous residue perturbed by a mode of supplied noise realizations, and each mode as the difference between consecutive residues.
decomposeICEEMDAN(signal, noise, amplitudeRatio = 0.2, normalizeNoise, sifting)decomposeICEEMDAN(signal, noise, amplitudeRatio = 0.2, normalizeNoise, sifting)
signal |
Numeric vector of at least two finite values without
|
noise |
Finite numeric matrix with one row per sample of |
amplitudeRatio |
Dimensionless ratio |
normalizeNoise |
|
sifting |
Named list of sifting controls, as in
|
Each column of noise is decomposed once with sifting,
. From , before stage
the common residue ends the decomposition, in this order, with
"terminalResidue" when it has at most one extremum, with
"modeLimit" when equals sifting$maxModes and with
"insufficientExtrema" when its envelopes cannot be built. Stage
perturbs with
, where
and, for , ,
divided by when normalizeNoise is
TRUE; standard deviations use the divisor . With
the average first mode of and
the mean perturbation, the new residue is the mean local mean and the mode
the difference of residues:
A realization without contributes a null perturbation and
stays in the divisor .
A list with
modes |
Double matrix, samples by modes. |
residue |
Numeric vector, the final common residue. |
iterations |
Integer vector by mode, the sum of the subtractions of
the |
converged |
Logical vector by mode: |
stopReason |
|
A noise mode of zero standard deviation leaves its scale undefined and
stops the function with an error of class xemdZeroEnergy.
Colominas, M. A., Schlotthauer, G. and Torres, M. E. (2014). Improved complete ensemble EMD: A suitable tool for biomedical signal processing. Biomedical Signal Processing and Control, 14, 19–29. doi:10.1016/j.bspc.2014.06.009
The selection of the reflected extrema and the spline interpolation of the envelope nodes are adapted from emd.m (G. Rilling, March 2007), distributed with CEEMDAN revision af9a0f83, copyright (c) 2020 Marcelo A. Colominas, MIT License; see the NOTICE file of the installed package.
decomposeCEEMDAN, decomposeEEMD,
decomposeCEEMD
Time <- seq(0, 9, length.out = 1000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time set.seed(628) Noise <- t(matrix(stats::rnorm(10L * length(Signal)), nrow = 10L, byrow = TRUE)) Sifting <- list(stopRule = "doubleThreshold", thresholds = c(0.05, 0.5), fraction = 0.05, maxSift = 2000, boundary = "reflection", maxModes = Inf) # Two of the ten realizations keep the example short. OUT <- decomposeICEEMDAN(Signal, noise = Noise[, 1:2], amplitudeRatio = 0.2, normalizeNoise = TRUE, sifting = Sifting) dim(OUT$modes) OUT$stopReason max(abs(rowSums(OUT$modes) + OUT$residue - Signal))Time <- seq(0, 9, length.out = 1000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time set.seed(628) Noise <- t(matrix(stats::rnorm(10L * length(Signal)), nrow = 10L, byrow = TRUE)) Sifting <- list(stopRule = "doubleThreshold", thresholds = c(0.05, 0.5), fraction = 0.05, maxSift = 2000, boundary = "reflection", maxModes = Inf) # Two of the ten realizations keep the example short. OUT <- decomposeICEEMDAN(Signal, noise = Noise[, 1:2], amplitudeRatio = 0.2, normalizeNoise = TRUE, sifting = Sifting) dim(OUT$modes) OUT$stopReason max(abs(rowSums(OUT$modes) + OUT$residue - Signal))
Decomposes a signal by successive extraction of components, each obtained by iterating the subtraction of a moving average whose filter is a supplied prototype resampled to a support set by the extrema of the residue.
decomposeIF(signal, filter, boundary, tolerance, maxIterations, stretch, maxModes = Inf)decomposeIF(signal, filter, boundary, tolerance, maxIterations, stretch, maxModes = Inf)
signal |
Numeric vector of finite values without |
filter |
Prototype filter, a numeric vector of finite weights of odd length, at least 3. No default. The package tests use the 13 weights that fifpy obtains from its prototype for a half width of 6. |
boundary |
|
tolerance |
Bound of the relative change between consecutive
iterates, greater than zero and less than one. No default; the package
tests use |
maxIterations |
Whole number |
stretch |
Number greater than zero that scales the support of the filter. No default; the package tests use 1.6. |
maxModes |
Whole number |
Before extraction the decomposition ends with
"terminalResidue" when has at most one extremum and
with "modeLimit" when equals maxModes. Otherwise
the half width is
for the extrema of ; from the second extraction a value
that does not exceed the previous half width becomes
. The prototype is resampled to
weights and the iteration
with the moving average under boundary, stops at
the first with
tolerance
(converged TRUE) or after maxIterations
(converged FALSE). Then and
. A shrinking prototype is integrated over
rescaled bins; an enlarged one is interpolated linearly and normalized to a
unit absolute sum. The components are not shown to satisfy the counting
conditions of intrinsic mode functions.
A list with
modes |
Double matrix, samples by components. |
residue |
Numeric vector, the final residue. |
iterations |
Integer vector, the iterations |
converged |
Logical vector by component. |
stopReason |
|
Cicone, A. and Zhou, H. (2018). Numerical Analysis for Iterative Filtering with New Efficient Implementations Based on FFT. arXiv:1802.01359.
The support rule, the resampling of the prototype and both iterations are adapted from fifpy, revision 26e51e7d45e551950dea8be37ece447fc4340296, copyright (c) 2022 Emanuele Papini, MIT License; see the NOTICE file of the installed package.
Time <- seq_len(1000) / 1000 Signal <- cos(2 * pi * 2 * Time) + 0.25 * cos(2 * pi * 24 * Time) + 0.0625 * cos(2 * pi * 288 * Time) Filter <- c(6.6306270449357867e-06, 0.00053827687799438354, 0.0082858777882808092, 0.044245208647455882, 0.11927281750086954, 0.20513332487239222, 0.24503568511284984, 0.20513332487239222, 0.11927281750086952, 0.044245208647455903, 0.0082858777882808109, 0.00053827687799438213, 6.6306270449358087e-06) OUT <- decomposeIF(Signal, filter = Filter, boundary = "periodic", tolerance = sqrt(0.001), maxIterations = 200, stretch = 1.6, maxModes = 3) OUT$iterations OUT$stopReason Zero <- decomposeIF(Signal, filter = Filter, boundary = "zero", tolerance = sqrt(0.001), maxIterations = 200, stretch = 1.6, maxModes = 3) Zero$iterationsTime <- seq_len(1000) / 1000 Signal <- cos(2 * pi * 2 * Time) + 0.25 * cos(2 * pi * 24 * Time) + 0.0625 * cos(2 * pi * 288 * Time) Filter <- c(6.6306270449357867e-06, 0.00053827687799438354, 0.0082858777882808092, 0.044245208647455882, 0.11927281750086954, 0.20513332487239222, 0.24503568511284984, 0.20513332487239222, 0.11927281750086952, 0.044245208647455903, 0.0082858777882808109, 0.00053827687799438213, 6.6306270449358087e-06) OUT <- decomposeIF(Signal, filter = Filter, boundary = "periodic", tolerance = sqrt(0.001), maxIterations = 200, stretch = 1.6, maxModes = 3) OUT$iterations OUT$stopReason Zero <- decomposeIF(Signal, filter = Filter, boundary = "zero", tolerance = sqrt(0.001), maxIterations = 200, stretch = 1.6, maxModes = 3) Zero$iterations
Iterates a uniform-phase masked decomposition, updating each mask frequency to the amplitude-weighted mean instantaneous frequency of its mode until a relative-change test passes or the iteration limit is reached (itEMD).
decomposeIteratedMaskedEMD(signal, samplingInterval, initialFrequencies, phaseCount, amplitudeRatio, tolerance = 0.1, maxIterations = 15, sifting)decomposeIteratedMaskedEMD(signal, samplingInterval, initialFrequencies, phaseCount, amplitudeRatio, tolerance = 0.1, maxIterations = 15, sifting)
signal |
Numeric vector of finite real values without |
samplingInterval |
Sampling interval in seconds, a finite number greater than zero, without default. |
initialFrequencies |
Numeric vector of |
phaseCount |
Whole number |
amplitudeRatio |
Dimensionless |
tolerance |
Threshold of the largest relative change of the mask
frequencies, a finite number greater than zero; default |
maxIterations |
Whole number |
sifting |
Named list of sifting controls, as in
|
Iteration decomposes the signal with the uniform-phase masks of
decomposeMaskedEMD, one stage per frequency of
, phases and the amplitude above.
Each frequency is then updated to the mean instantaneous frequency of its
mode weighted by the squared instantaneous amplitude, over the samples where
the frequency is defined,
with and from
computeInstantaneousAttributes. The iteration stops with
"tolerance" when every relative change
is below tolerance, or with
"iterationLimit" after maxIterations updates. The result is the
last decomposition together with the frequencies that produced it.
A list with the fields of decomposeMaskedEMD for the last
decomposition (modes, residue, iterations,
converged) and
stopReason |
|
maskFrequencies |
Numeric vector, the |
maskIterations |
Integer, the number of frequency updates. |
innerStopReason |
The termination of the returned masked
decomposition, with the vocabulary of |
When the masked decomposition has fewer modes than masks the update is
undefined and the function stops with an error of class
xemdInsufficientModes. A mode with zero squared amplitude where its
frequency is defined stops with an error of class xemdZeroEnergy. An
updated frequency that is not positive stops with an error when the
iteration continues.
Fabus, M. S., Quinn, A. J., Warnaby, C. E. and Woolrich, M. W. (2021). Automatic decomposition of electrophysiological data into distinct nonsinusoidal oscillatory modes. Journal of Neurophysiology, 126(5), 1670–1684. doi:10.1152/jn.00315.2021
The selection of the reflected extrema and the spline interpolation of the envelope nodes are adapted from emd.m (G. Rilling, March 2007), distributed with CEEMDAN revision af9a0f83, copyright (c) 2020 Marcelo A. Colominas, MIT License; see the NOTICE file of the installed package.
decomposeMaskedEMD, computeInstantaneousAttributes
Time <- seq(0, 9, length.out = 3000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time Sifting <- list(stopRule = "doubleThreshold", thresholds = c(0.05, 0.5), fraction = 0.05, maxSift = 2000, boundary = "reflection", maxModes = 3) # Three dyadic initial frequencies, with one sample per second. OUT <- decomposeIteratedMaskedEMD(Signal, samplingInterval = 1, initialFrequencies = 55 / 3000 / 2 / 2^(0:2), phaseCount = 4, amplitudeRatio = 1, tolerance = 0.1, maxIterations = 15, sifting = Sifting) OUT$maskFrequencies OUT$maskIterations OUT$stopReasonTime <- seq(0, 9, length.out = 3000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time Sifting <- list(stopRule = "doubleThreshold", thresholds = c(0.05, 0.5), fraction = 0.05, maxSift = 2000, boundary = "reflection", maxModes = 3) # Three dyadic initial frequencies, with one sample per second. OUT <- decomposeIteratedMaskedEMD(Signal, samplingInterval = 1, initialFrequencies = 55 / 3000 / 2 / 2^(0:2), phaseCount = 4, amplitudeRatio = 1, tolerance = 0.1, maxIterations = 15, sifting = Sifting) OUT$maskFrequencies OUT$maskIterations OUT$stopReason
Decomposes a signal by successive extraction of product functions, each obtained by repeated subtraction of a smoothed local mean and division by a smoothed local magnitude.
decomposeLMD(signal, maxIterations, envelopeTolerance, changeTolerance, maxSmoothPasses, maxModes = Inf)decomposeLMD(signal, maxIterations, envelopeTolerance, changeTolerance, maxSmoothPasses, maxModes = Inf)
signal |
Numeric vector of finite values without |
maxIterations |
Whole number |
envelopeTolerance |
Number |
changeTolerance |
Number |
maxSmoothPasses |
Whole number |
maxModes |
Whole number |
The local levels of a function use as nodes its interior extrema and its
first and last samples: consecutive nodes give the mean
and the magnitude
, held between the two nodes. Both levels are
smoothed by a repeated uniform moving average whose half width follows from
the largest gap between nodes and shrinks at the borders; passes repeat
while two consecutive samples are equal, up to maxSmoothPasses.
From , iteration forms
with the smoothed levels of . The extraction ends without that
normalization, with converged TRUE, when one of the two
tolerances is met; it ends with converged FALSE when
has at most one extremum or after maxIterations
normalizations. With normalizations, the product function is
and . Before extraction
the decomposition ends with "terminalResidue" when
has at most one extremum and with "modeLimit" when
equals maxModes. A product function combines an
accumulated amplitude envelope with a normalized oscillation; this
construction does not impose the IMF envelope conditions of EMD.
In the first iteration and carry the units of
the signal, so both tolerances compare magnitudes in those units with
dimensionless quantities; the result depends on the unit only when the
initial magnitude approaches 1 in that unit.
A list with
modes |
Double matrix, samples by product functions. |
residue |
Numeric vector, the final residue. |
iterations |
Integer vector, the number |
converged |
Logical vector by product function. |
stopReason |
|
A local magnitude that is not positive leaves the normalization undefined
and stops the function with an error of class xemdZeroEnvelope.
Smith, J. S. (2005). The local mean decomposition and its application to EEG perception data. Journal of the Royal Society Interface, 2(5), 443–454. doi:10.1098/rsif.2005.0058
The local levels and the extraction of a product function are adapted from LMD 1.2.1 (Shubhra Prakash), revision ec11b721ec7b05f0137eeb67a619b28f62ef85a2, Apache License (>= 2); see the NOTICE file of the installed package.
Time <- seq(0, 9, length.out = 3000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time OUT <- decomposeLMD(Signal, maxIterations = 200, envelopeTolerance = 0.01, changeTolerance = 0.01, maxSmoothPasses = 12, maxModes = 8) dim(OUT$modes) OUT$iterations OUT$stopReasonTime <- seq(0, 9, length.out = 3000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time OUT <- decomposeLMD(Signal, maxIterations = 200, envelopeTolerance = 0.01, changeTolerance = 0.01, maxSmoothPasses = 12, maxModes = 8) dim(OUT$modes) OUT$iterations OUT$stopReason
Decomposes a signal by successive extraction in which each mode is the average first mode of the residue plus sinusoidal masks of several phases, under one of three mask rules: the opposite sine pair of 2005, dyadic masks (EMD-DMS) and uniformly distributed phases (UPEMD).
decomposeMaskedEMD(signal, samplingInterval, masking, sifting)decomposeMaskedEMD(signal, samplingInterval, masking, sifting)
signal |
Numeric vector of finite real values without |
samplingInterval |
Sampling interval in seconds, a finite number greater than zero, without default. Mask frequencies are in Hz. |
masking |
Named list with the field
|
sifting |
Named list of sifting controls, as in
|
From , before stage the decomposition ends, in this
order, with "terminalResidue" when has at most one
extremum, with "modeLimit" when equals
sifting$maxModes or the schedule of masks is exhausted, and with
"insufficientExtrema" when the envelopes of cannot be
built. Otherwise the masks of stage are
, ,
with the first sample as phase origin, and the mode is the average of the
first sifted component of plus each mask,
A stage is retained unless one of its phases has no first mode or loses
its envelopes during sifting; then the decomposition stops before adding
the stage mean or subtracting it from the residue. A phase that reaches
the iteration limit is kept and flags the stage FALSE. The phases and divisor are unchanged.
The rules fix the phases, frequencies and amplitudes:
"pair"Phases and , so the masks
are and the mode is
. The schedule has one stage: the
decomposition ends with "modeLimit" after one extraction unless the
residue is terminal.
"dyadic"Phases 0 and ;
; amplitude times the mean absolute
value of the maxima of the residue.
"uniformPhase"Phases ,
; ; amplitude
times the standard deviation of the residue with
divisor .
The masks are deterministic: the function draws no random numbers.
A list with
modes |
Double matrix, samples by modes. |
residue |
Numeric vector, the final residue. |
iterations |
Integer vector by mode, the sum of the subtractions of the extractions of the stage. |
converged |
Logical vector by mode: |
stopReason |
|
maskFrequencies |
Numeric vector, the mask frequency of each mode in Hz. |
termination |
Data frame with |
Deering, R. and Kaiser, J. F. (2005). The use of a masking signal to improve empirical mode decomposition. In IEEE International Conference on Acoustics, Speech, and Signal Processing (ICASSP), 4, 485–488.
The selection of the reflected extrema and the spline interpolation of the envelope nodes are adapted from emd.m (G. Rilling, March 2007), distributed with CEEMDAN revision af9a0f83, copyright (c) 2020 Marcelo A. Colominas, MIT License; see the NOTICE file of the installed package.
estimateMaskFrequency,
decomposeIteratedMaskedEMD, decomposeEMD
Time <- seq(0, 9, length.out = 3000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time Sifting <- list(stopRule = "doubleThreshold", thresholds = c(0.05, 0.5), fraction = 0.05, maxSift = 2000, boundary = "reflection", maxModes = 3) # Uniform phases, with one sample per second. OUT <- decomposeMaskedEMD(Signal, samplingInterval = 1, masking = list(rule = "uniformPhase", amplitudeRatio = 1, phaseCount = 4), sifting = Sifting) OUT$maskFrequencies OUT$stopReason # The pair of 2005 at the estimated mask frequency. Frequency <- estimateMaskFrequency(Signal, samplingInterval = 1, sifting = Sifting) Pair <- decomposeMaskedEMD(Signal, samplingInterval = 1, masking = list(rule = "pair", frequency = Frequency, amplitude = sqrt(mean((Signal - mean(Signal))^2))), sifting = Sifting) dim(Pair$modes) Pair$stopReasonTime <- seq(0, 9, length.out = 3000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time Sifting <- list(stopRule = "doubleThreshold", thresholds = c(0.05, 0.5), fraction = 0.05, maxSift = 2000, boundary = "reflection", maxModes = 3) # Uniform phases, with one sample per second. OUT <- decomposeMaskedEMD(Signal, samplingInterval = 1, masking = list(rule = "uniformPhase", amplitudeRatio = 1, phaseCount = 4), sifting = Sifting) OUT$maskFrequencies OUT$stopReason # The pair of 2005 at the estimated mask frequency. Frequency <- estimateMaskFrequency(Signal, samplingInterval = 1, sifting = Sifting) Pair <- decomposeMaskedEMD(Signal, samplingInterval = 1, masking = list(rule = "pair", frequency = Frequency, amplitude = sqrt(mean((Signal - mean(Signal))^2))), sifting = Sifting) dim(Pair$modes) Pair$stopReason
Decomposes a signal of two or more channels by successive extraction of vector modes, with vector envelopes built at the maxima of its projections onto directions of the channel space.
decomposeMEMD(signal, directionCount = 64, sifting)decomposeMEMD(signal, directionCount = 64, sifting)
signal |
Numeric matrix of finite real values, samples by channels, with two or more columns, as composed by the caller and without standardization. |
directionCount |
Whole number |
sifting |
Named list of sifting controls, as in
|
The directions map Hammersley points, built from the radical
inverses in the bases of the first primes, to unit vectors
through the angles of get.projections of emdr
1.2.3 (Pierre Masselot); their antipodes complete directions. For each
direction, interpolates the vector samples at the maxima
of the projection , extended by
reflection, and the sifting subtracts the mean of the envelopes,
The adaptive rules act on the projections. "consecutive" accepts when
every projection keeps in consecutiveCount
successive states after a subtraction, the run restarting when one does
not. "doubleThreshold" accepts a state, the signal included, whose
projections all keep and whose ratio
meets the double threshold of
decomposeEMD; is the mean distance of the envelopes
to their mean with "globalMean", or the mean half distance between
the envelopes of antipodal directions with "envelopePairs". Before
extraction the decomposition ends with "terminalResidue"
when every projection of has at most one extremum,
with "modeLimit" when equals sifting$maxModes, and
with "insufficientExtrema" when a direction has no envelope. One
extraction serves all the channels, so they share the number of modes.
A list with
modes |
Double array, samples by modes by channels, in the order of
the columns of |
residue |
Numeric matrix, samples by channels. |
iterations |
Integer vector, the subtractions of each mode. |
converged |
Logical vector by mode, as in |
stopReason |
|
Rehman, N. and Mandic, D. P. (2010). Multivariate empirical mode decomposition. Proceedings of the Royal Society A, 466, 1291–1302. doi:10.1098/rspa.2009.0502
The selection of the reflected extrema and the spline interpolation of the envelope nodes are adapted from emd.m (G. Rilling, March 2007), distributed with CEEMDAN revision af9a0f83, copyright (c) 2020 Marcelo A. Colominas, MIT License; see the NOTICE file of the installed package.
decomposeNAMEMD, decomposeBEMD,
decomposeMVMD, decomposeEMD
Time <- 2 * pi * (0:255) / 256 z <- cos(0.3 * Time) * exp(2i * Time) + 0.3 * abs(sin(2.3 * Time)) * exp(17i * Time) Signal <- cbind(Re(z), Im(z)) OUT <- decomposeMEMD(Signal, directionCount = 64, sifting = list(stopRule = "fixed", fixedSift = 10, boundary = "reflection", maxModes = 3)) dim(OUT$modes) OUT$stopReasonTime <- 2 * pi * (0:255) / 256 z <- cos(0.3 * Time) * exp(2i * Time) + 0.3 * abs(sin(2.3 * Time)) * exp(17i * Time) Signal <- cbind(Re(z), Im(z)) OUT <- decomposeMEMD(Signal, directionCount = 64, sifting = list(stopRule = "fixed", fixedSift = 10, boundary = "reflection", maxModes = 3)) dim(OUT$modes) OUT$stopReason
Decomposes the channels of a sampled multichannel signal into modes whose channel coordinates share one center frequency.
decomposeMVMD(signal, samplingInterval, initialCenters, alpha, tau, fixedZeroCenter, tolerance, maxIterations = 499)decomposeMVMD(signal, samplingInterval, initialCenters, alpha, tau, fixedZeroCenter, tolerance, maxIterations = 499)
signal |
Numeric matrix of finite values, samples by channels, with at least one row and one column, as composed by the caller and without standardization. |
samplingInterval |
Sampling interval |
initialCenters |
Numeric vector of initial center frequencies in Hz,
each in |
alpha |
Penalty |
tau |
Dual ascent step |
fixedZeroCenter |
|
tolerance |
Threshold |
maxIterations |
Whole number |
Each channel is extended and transformed as in decomposeVMD.
In each sweep the coordinate of mode is
with a denominator common to the channels; the new center weights
by the power summed over the channels, and the multiplier of
each channel is updated with step . The iteration stops with
"tolerance" when
,
which cannot happen before the second sweep, or with
"iterationLimit" after maxIterations sweeps. A coordinate
without energy in the previous sweep leaves its ratio undefined, so the
test fails until maxIterations. The channels keep the order
received. The joint bandwidth formulation does not impose the geometrical
IMF conditions of EMD. A shared spectral center does not require identical
amplitudes or instantaneous frequencies across channels.
A list with
modes |
Double array, samples by modes by channels. |
fitResidual |
Numeric matrix, samples by channels,
|
centers |
Numeric vector of the |
iterations |
Integer vector repeating, for every mode, the number of sweeps. |
converged |
Logical vector repeating, for every mode, the result of the joint stopping test. |
stopReason |
|
A mode without energy over all its channels leaves its center undefined and
stops the function with an error of class xemdZeroEnergy.
ur Rehman, N. and Aftab, H. (2019). Multivariate Variational Mode Decomposition. arXiv:1907.04509.
decomposeVMD, decomposeSVMD,
decomposeTSL
SamplingInterval <- 1 / 1000 Time <- seq_len(1000) * SamplingInterval Signal <- cbind(cos(2 * pi * 2 * Time) + 0.25 * cos(2 * pi * 24 * Time) + 0.0625 * cos(2 * pi * 288 * Time), cos(2 * pi * 2 * Time), 0.25 * cos(2 * pi * 24 * Time)) OUT <- decomposeMVMD(Signal, samplingInterval = SamplingInterval, initialCenters = (0:2) / (6 * SamplingInterval), alpha = 2000 * SamplingInterval^2 / (8 * pi^2), tau = 0.5, fixedZeroCenter = FALSE, tolerance = 1e-6, maxIterations = 98) dim(OUT$modes) OUT$centers OUT$stopReasonSamplingInterval <- 1 / 1000 Time <- seq_len(1000) * SamplingInterval Signal <- cbind(cos(2 * pi * 2 * Time) + 0.25 * cos(2 * pi * 24 * Time) + 0.0625 * cos(2 * pi * 288 * Time), cos(2 * pi * 2 * Time), 0.25 * cos(2 * pi * 24 * Time)) OUT <- decomposeMVMD(Signal, samplingInterval = SamplingInterval, initialCenters = (0:2) / (6 * SamplingInterval), alpha = 2000 * SamplingInterval^2 / (8 * pi^2), tau = 0.5, fixedZeroCenter = FALSE, tolerance = 1e-6, maxIterations = 98) dim(OUT$modes) OUT$centers OUT$stopReason
Decomposes a signal together with supplied noise channels by one multivariate decomposition and keeps the coordinates of the signal.
decomposeNAMEMD(signal, noiseChannels, directionCount = 64, sifting)decomposeNAMEMD(signal, noiseChannels, directionCount = 64, sifting)
signal |
Numeric matrix of finite real values, samples by channels, with one or more columns. |
noiseChannels |
Numeric matrix of finite real values with the rows of
|
directionCount |
Whole number of Hammersley points, as in
|
sifting |
Named list of sifting controls, as in
|
The function runs decomposeMEMD on the augmented matrix
and keeps the first
coordinates of every mode, ,
and of the residue. Projections, stopping, iterations and termination are
those of the augmented decomposition. In decomposeTSL the
noise channels are drawn by group with noiseChannelCount and scaled
by noiseRatio times the reference deviation of the group.
A list with the fields of decomposeMEMD; modes has
the channels of signal and residue its
columns.
ur Rehman, N. and Mandic, D. P. (2011). Filter Bank Property of Multivariate Empirical Mode Decomposition. IEEE Transactions on Signal Processing, 59(5), 2421–2426. doi:10.1109/TSP.2011.2106779
The selection of the reflected extrema and the spline interpolation of the envelope nodes are adapted from emd.m (G. Rilling, March 2007), distributed with CEEMDAN revision af9a0f83, copyright (c) 2020 Marcelo A. Colominas, MIT License; see the NOTICE file of the installed package.
Time <- 2 * pi * (0:511) / 512 z <- cos(0.3 * Time) * exp(2i * Time) + 0.3 * abs(sin(2.3 * Time)) * exp(17i * Time) Signal <- cbind(Re(z), Im(z)) set.seed(628) # Two noise channels with 0.02 times the reference deviation of the signal. Noise <- 0.02 * sqrt(mean(apply(Signal, 2, stats::sd)^2)) * matrix(stats::rnorm(512 * 2), nrow = 512) OUT <- decomposeNAMEMD(Signal, noiseChannels = Noise, directionCount = 64, sifting = list(stopRule = "fixed", fixedSift = 1, boundary = "reflection", maxModes = 3)) dim(OUT$modes) dim(OUT$residue)Time <- 2 * pi * (0:511) / 512 z <- cos(0.3 * Time) * exp(2i * Time) + 0.3 * abs(sin(2.3 * Time)) * exp(17i * Time) Signal <- cbind(Re(z), Im(z)) set.seed(628) # Two noise channels with 0.02 times the reference deviation of the signal. Noise <- 0.02 * sqrt(mean(apply(Signal, 2, stats::sd)^2)) * matrix(stats::rnorm(512 * 2), nrow = 512) OUT <- decomposeNAMEMD(Signal, noiseChannels = Noise, directionCount = 64, sifting = list(stopRule = "fixed", fixedSift = 1, boundary = "reflection", maxModes = 3)) dim(OUT$modes) dim(OUT$residue)
Extracts variational modes one at a time from the whole signal, keeping the centers of the modes already extracted fixed, and stops after a known number of modes or when the residual power meets a known noise power.
decomposeSVMD(signal, samplingInterval, initialCenter = 0, alpha, maxAlpha, tau, tolerance, maxIterations = 299, stopping)decomposeSVMD(signal, samplingInterval, initialCenter = 0, alpha, maxAlpha, tau, tolerance, maxIterations = 299, stopping)
signal |
Non-empty numeric vector of finite values without |
samplingInterval |
Sampling interval |
initialCenter |
Initial center of every mode in Hz, in
|
alpha |
Initial penalty |
maxAlpha |
Final penalty, at least |
tau |
Dual ascent step |
tolerance |
Threshold |
maxIterations |
Whole number |
stopping |
Named list with the field
|
The signal is extended and transformed as in decomposeVMD.
Mode is extracted from the whole signal with the centers
of the previous modes fixed. Its
penalty starts at alpha and doubles while below maxAlpha;
when doubling would exceed maxAlpha, one last computation runs at
maxAlpha. Each penalty restarts the inner iteration from the
spectrum and center reached, with a zero multiplier and the penalty
. With
, the inner update is
followed by the new center and the dual ascent, and it stops when the
relative change of is below tolerance or after
maxIterations. Extraction stops with "modeCount" after
modeCount modes; with "noisePower" when
, the mean square of
the residual on the record; or with "modeLimit" after
maxModes modes without meeting it. With maxModes = Inf the
extraction under "noisePower" continues until the condition holds.
The modes keep the extraction order. Their bandwidth formulation does not
impose the geometrical IMF conditions of EMD.
A list with
modes |
Double matrix, samples by modes, in extraction order. |
fitResidual |
Numeric vector |
centers |
Numeric vector of the centers in Hz. |
iterations |
Integer vector by mode, the inner iterations of all its penalties. |
converged |
Logical vector by mode, |
stopReason |
|
A mode without spectral energy leaves its center undefined and stops the
function with an error of class xemdZeroEnergy.
Nazari, M. and Sakhaei, S. M. (2020). Successive variational mode decomposition. Signal Processing, 107610. doi:10.1016/j.sigpro.2020.107610
SamplingInterval <- 1 / 1000 Time <- seq_len(1000) * SamplingInterval Signal <- cos(2 * pi * 2 * Time) + 0.25 * cos(2 * pi * 24 * Time) + 0.0625 * cos(2 * pi * 288 * Time) OUT <- decomposeSVMD(Signal, samplingInterval = SamplingInterval, initialCenter = 0, alpha = 10 * SamplingInterval^2 / (4 * pi^2), maxAlpha = 20000 * SamplingInterval^2 / (4 * pi^2), tau = 0, tolerance = 1e-6, maxIterations = 299, stopping = list(stopRule = "modeCount", modeCount = 5)) OUT$centers OUT$stopReasonSamplingInterval <- 1 / 1000 Time <- seq_len(1000) * SamplingInterval Signal <- cos(2 * pi * 2 * Time) + 0.25 * cos(2 * pi * 24 * Time) + 0.0625 * cos(2 * pi * 288 * Time) OUT <- decomposeSVMD(Signal, samplingInterval = SamplingInterval, initialCenter = 0, alpha = 10 * SamplingInterval^2 / (4 * pi^2), maxAlpha = 20000 * SamplingInterval^2 / (4 * pi^2), tau = 0, tolerance = 1e-6, maxIterations = 299, stopping = list(stopRule = "modeCount", modeCount = 5)) OUT$centers OUT$stopReason
Decomposes the series of a long table of records, grouped by record and quantity, with one method of the package, and returns homogeneous tables for all the methods.
decomposeTSL(TSL, method, control, by)decomposeTSL(TSL, method, control, by)
TSL |
Long table, a data frame or a data.table, with rows, unique
column names and the columns |
method |
One of |
control |
Named list of arguments of |
by |
Character vector naming the metadata columns that identify a
record, or |
A group is a record and an ID; its OCID are the channels of
the group and must share one time grid. Groups follow by ascending
and the IDs "AT", "VT" and "DT" first, then the other
IDs ascending; the OCID of a group ascend. The order of the rows of
TSL does not intervene. A series needs two samples or more, a time
cannot repeat within a series, and the metadata other than by must be
constant within each record, ID and OCID.
The grid of a group is uniform when diff(t) equals the mean step
under all.equal; it is then used
unchanged, with samplingInterval . A grid that is not
uniform is regularized with one warning per group: the step becomes
, with the smallest not below
; the grid is , and each OCID is
interpolated on it by stats::splinefun(method = "monoH.FC"). The
table signal holds the series actually decomposed.
Scalar methods decompose each OCID separately with the same
controls. The coupled methods decompose the matrix of the OCID of a
group in ascending order, without standardization:
decomposeBEMD needs exactly two OCID and
decomposeMEMD at least two; their iterations,
converged, stopReason and centers are common and repeat
for every OCID. The ensembles draw realizationCount unit
normal realizations for each OCID from the random stream of the
caller, in the order group, OCID, realization.
decomposeNAMEMD draws noiseChannelCount channels for
each group and scales them by noiseRatio times
, the sample deviations of the
OCID of the group; the noise channels give no rows. A control valid
for one group and not for another, such as a center above the Nyquist
frequency of a group, stops the operation. Units are not inferred,
validated or converted; the metadata are carried to the output.
Channels are coupled within a record and an ID. The operation does
not impose a kinematic relationship between separate AT, VT and DT groups.
Equal mode indices across those groups do not establish corresponding
physical contributions.
A named list of data.table tables, each with the by columns,
the other metadata, OCID and ID, followed by
signal |
|
modes |
|
residue, fitResidual, meanNoise
|
|
diagnostics |
|
termination |
|
centers, maskFrequencies
|
|
boundaries |
|
Rows follow the by columns, OCID, ID, mode or
boundary, and t.
The regularization of the grid is adapted from .regularize and
.rationalize of gmsp 0.8.0, copyright (c) 2026
Alejandro Verri Kozlowski, MIT License: gmsp starts from the smallest
difference of the times and returns the grid from zero, whereas here the
step starts from the mean and the grid keeps the origin . See the
NOTICE file of the installed package.
listDecompositions, decomposeEMD,
decomposeMVMD
Time <- seq(0, 9, length.out = 3000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time # The same series under three IDs and three components. TSL <- data.table::rbindlist(lapply(c("AT", "VT", "DT"), function(id) { data.table::rbindlist(lapply(c("H1", "H2", "UP"), function(ocid) { data.table::data.table(ID = id, OCID = ocid, t = Time, s = Signal) })) })) OUT <- decomposeTSL(TSL, method = "decomposeEMD", control = list(sifting = list(stopRule = "doubleThreshold")), by = character()) names(OUT) OUT$termination head(OUT$modes) # A coupled method: three channels of one record decomposed together. SamplingInterval <- 1 / 1000 TimeV <- seq_len(1000) * SamplingInterval Series <- cbind(cos(2 * pi * 2 * TimeV) + 0.25 * cos(2 * pi * 24 * TimeV) + 0.0625 * cos(2 * pi * 288 * TimeV), cos(2 * pi * 2 * TimeV), 0.25 * cos(2 * pi * 24 * TimeV)) Record <- data.table::data.table(ID = "AT", OCID = rep(c("H1", "H2", "UP"), each = 1000), t = rep(TimeV, 3), s = as.vector(Series)) Coupled <- decomposeTSL(Record, method = "decomposeMVMD", control = list(initialCenters = (0:2) / (6 * SamplingInterval), alpha = 2000 * SamplingInterval^2 / (8 * pi^2), tau = 0.5, fixedZeroCenter = FALSE, tolerance = 1e-6, maxIterations = 98), by = character()) Coupled$centersTime <- seq(0, 9, length.out = 3000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time # The same series under three IDs and three components. TSL <- data.table::rbindlist(lapply(c("AT", "VT", "DT"), function(id) { data.table::rbindlist(lapply(c("H1", "H2", "UP"), function(ocid) { data.table::data.table(ID = id, OCID = ocid, t = Time, s = Signal) })) })) OUT <- decomposeTSL(TSL, method = "decomposeEMD", control = list(sifting = list(stopRule = "doubleThreshold")), by = character()) names(OUT) OUT$termination head(OUT$modes) # A coupled method: three channels of one record decomposed together. SamplingInterval <- 1 / 1000 TimeV <- seq_len(1000) * SamplingInterval Series <- cbind(cos(2 * pi * 2 * TimeV) + 0.25 * cos(2 * pi * 24 * TimeV) + 0.0625 * cos(2 * pi * 288 * TimeV), cos(2 * pi * 2 * TimeV), 0.25 * cos(2 * pi * 24 * TimeV)) Record <- data.table::data.table(ID = "AT", OCID = rep(c("H1", "H2", "UP"), each = 1000), t = rep(TimeV, 3), s = as.vector(Series)) Coupled <- decomposeTSL(Record, method = "decomposeMVMD", control = list(initialCenters = (0:2) / (6 * SamplingInterval), alpha = 2000 * SamplingInterval^2 / (8 * pi^2), tau = 0.5, fixedZeroCenter = FALSE, tolerance = 1e-6, maxIterations = 98), by = character()) Coupled$centers
Decomposes a signal by successive extraction of components, each obtained by sifting with a local mean that is a B-spline approximation on knots placed by a time-varying cutoff frequency (TVF-EMD).
decomposeTVFEMD(signal, bandwidthThreshold, splineOrder, intermittencyThreshold, maxSift, maxModes = Inf)decomposeTVFEMD(signal, bandwidthThreshold, splineOrder, intermittencyThreshold, maxSift, maxModes = Inf)
signal |
Numeric vector of finite real values without |
bandwidthThreshold |
Dimensionless threshold |
splineOrder |
Whole number |
intermittencyThreshold |
Dimensionless threshold |
maxSift |
Whole number |
maxModes |
Whole number |
Before extraction the decomposition ends with
"terminalResidue" when has fewer than four extrema,
maxima plus minima, and with "modeLimit" when equals
maxModes. A component is obtained by sifting,
where is the periodic least-squares B-spline approximation of
order of on knots at the extrema of
, the cumulative realigned cutoff. Each
iteration extends by symmetric reflection of
samples per side and restores the record
afterwards. The cutoff follows from the amplitude and the frequency
of the analytic signal, interpolated at the minima and at the maxima of
; values above
are lowered to , undefined or non-positive values
are interpolated, and the zones marked by intermittency events, where the
relative variation of the cutoff between consecutive maxima of the signal
exceeds , are replaced by interpolation.
The stopping rule aggregates the relative instantaneous bandwidth
over the samples from to
: is accepted when the mean of
is below , from in the
first component and from in the later ones, or when the samples
with are fewer than . This aggregation of
pytvfemd 0.3.14 replaces the local criterion of the monograph.
converged is FALSE when maxSift subtractions end
without acceptance or when the cutoff or the knots cannot be built.
Acceptance refers to the aggregated rule above; it does not establish the
pointwise narrow-band condition. Neither that rule nor a returned component
guarantees the two classical IMF conditions.
A list with
modes |
Double matrix, samples by components. |
residue |
Numeric vector, the final residue. |
iterations |
Integer vector, the subtractions of each component. |
converged |
Logical vector by component. |
stopReason |
|
The stopping rule and the reflection of the sifting, the end of the decomposition, the interpolation, the bounds and the realignment of the cutoff, the relative bandwidth, the knots and the periodic B-spline approximation are adapted from pytvfemd 0.3.14 (Stefano Bianchi and Alessandro Longo), GPL-3; see the NOTICE file of the installed package.
decomposeEMD, computeInstantaneousAttributes
Time <- seq(0, 9, length.out = 3000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time OUT <- decomposeTVFEMD(Signal, bandwidthThreshold = 0.1, splineOrder = 28, intermittencyThreshold = 0.25, maxSift = 5) dim(OUT$modes) OUT$iterations OUT$stopReasonTime <- seq(0, 9, length.out = 3000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time OUT <- decomposeTVFEMD(Signal, bandwidthThreshold = 0.1, splineOrder = 28, intermittencyThreshold = 0.25, maxSift = 5) dim(OUT$modes) OUT$iterations OUT$stopReason
Decomposes a sampled signal into a given number of modes, each concentrated around a center frequency, by alternating updates of the mode spectra, the centers and a multiplier.
decomposeVMD(signal, samplingInterval, initialCenters, alpha, tau, fixedZeroCenter, tolerance, maxIterations)decomposeVMD(signal, samplingInterval, initialCenters, alpha, tau, fixedZeroCenter, tolerance, maxIterations)
signal |
Non-empty numeric vector of finite values without |
samplingInterval |
Sampling interval |
initialCenters |
Numeric vector of initial center frequencies in Hz,
each in |
alpha |
Penalty |
tau |
Dual ascent step |
fixedZeroCenter |
|
tolerance |
Threshold |
maxIterations |
Whole number |
The record of samples is extended to samples by
reflecting samples at the start and the rest at the
end, and transformed with the unnormalized discrete Fourier transform; the
grid holds in rad/s. Sweeps start from zero mode spectra and
multiplier. In each sweep mode , updated after modes
, is
its center becomes the power-weighted mean of , and the sweep
closes with .
The iteration stops with "tolerance" when
,
which cannot happen before the second sweep, or with
"iterationLimit" after maxIterations sweeps; the last sweep
is returned. The modes are the inverse transforms restricted to the record.
With tau = 0 the penalized formulation permits a nonzero fit residual.
VMD defines its modes through a bandwidth objective, without imposing the
geometrical IMF conditions of EMD.
A list with
modes |
Double matrix, samples by modes, on the input grid. |
fitResidual |
Numeric vector |
centers |
Numeric vector of the |
iterations |
Integer vector repeating, for every mode, the number of sweeps. |
converged |
Logical vector repeating, for every mode, the result of the joint stopping test. |
stopReason |
|
A mode without spectral energy leaves its center undefined and stops the
function with an error of class xemdZeroEnergy.
Dragomiretskiy, K. and Zosso, D. (2014). Variational Mode Decomposition. IEEE Transactions on Signal Processing, 62(3), 531–544. doi:10.1109/TSP.2013.2288675
decomposeMVMD, decomposeSVMD,
decomposeTSL
SamplingInterval <- 1 / 1000 Time <- seq_len(1000) * SamplingInterval Signal <- cos(2 * pi * 2 * Time) + 0.25 * cos(2 * pi * 24 * Time) + 0.0625 * cos(2 * pi * 288 * Time) OUT <- decomposeVMD(Signal, samplingInterval = SamplingInterval, initialCenters = (0:2) / (6 * SamplingInterval), alpha = 2000 * SamplingInterval^2 / (8 * pi^2), tau = 0.5, fixedZeroCenter = FALSE, tolerance = 1e-6, maxIterations = 98) OUT$centers OUT$stopReason max(abs(OUT$fitResidual))SamplingInterval <- 1 / 1000 Time <- seq_len(1000) * SamplingInterval Signal <- cos(2 * pi * 2 * Time) + 0.25 * cos(2 * pi * 24 * Time) + 0.0625 * cos(2 * pi * 288 * Time) OUT <- decomposeVMD(Signal, samplingInterval = SamplingInterval, initialCenters = (0:2) / (6 * SamplingInterval), alpha = 2000 * SamplingInterval^2 / (8 * pi^2), tau = 0.5, fixedZeroCenter = FALSE, tolerance = 1e-6, maxIterations = 98) OUT$centers OUT$stopReason max(abs(OUT$fitResidual))
Returns the name and the installed version of the package.
describeModule()describeModule()
A list with package, the string "xemd", and version,
the installed version as a string.
listOperations, listDecompositions
describeModule()describeModule()
Estimates the frequency of the masking signal of 2005 from the instantaneous amplitude and frequency of the first sifted component of a signal.
estimateMaskFrequency(signal, samplingInterval, sifting)estimateMaskFrequency(signal, samplingInterval, sifting)
signal |
Numeric vector of finite real values without |
samplingInterval |
Sampling interval in seconds, a finite number greater than zero, without default. |
sifting |
Named list of sifting controls, as in
|
With and the instantaneous amplitude and frequency,
computed by computeInstantaneousAttributes, of the first
sifted component without mask, the estimate is
with the sums over the samples where is defined. The result is
the frequency of the rule "pair" of
decomposeMaskedEMD.
A number, the mask frequency in Hz.
A signal without a first extracted component stops with an error. When
the weights sum to zero the estimate is undefined, and the
function stops with an error of class xemdZeroEnergy.
The selection of the reflected extrema and the spline interpolation of the envelope nodes are adapted from emd.m (G. Rilling, March 2007), distributed with CEEMDAN revision af9a0f83, copyright (c) 2020 Marcelo A. Colominas, MIT License; see the NOTICE file of the installed package.
decomposeMaskedEMD, computeInstantaneousAttributes
Time <- seq(0, 9, length.out = 3000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time Sifting <- list(stopRule = "doubleThreshold", thresholds = c(0.05, 0.5), fraction = 0.05, maxSift = 2000, boundary = "reflection", maxModes = 3) # One sample per second, so the result is in cycles per sample. estimateMaskFrequency(Signal, samplingInterval = 1, sifting = Sifting) # The time step of the signal, 9 / 2999 s. estimateMaskFrequency(Signal, samplingInterval = 9 / 2999, sifting = Sifting)Time <- seq(0, 9, length.out = 3000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time Sifting <- list(stopRule = "doubleThreshold", thresholds = c(0.05, 0.5), fraction = 0.05, maxSift = 2000, boundary = "reflection", maxModes = 3) # One sample per second, so the result is in cycles per sample. estimateMaskFrequency(Signal, samplingInterval = 1, sifting = Sifting) # The time step of the signal, 9 / 2999 s. estimateMaskFrequency(Signal, samplingInterval = 9 / 2999, sifting = Sifting)
Extracts ridges of a synchrosqueezed transform one after another by dynamic programming and reconstructs a component from the coefficients in a band around each ridge.
extractSSTModes(transform, frequency, modeCount, penalty = 1000, exclusionWidth = 4, reconstructionWidth, morletCenter)extractSSTModes(transform, frequency, modeCount, penalty = 1000, exclusionWidth = 4, reconstructionWidth, morletCenter)
transform |
Numeric or complex matrix of finite values, samples by
frequency cells, such as the |
frequency |
Increasing positive frequencies of the cells, one per
column of |
modeCount |
Whole number |
penalty |
Dimensionless penalty |
exclusionWidth |
Whole number |
reconstructionWidth |
Whole number |
morletCenter |
Center |
With the coefficients, the frequencies and
, the cost of a cell is
, the sum of
over the matrix. The accumulated cost is
and
over every cell ; the ridge ends at the first cell of least
, and each earlier cell is the first whose residual in that
recurrence is below in modulus. After each ridge ,
the cells from to , clipped to the cells, take
the value , the machine
precision, and the next ridge is extracted with the energy recomputed.
Component sums the original coefficients of its band,
over the cells of the band, with
and
for the Morlet
wavelet of center morletCenter. The bands may overlap, the
components need not add up to the signal, and no residue is returned. The
components are defined by the selected ridge bands, without imposing the
IMF conditions of EMD.
Double matrix, samples by components, one column per ridge.
A transform of zero energy stops the function with an error of class
xemdZeroEnergy. A sample where no cell satisfies the recurrence
within the tolerance stops it with an error.
Daubechies, I., Lu, J. and Wu, H.-T. (2009). Synchrosqueezed wavelet transforms: a tool for empirical mode decomposition. arXiv:0912.2437.
Brevdo, E. and Thakur, G. Synchrosqueezing Toolbox, revision 7e9fec0c6c9ed478dafac4479c0658d24fc6d8ef, functions curve_ext (original code by Jianfeng Lu), curve_ext_multi and synsq_cwt_iw, https://github.com/ebrevdo/synchrosqueezing.
The extraction of the ridges is adapted from curve_ext (original author
Jianfeng Lu, maintainer Eugene Brevdo) and curve_ext_multi of the
Synchrosqueezing Toolbox, as ported in SynchWave 1.1.2, revision
9ac80b2c3e60b417d0ee5567a66e8e64faa1a979 (port by Dongik Jang), and the
inversion from SynchWave 1.1.2 (MATLAB original by Eugene Brevdo; R port by
Dongik Jang, Hee-Seok Oh and Donghoh Kim), LGPL-2.0-or-later, which xemd
distributes under GPL-3 as section 3 of the GNU Library General Public
License version 2 permits; see the NOTICE file of the installed package.
SamplingInterval <- 1 / 1000 Time <- seq_len(1000) * SamplingInterval Signal <- cos(2 * pi * 2 * Time) + 0.25 * cos(2 * pi * 24 * Time) + 0.0625 * cos(2 * pi * 288 * Time) SST <- transformSST(Signal, samplingInterval = SamplingInterval, voiceCount = 16, morletCenter = 2 * pi, threshold = sqrt(.Machine$double.eps)) Modes <- extractSSTModes(SST$transform, frequency = SST$frequency, modeCount = 3, reconstructionWidth = 0, morletCenter = 2 * pi) dim(Modes) sqrt(colMeans(Modes^2))SamplingInterval <- 1 / 1000 Time <- seq_len(1000) * SamplingInterval Signal <- cos(2 * pi * 2 * Time) + 0.25 * cos(2 * pi * 24 * Time) + 0.0625 * cos(2 * pi * 288 * Time) SST <- transformSST(Signal, samplingInterval = SamplingInterval, voiceCount = 16, morletCenter = 2 * pi, threshold = sqrt(.Machine$double.eps)) Modes <- extractSSTModes(SST$transform, frequency = SST$frequency, modeCount = 3, reconstructionWidth = 0, morletCenter = 2 * pi) dim(Modes) sqrt(colMeans(Modes^2))
Returns the names of the decomposition methods that decomposeTSL
accepts.
listDecompositions()listDecompositions()
The scalar decompositions are applied to each OCID of a group and
the coupled ones (decomposeBEMD, decomposeMEMD,
decomposeNAMEMD and decomposeMVMD) to the
OCID of a group together. transformSST, the analysis
operations, resiftModes and
estimateMaskFrequency have no record operation.
Character vector of function names: the thirteen scalar methods followed by the four coupled ones.
listDecompositions()listDecompositions()
Lists the exported functions of the package with the names of their formal arguments.
listOperations()listOperations()
The list reads the exports of the loaded namespace; it performs no decomposition and reads no files.
A list with one element per exported function, in the order of
sort() on their names; each element is a list with name, the
function name, and arguments, the names of its formal arguments.
describeModule, listDecompositions
Operations <- listOperations() length(Operations) Operations[[1]]Operations <- listOperations() length(Operations) Operations[[1]]
Computes, sample by sample and mode by mode, the sample variance of the members of an ensemble around their mean, and that sample variance divided by the number of members. The latter estimates the variance of the mean under the assumptions stated below.
measureDispersion(realizations)measureDispersion(realizations)
realizations |
Finite numeric array with three dimensions, samples by modes by realizations, with at least two realizations. The modes of each realization occupy their extraction order, and a mode absent from a realization is filled with zeros. |
With realizations and their mean , the
sample variance is
and the returned estimate for the variance of the mean is .
The first describes dispersion between members. Interpreting the second
as Monte Carlo precision assumes comparable components and independent
realizations with a common mean and a common finite covariance.
Opposite perturbations in a complementary pair are dependent; the two
signs do not provide independent realizations for this interpretation.
The function does not establish these statistical assumptions or physical
correspondence between equal mode indices. Dispersion under perturbations
of a fixed record does not quantify all uncertainty in the physical signal,
and increasing the number of members does not remove decomposition bias.
Attributes of realizations other than dim do not reach the
outputs.
A list with two matrices, samples by modes:
variance |
The sample variance |
meanVariance |
The estimate |
# Two realizations of four samples: the first has two modes, the second # one, so its second mode is filled with zeros. Realizations <- array(c(2, 4, 6, 8, 1, 1, 1, 1, 4, 6, 8, 10, 0, 0, 0, 0), dim = c(4, 2, 2)) measureDispersion(Realizations)# Two realizations of four samples: the first has two modes, the second # one, so its second mode is filled with zeros. Realizations <- array(c(2, 4, 6, 8, 1, 1, 1, 1, 4, 6, 8, 10, 0, 0, 0, 0), dim = c(4, 2, 2)) measureDispersion(Realizations)
Computes the dynamic time warping distance between a signal and each of its modes.
measureDTW(signal, modes)measureDTW(signal, modes)
signal |
Non-empty finite numeric vector without |
modes |
Finite numeric matrix with one row per sample of
|
With the local cost and the accumulation
and infinite cost outside the matrix, the distance is
, without normalization by the length of the path. The
work grows with the square of the number of samples for each mode.
Numeric vector with one distance per mode, in the units of the signal.
Time <- seq_len(1000) / 1000 Tones <- cbind(cos(2 * pi * 2 * Time), 0.25 * cos(2 * pi * 24 * Time), 0.0625 * cos(2 * pi * 288 * Time)) measureDTW(signal = rowSums(Tones), modes = Tones)Time <- seq_len(1000) / 1000 Tones <- cbind(cos(2 * pi * 2 * Time), 0.25 * cos(2 * pi * 24 * Time), 0.0625 * cos(2 * pi * 288 * Time)) measureDTW(signal = rowSums(Tones), modes = Tones)
Computes the fault correlation factor between a signal and each of its modes, a normalized inner product without removal of means.
measureFCF(signal, modes)measureFCF(signal, modes)
signal |
Finite numeric vector without |
modes |
Finite numeric matrix with one row per sample of
|
The means are not removed, so the factor differs from a correlation of centered vectors when the inputs have a nonzero mean.
Numeric vector with one factor per mode.
A signal or a mode of zero norm stops the function with an error of class
xemdZeroEnergy.
Time <- seq_len(1000) / 1000 Tones <- cbind(cos(2 * pi * 2 * Time), 0.25 * cos(2 * pi * 24 * Time), 0.0625 * cos(2 * pi * 288 * Time)) measureFCF(signal = rowSums(Tones), modes = Tones)Time <- seq_len(1000) / 1000 Tones <- cbind(cos(2 * pi * 2 * Time), 0.25 * cos(2 * pi * 24 * Time), 0.0625 * cos(2 * pi * 288 * Time)) measureFCF(signal = rowSums(Tones), modes = Tones)
Measures every mode and every series of the tables of
decomposeTSL, for any of its methods: frequency, bandwidth,
energy, energy fraction and mean period of each mode, and number of modes
and energy fractions of the remainder and the energy difference described
by crossFraction for each series.
measureModesTSL(decomposition)measureModesTSL(decomposition)
decomposition |
The list of tables of |
A mode of a series with samples uses the step
of the grid of its group, with its
samples ordered by t; the order of the rows does not intervene. Its
spectrum is that of the VMD family: the mode is extended to
samples by reflecting samples at the
start and the others at the end, is the squared modulus of the
unnormalized discrete Fourier transform of the extension and
, . Then
frequency is the power centroid
and bandwidth the power deviation around it on the same grid,
both in Hz. frequency equals the centers of
decomposeVMD and decomposeSVMD, except a center
fixed at zero, which is not a centroid; in decomposeMVMD it is
the centroid of each channel, not the common center. A mode of zero energy
determines no centroid: its frequency and bandwidth are
NA. energy is ,
energyFraction is , and
meanPeriod is over the number of maxima of
the mode, or without maxima.
For each series, modeCount is the number of its modes;
residueFraction is ,
with its residue or fitResidual, and zero when the
method returns neither, as decomposeEWT; and
crossFraction is
the input-energy fraction left after subtracting modal and remainder
energies. It equals the normalized cross products when the modes and
remainder reconstruct that input. Otherwise it also reflects the
reconstruction discrepancy, as with EEMD's retained meanNoise.
A series without modes has modeCount 0, and its remainder is the
series.
Energy here is a quadratic signal measure, with squared signal units times seconds. Its identification with physical energy requires a relation for the measured quantity. A large modal energy fraction does not establish that the component is free of contamination.
A named list of two data.table tables, each with the keys of
decomposition followed by
metrics |
|
metricsSeries |
|
A series of signal with zero energy leaves its energy fractions
undefined and stops the function with an error of class
xemdZeroEnergy.
decomposeTSL, selectModesTSL,
reconstructTSL
Time <- seq(0, 9, length.out = 3000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time # The same series under three IDs and three components. TSL <- data.table::rbindlist(lapply(c("AT", "VT", "DT"), function(id) { data.table::rbindlist(lapply(c("H1", "H2", "UP"), function(ocid) { data.table::data.table(ID = id, OCID = ocid, t = Time, s = Signal) })) })) Sifting <- list(stopRule = "doubleThreshold") Decomposition <- decomposeTSL(TSL, method = "decomposeEMD", control = list(sifting = Sifting), by = character()) OUT <- measureModesTSL(Decomposition) OUT$metrics[OUT$metrics$OCID == "H1" & OUT$metrics$ID == "AT", ] OUT$metricsSeriesTime <- seq(0, 9, length.out = 3000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time # The same series under three IDs and three components. TSL <- data.table::rbindlist(lapply(c("AT", "VT", "DT"), function(id) { data.table::rbindlist(lapply(c("H1", "H2", "UP"), function(ocid) { data.table::data.table(ID = id, OCID = ocid, t = Time, s = Signal) })) })) Sifting <- list(stopRule = "doubleThreshold") Decomposition <- decomposeTSL(TSL, method = "decomposeEMD", control = list(sifting = Sifting), by = character()) OUT <- measureModesTSL(Decomposition) OUT$metrics[OUT$metrics$OCID == "H1" & OUT$metrics$ID == "AT", ] OUT$metricsSeries
Computes the inner products between the columns of a matrix of components and the cosines of the angles between them.
measureOrthogonality(components)measureOrthogonality(components)
components |
Finite numeric matrix, samples by components. Attributes
other than |
The inner products are the Euclidean products ,
without the sampling interval of the discrete inner product, which cancels
in the cosine
The cosine keeps its sign. The cross products are the terms by which the energy of a sum of components differs from the sum of their energies.
A list of two square matrices, components by components:
innerProduct |
The inner products. |
cosine |
The cosines. |
A column of zero norm stops the function with an error of class
xemdZeroEnergy.
Time <- seq_len(1000) / 1000 Tones <- cbind(cos(2 * pi * 2 * Time), 0.25 * cos(2 * pi * 24 * Time), 0.0625 * cos(2 * pi * 288 * Time)) # The sum of the tones and the tones. OUT <- measureOrthogonality(cbind(rowSums(Tones), Tones)) round(OUT$cosine, 6)Time <- seq_len(1000) / 1000 Tones <- cbind(cos(2 * pi * 2 * Time), 0.25 * cos(2 * pi * 24 * Time), 0.0625 * cos(2 * pi * 288 * Time)) # The sum of the tones and the tones. OUT <- measureOrthogonality(cbind(rowSums(Tones), Tones)) round(OUT$cosine, 6)
Computes the pseudo-mode splitting index of each pair of adjacent modes.
measurePMSI(modes, denominator)measurePMSI(modes, denominator)
modes |
Finite numeric matrix, samples by modes, with at least one
column. Attributes other than |
denominator |
|
For each pair of adjacent columns,
with added to the denominator under "regularized".
Numeric vector with one value per pair of adjacent modes, of length one less than the number of columns.
A pair of adjacent modes with zero energy under "homogeneous" stops
the function with an error of class xemdZeroEnergy.
measureOrthogonality, decomposeMaskedEMD
Time <- seq_len(1000) / 1000 Tones <- cbind(cos(2 * pi * 2 * Time), 0.25 * cos(2 * pi * 24 * Time), 0.0625 * cos(2 * pi * 288 * Time)) Mixed <- cbind(rowSums(Tones), Tones) measurePMSI(Mixed, denominator = "homogeneous") measurePMSI(Mixed, denominator = "regularized")Time <- seq_len(1000) / 1000 Tones <- cbind(cos(2 * pi * 2 * Time), 0.25 * cos(2 * pi * 24 * Time), 0.0625 * cos(2 * pi * 288 * Time)) Mixed <- cbind(rowSums(Tones), Tones) measurePMSI(Mixed, denominator = "homogeneous") measurePMSI(Mixed, denominator = "regularized")
Computes the quality of reconstruction factor of an estimate against a reference component, in decibels.
measureQRF(estimate, reference)measureQRF(estimate, reference)
estimate |
Finite numeric vector without |
reference |
Finite numeric vector without |
Inf when the estimate equals the reference.
A number in dB.
A reference of zero norm is outside the domain of the factor and stops the function with an error.
measureFCF, measureOrthogonality
Time <- seq_len(1000) / 1000 Signal <- cos(2 * pi * 2 * Time) + 0.25 * cos(2 * pi * 24 * Time) + 0.0625 * cos(2 * pi * 288 * Time) # The signal without its third tone, against the signal. measureQRF(estimate = Signal - 0.0625 * cos(2 * pi * 288 * Time), reference = Signal) measureQRF(estimate = Signal, reference = Signal)Time <- seq_len(1000) / 1000 Signal <- cos(2 * pi * 2 * Time) + 0.25 * cos(2 * pi * 24 * Time) + 0.0625 * cos(2 * pi * 288 * Time) # The signal without its third tone, against the signal. measureQRF(estimate = Signal - 0.0625 * cos(2 * pi * 288 * Time), reference = Signal) measureQRF(estimate = Signal, reference = Signal)
Adds up, for each series of the tables of decomposeTSL, the
modes that a selection retains and, unless excluded, the remainder of the
series.
reconstructTSL(decomposition, selection, includeResidue = TRUE)reconstructTSL(decomposition, selection, includeResidue = TRUE)
decomposition |
The list of tables of |
selection |
A table with the keys and |
includeResidue |
|
The reconstruction of a series is the sum of its retained modes and, with
includeResidue, its remainder. A series without retained modes sums
zero, and a method without remainder, as decomposeEWT, adds
none. With every mode and the remainder, the result follows the
reconstruction relation of the selected method. For EMD the sum recovers
the input up to rounding. In decomposeEEMD with the divisor
"realizations", it gives the signal plus meanNoise.
The order of the rows of the tables does not intervene.
A partial sum implements the declared selection; neither the sum nor the choice to include a remainder establishes that the result is free of noise.
A named list with one data.table table, reconstruction: the
keys of decomposition, t and s, on the grid and in the
order of signal.
selectModesTSL, measureModesTSL,
decomposeTSL
Time <- seq(0, 9, length.out = 3000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time # The same series under three IDs and three components. TSL <- data.table::rbindlist(lapply(c("AT", "VT", "DT"), function(id) { data.table::rbindlist(lapply(c("H1", "H2", "UP"), function(ocid) { data.table::data.table(ID = id, OCID = ocid, t = Time, s = Signal) })) })) Sifting <- list(stopRule = "doubleThreshold") Decomposition <- decomposeTSL(TSL, method = "decomposeEMD", control = list(sifting = Sifting), by = character()) Metrics <- measureModesTSL(Decomposition)$metrics # A minimum energy fraction of zero retains every mode: with the residue, # the reconstruction is the signal. Every <- selectModesTSL(Decomposition, metrics = Metrics, criterion = list(rule = "energyFraction", minimum = 0, action = "keep")) Complete <- reconstructTSL(Decomposition, selection = Every$selection) max(abs(Complete$reconstruction$s - Decomposition$signal$s)) # The modes in [2, 15] Hz, without the residue. Band <- selectModesTSL(Decomposition, metrics = Metrics, criterion = list(rule = "band", fMin = 2, fMax = 15, action = "keep")) Filtered <- reconstructTSL(Decomposition, selection = Band$selection, includeResidue = FALSE) head(Filtered$reconstruction)Time <- seq(0, 9, length.out = 3000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time # The same series under three IDs and three components. TSL <- data.table::rbindlist(lapply(c("AT", "VT", "DT"), function(id) { data.table::rbindlist(lapply(c("H1", "H2", "UP"), function(ocid) { data.table::data.table(ID = id, OCID = ocid, t = Time, s = Signal) })) })) Sifting <- list(stopRule = "doubleThreshold") Decomposition <- decomposeTSL(TSL, method = "decomposeEMD", control = list(sifting = Sifting), by = character()) Metrics <- measureModesTSL(Decomposition)$metrics # A minimum energy fraction of zero retains every mode: with the residue, # the reconstruction is the signal. Every <- selectModesTSL(Decomposition, metrics = Metrics, criterion = list(rule = "energyFraction", minimum = 0, action = "keep")) Complete <- reconstructTSL(Decomposition, selection = Every$selection) max(abs(Complete$reconstruction$s - Decomposition$signal$s)) # The modes in [2, 15] Hz, without the residue. Band <- selectModesTSL(Decomposition, metrics = Metrics, criterion = list(rule = "band", fMin = 2, fMax = 15, action = "keep")) Filtered <- reconstructTSL(Decomposition, selection = Band$selection, includeResidue = FALSE) head(Filtered$reconstruction)
Re-sifts a sequence of modes, typically the averaged modes of an ensemble, by extracting the first sifted component of consecutive sums and carrying each remainder to the next mode.
resiftModes(modes, sifting)resiftModes(modes, sifting)
modes |
Finite numeric matrix, samples by modes, with at least two
columns |
sifting |
Named list of sifting controls, as in
|
With , stage extracts
, keeps the remainder and adds
the next mode, . The completed chain returns
modes and the residue with
"chainComplete", and
When does not exist, the chain ends with
"insufficientExtrema", the modes and the
residue , which keeps the same sum.
A list with
modes |
Double matrix, samples by the extracted modes. |
residue |
Numeric vector, the remainder of the chain. |
iterations |
Integer vector, the subtractions of each extraction. |
converged |
Logical vector by extraction, as in
|
stopReason |
|
The selection of the reflected extrema and the spline interpolation of the envelope nodes are adapted from emd.m (G. Rilling, March 2007), distributed with CEEMDAN revision af9a0f83, copyright (c) 2020 Marcelo A. Colominas, MIT License; see the NOTICE file of the installed package.
Time <- seq(0, 9, length.out = 1000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time set.seed(628) Noise <- t(matrix(stats::rnorm(10L * length(Signal)), nrow = 10L, byrow = TRUE)) Sifting <- list(stopRule = "doubleThreshold", thresholds = c(0.05, 0.5), fraction = 0.05, maxSift = 2000, boundary = "reflection", maxModes = Inf) # Two of the ten realizations keep the example short. Modes <- decomposeEEMD(Signal, noise = Noise[, 1:2], amplitudeRatio = 0.2, divisor = "realizations", sifting = Sifting)$modes OUT <- resiftModes(Modes, sifting = Sifting) c(input = ncol(Modes), output = ncol(OUT$modes)) OUT$stopReason max(abs(rowSums(OUT$modes) + OUT$residue - rowSums(Modes)))Time <- seq(0, 9, length.out = 1000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time set.seed(628) Noise <- t(matrix(stats::rnorm(10L * length(Signal)), nrow = 10L, byrow = TRUE)) Sifting <- list(stopRule = "doubleThreshold", thresholds = c(0.05, 0.5), fraction = 0.05, maxSift = 2000, boundary = "reflection", maxModes = Inf) # Two of the ten realizations keep the example short. Modes <- decomposeEEMD(Signal, noise = Noise[, 1:2], amplitudeRatio = 0.2, divisor = "realizations", sifting = Sifting)$modes OUT <- resiftModes(Modes, sifting = Sifting) c(input = ncol(Modes), output = ncol(OUT$modes)) OUT$stopReason max(abs(rowSums(OUT$modes) + OUT$residue - rowSums(Modes)))
Orders the modes by decreasing energy and selects those before the largest drop between consecutive energies.
selectModesEnergy(modes)selectModesEnergy(modes)
modes |
Finite numeric matrix, samples by modes, with at least two
columns. Attributes other than |
The energy of mode is . With the
permutation that orders the energies decreasingly, the selection
keeps with
The source fixes no tie-break, so a largest drop that is zero or not unique stops the function with an error.
Integer vector of the selected column indices, the most energetic first.
Time <- seq_len(1000) / 1000 Tones <- cbind(cos(2 * pi * 2 * Time), 0.25 * cos(2 * pi * 24 * Time), 0.0625 * cos(2 * pi * 288 * Time)) selectModesEnergy(Tones) # The same tones in another order. selectModesEnergy(Tones[, c(3, 1, 2)])Time <- seq_len(1000) / 1000 Tones <- cbind(cos(2 * pi * 2 * Time), 0.25 * cos(2 * pi * 24 * Time), 0.0625 * cos(2 * pi * 288 * Time)) selectModesEnergy(Tones) # The same tones in another order. selectModesEnergy(Tones[, c(3, 1, 2)])
Selects the modes of the tables of decomposeTSL with a
declared criterion: explicit mode indices, a minimum energy fraction or a
frequency band, to keep the modes that meet it or to remove them.
selectModesTSL(decomposition, metrics, criterion)selectModesTSL(decomposition, metrics, criterion)
decomposition |
The list of tables of |
metrics |
The table |
criterion |
A list with
|
The criterion is supplied by the caller. Mode indices, energy fractions and centroid frequencies do not by themselves identify uncontaminated physical components. Equal mode indices in independently decomposed series need not represent the same physical contribution.
The band compares frequency alone, whereas the rules keep.Fo
and remove.Fo of gmsp 0.8.0 require the interval
inside the band.
A named list of two data.table tables:
modes |
The rows of |
selection |
Every mode of |
measureModesTSL, reconstructTSL,
decomposeTSL
Time <- seq(0, 9, length.out = 3000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time # The same series under three IDs and three components. TSL <- data.table::rbindlist(lapply(c("AT", "VT", "DT"), function(id) { data.table::rbindlist(lapply(c("H1", "H2", "UP"), function(ocid) { data.table::data.table(ID = id, OCID = ocid, t = Time, s = Signal) })) })) Sifting <- list(stopRule = "doubleThreshold") Decomposition <- decomposeTSL(TSL, method = "decomposeEMD", control = list(sifting = Sifting), by = character()) Metrics <- measureModesTSL(Decomposition)$metrics # Keep the modes whose frequency lies in [2, 15] Hz. Band <- selectModesTSL(Decomposition, metrics = Metrics, criterion = list(rule = "band", fMin = 2, fMax = 15, action = "keep")) Band$selection[Band$selection$OCID == "H1" & Band$selection$ID == "AT", ] # Remove the first mode of every series of the ID VT. Listed <- data.frame(ID = "VT", mode = 1) First <- selectModesTSL(Decomposition, metrics = Metrics, criterion = list(rule = "modes", modes = Listed, action = "remove")) table(First$selection$ID, First$selection$retained)Time <- seq(0, 9, length.out = 3000) Signal <- sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time # The same series under three IDs and three components. TSL <- data.table::rbindlist(lapply(c("AT", "VT", "DT"), function(id) { data.table::rbindlist(lapply(c("H1", "H2", "UP"), function(ocid) { data.table::data.table(ID = id, OCID = ocid, t = Time, s = Signal) })) })) Sifting <- list(stopRule = "doubleThreshold") Decomposition <- decomposeTSL(TSL, method = "decomposeEMD", control = list(sifting = Sifting), by = character()) Metrics <- measureModesTSL(Decomposition)$metrics # Keep the modes whose frequency lies in [2, 15] Hz. Band <- selectModesTSL(Decomposition, metrics = Metrics, criterion = list(rule = "band", fMin = 2, fMax = 15, action = "keep")) Band$selection[Band$selection$OCID == "H1" & Band$selection$ID == "AT", ] # Remove the first mode of every series of the ID VT. Listed <- data.frame(ID = "VT", mode = 1) First <- selectModesTSL(Decomposition, metrics = Metrics, criterion = list(rule = "modes", modes = Listed, action = "remove")) table(First$selection$ID, First$selection$retained)
Computes the Morlet continuous wavelet transform of a sampled signal and reassigns its coefficients to frequency cells by the instantaneous frequency estimated from the transform.
transformSST(signal, samplingInterval, voiceCount = 16, morletCenter = 2 * pi, threshold)transformSST(signal, samplingInterval, voiceCount = 16, morletCenter = 2 * pi, threshold)
signal |
Numeric vector of at least four finite values without
|
samplingInterval |
Sampling interval |
voiceCount |
Whole number |
morletCenter |
Center |
threshold |
Number greater than zero in the units of the signal: only
coefficients with |
The record is extended by symmetric padding to
samples, and the transform uses
the scales ,
. For each
coefficient above the threshold, the frequency
in Hz goes to the nearest of logarithmic cells from
to , the number of
scales, where the coefficient adds ; the sums are divided by
voiceCount. Estimates that are not positive or fall outside the
cells are not accumulated, and a transform whose energy is below the
machine epsilon gives a zero result. The representation recovers the
signal only approximately. The threshold is in the units of the signal,
so decomposeTSL has no operation for this transform.
A list with
transform |
Complex matrix, samples by frequency cells. |
frequency |
Numeric vector of the cell frequencies in Hz. |
Daubechies, I., Lu, J. and Wu, H.-T. (2009). Synchrosqueezed wavelet transforms: a tool for empirical mode decomposition. arXiv:0912.2437.
The wavelet transform, the Morlet wavelet and the reassignment are adapted
from SynchWave 1.1.2, revision 9ac80b2c3e60b417d0ee5567a66e8e64faa1a979
(MATLAB original by Eugene Brevdo; R port by Dongik Jang, Hee-Seok Oh and
Donghoh Kim; the Synchrosqueezing toolbox attribution also names Hau-Tieng
Wu), LGPL-2.0-or-later, which xemd distributes under GPL-3 as section 3 of
the GNU Library General Public License version 2 permits; see the NOTICE
file of the installed package.
decomposeEWT, computeInstantaneousAttributes
SamplingInterval <- 1 / 1000 Time <- seq_len(1000) * SamplingInterval Signal <- cos(2 * pi * 2 * Time) + 0.25 * cos(2 * pi * 24 * Time) + 0.0625 * cos(2 * pi * 288 * Time) OUT <- transformSST(Signal, samplingInterval = SamplingInterval, voiceCount = 16, morletCenter = 2 * pi, threshold = sqrt(.Machine$double.eps)) dim(OUT$transform) range(OUT$frequency)SamplingInterval <- 1 / 1000 Time <- seq_len(1000) * SamplingInterval Signal <- cos(2 * pi * 2 * Time) + 0.25 * cos(2 * pi * 24 * Time) + 0.0625 * cos(2 * pi * 288 * Time) OUT <- transformSST(Signal, samplingInterval = SamplingInterval, voiceCount = 16, morletCenter = 2 * pi, threshold = sqrt(.Machine$double.eps)) dim(OUT$transform) range(OUT$frequency)