Decomposition of Time-Series Records
decomposeTSL.RdDecomposes 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.
Arguments
- TSL
Long table, a data frame or a data.table, with rows, unique column names and the columns
t, the time in seconds;s, the sample;ID, the quantity, such as"AT","VT"or"DT"; andOCID, the component.tandsare finite numbers;IDandOCIDare character withoutNA. The other columns are metadata; they cannot take the namesmode,iterations,converged,stopReason,innerStopReason,frequencyorboundary. Also reserved for the selected method arerealizationfor EEMD;realizationandsignfor CEEMD;phasefor MaskedEMD; anddirectionfor BEMD.TSLis not modified.- method
One of
listDecompositions().- control
Named list of arguments of
method, common to all the groups, except those the operation derives for each group:signal,samplingInterval,noiseandnoiseChannels. The ensembles takerealizationCountin place ofnoise;decomposeNAMEMDtakesnoiseChannelCountandnoiseRatio, a finite number \(\ge 0\), in place ofnoiseChannels. Controls in the units of the signal are rejected, because AT, VT and DT do not share units: the rule"pair"ofdecomposeMaskedEMDand anystopping$stopRuleofdecomposeSVMDother than"modeCount".- by
Character vector naming the metadata columns that identify a record, or
character()for a single record.
Details
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
\(\Delta t = (t_N - t_1)/(N - 1)\) under all.equal; it is then used
unchanged, with samplingInterval \(\Delta t\). A grid that is not
uniform is regularized with one warning per group: the step becomes
\(1/F_s\), with \(F_s\) the smallest \(2^a 5^b\) not below
\(1/\Delta t\); the grid is \(t_1 + k/F_s\), 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
\(\sqrt{\mathrm{mean}(s_c^2)}\), \(s_c\) 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.
Value
A named list of data.table tables, each with the by columns,
the other metadata, OCID and ID, followed by
- signal
t,s: the series decomposed, on the output grid.- modes
mode, an integer from 1,t,s. EachOCIDkeeps its own number of modes, without padding; anOCIDwithout modes has no rows.- residue, fitResidual, meanNoise
t,s, for the fields that the method returns.- diagnostics
mode,iterations,converged, when the method returns iterations.- termination
stopReason, andinnerStopReasonfordecomposeIteratedMaskedEMD, when the method returns a termination. EEMD, CEEMD, MaskedEMD and BEMD carry the columns and rows of their nativeterminationdata frame, with the series keys added; the BEMD row repeats for both channels. In these rowsmodeidentifies the next attempted extraction, not a returned mode;diagnosticscontinues to describe only returned modes.- centers, maskFrequencies
mode,frequencyin Hz.- boundaries
boundary,frequencyin Hz.
Rows follow the by columns, OCID, ID, mode or
boundary, and t.
References
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 \(t_1\). See the
NOTICE file of the installed package.
Examples
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)
#> [1] "signal" "modes" "residue" "diagnostics" "termination"
OUT$termination
#> OCID ID stopReason
#> <char> <char> <char>
#> 1: H1 AT insufficientExtrema
#> 2: H1 VT insufficientExtrema
#> 3: H1 DT insufficientExtrema
#> 4: H2 AT insufficientExtrema
#> 5: H2 VT insufficientExtrema
#> 6: H2 DT insufficientExtrema
#> 7: UP AT insufficientExtrema
#> 8: UP VT insufficientExtrema
#> 9: UP DT insufficientExtrema
head(OUT$modes)
#> OCID ID mode t s
#> <char> <char> <int> <num> <num>
#> 1: H1 AT 1 0.000000000 -0.8149686
#> 2: H1 AT 1 0.003001000 -0.7334793
#> 3: H1 AT 1 0.006002001 -0.6524386
#> 4: H1 AT 1 0.009003001 -0.5720312
#> 5: H1 AT 1 0.012004001 -0.4924402
#> 6: H1 AT 1 0.015005002 -0.4138474
# 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
#> OCID ID mode frequency
#> <char> <char> <int> <num>
#> 1: H1 AT 1 2.000017
#> 2: H1 AT 2 23.999987
#> 3: H1 AT 3 287.943889
#> 4: H2 AT 1 2.000017
#> 5: H2 AT 2 23.999987
#> 6: H2 AT 3 287.943889
#> 7: UP AT 1 2.000017
#> 8: UP AT 2 23.999987
#> 9: UP AT 3 287.943889