Discovers the top-K contrasting patterns (Platos) between a positive time series and a negative time series using an iterative Relative Frequency Contrast Profile (RFCP) procedure.
Usage
rfcp_top_k(
positive_data,
negative_data,
window_size,
k_platos = 2L,
max_freq = 5L,
exclusion_radius = NULL,
min_rms = 1e-04,
adaptive_max_freq = FALSE,
min_freq = 2L,
n_workers = 1L,
backend = "cpu",
progress = FALSE,
query_block_size = NULL,
progress_callback = NULL,
checkpoint_callback = NULL,
resume_state = NULL
)Arguments
- positive_data
Numeric positive/query time series.
- negative_data
Numeric negative/reference time series.
- window_size
Integer subsequence length, at least
2and no larger than either input series.- k_platos
Integer number of distinct Platos to discover. Defaults to
2L.- max_freq
Integer scalar or integer vector specifying the number of non-overlapping neighbor ranks requested for each Plato iteration. If a scalar is provided, it is used for all iterations. If a vector is provided, its length must equal
k_platos, allowing dynamic re-evaluation of frequency for rarer morphologies. Defaults to5L.- exclusion_radius
Integer exclusion radius between accepted neighbor starts and for padding concatenated segments.
NULLuseswindow_size.- min_rms
Numeric threshold for root-mean-square contrast. Iteration stops early if the detected Plato has an RMS contrast below this value. Defaults to
1e-4.- adaptive_max_freq
Logical. If
TRUE, dynamically adaptsmax_freqfor subsequent iterations based on the observed support (number of valid positive self-join neighbors with distance below \(\sqrt{2 \cdot \text{window\_size}}\)) of the current Plato. Defaults toFALSE.- min_freq
Integer minimum rank frequency floor when
adaptive_max_freq = TRUE. Defaults to2L.- n_workers
Number of native worker threads for the CPU backend. Ignored when
backend = "cuda". Defaults to1L. For parallel execution across processes, prefer a PSOCK cluster and usen_workers = 1within each worker. See matrixprofiler for fork limitations.- backend
Computation backend:
"cpu"(default) or"cuda".- progress
Logical progress flag for each RFCP iteration. Defaults to
FALSE.- query_block_size
Optional integer query block size for chunked execution. If
NULL(default), queries are processed monolithically in a single call. If specified, queries are processed in contiguous blocks of sizequery_block_size.- progress_callback
Optional callback function
function(event)invoked periodically with structured progress events ("round_start","block_done","round_done").- checkpoint_callback
Optional callback function
function(state)invoked after each block and Plato with a serializable state list.- resume_state
Optional state list from a previous execution (
checkpoint_callback) used to resume execution idempotently.
Value
An object of class "rfcp_top_k", which is a list containing:
k_requested: requested number of Platos.k_found: number of Platos discovered before stopping.window_size: subsequence length.exclusion_radius: exclusion radius used.adaptive_max_freq: whether adaptive frequency was enabled.min_freq: minimum frequency floor used.max_freq: vector of frequencies used for each Plato.platos: list of discovered Plato objects, each containing:k: Plato iteration rank (1, 2, ...).plato_index: one-based start index inpositive_data.plato_rms: contrast score atplato_index.plato_subsequence: numeric vector containing the pattern.plato_twin_index: one-based start index of nearest self-join neighbor.rfcp_at_plato: clipped contrasts across accepted ranks.rfmp_aa_at_plato: positive self-join distances.rfmp_ab_at_plato: negative AB distances.rfmpi_aa_at_plato: positive neighbor indices.rfmpi_ab_at_plato: negative neighbor indices.effective_max_freq: highest paired rank observed.
negative_data_final: the negative series augmented with the suppressed Plato occurrences and exclusion zones.
Details
In each iteration \(i \in \{1, \dots, K\}\), the algorithm:
Executes
rfcpusing the current augmented negative series and the requested frequencymax_freq[i].Identifies the highest-contrast query window (\(\text{Plato}_i\)) outside the exclusion zone of previously discovered Platos and their associated neighbors.
If the contrast score is below
min_rmsor no valid candidate remains, iteration terminates early.Extracts the subsequences of \(\text{Plato}_i\) and all its accepted positive self-join neighbors (
rfmpi_aa_at_plato), expanded by the exclusion zone: $$[\max(1, j - \text{exclusion\_radius}), \min(N^{(+)}, j + \text{window\_size} - 1 + \text{exclusion\_radius})]$$Merges overlapping intervals to maintain signal continuity, and appends the resulting segments to the negative series separated by
NAbarriers. Becauserfcpis NA-aware, this suppresses the contrast of that morphology and its trivial overlaps in subsequent iterations without introducing spurious cross-boundary windows.If
adaptive_max_freq = TRUE, re-evaluates the frequency for the next iteration based on the count of finite AA neighbors with distance below \(\sqrt{2 \cdot \text{window\_size}}\), bounded below bymin_freq.
Examples
set.seed(42)
# Create positive series with 5 sine pulses and 2 cosine pulses
t <- seq(0, 4 * pi, length.out = 20)
sine_pulse <- sin(t)
cos_pulse <- cos(t)
pos <- rnorm(300, sd = 0.05)
for (p in c(20, 60, 100, 140, 180)) pos[p:(p + 19)] <- pos[p:(p + 19)] + sine_pulse
for (p in c(220, 260)) pos[p:(p + 19)] <- pos[p:(p + 19)] + cos_pulse * 1.5
neg <- rnorm(300, sd = 0.05)
top_platos <- rfcp_top_k(pos, neg, window_size = 20, k_platos = 2, max_freq = c(4, 2))
print(top_platos)
#> Top-2 Relative Frequency Contrast Profile (RFCP)
#> Window size: 20 | Exclusion radius: 20 | Requested: 2 | Adaptive: FALSE
#> Plato 1: index = 97, RMS = 0.683502, max_freq = 4 (twin = 177)
#> Plato 2: index = 279, RMS = 0.341239, max_freq = 2 (twin = 239)
