## ----include = FALSE---------------------------------------------------------- knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.width = 7, fig.height = 4 ) ## ----setup-------------------------------------------------------------------- library(rLifting) if (!requireNamespace("ggplot2", quietly = TRUE)) { knitr::opts_chunk$set(eval = FALSE) message("'ggplot2' is required to render plots. Vignette code will not run.") } else { library(ggplot2) } data("doppler_example", package = "rLifting") n = nrow(doppler_example) ## ----plot-input, echo=FALSE, fig.cap="Figure 1: Doppler signal. The dashed black line shows the underlying signal; the grey line shows the same signal with additive Gaussian noise (sd = 0.5)."---- ggplot(doppler_example, aes(x = index)) + geom_line(aes(y = noisy), color = "grey60", alpha = 0.8, linewidth = 0.3) + geom_line( aes(y = original), color = "black", linewidth = 0.6, linetype = "dashed" ) + theme_minimal() + labs( title = "Doppler signal: original (dashed) and noisy input", x = "Sample index", y = "Amplitude" ) ## ----wavelets, eval=FALSE----------------------------------------------------- # lifting_scheme("haar") # Fast; 1 vanishing moment; step-like signals # lifting_scheme("cdf53") # Linear prediction; 2 VM; JPEG 2000 lossless # lifting_scheme("dd4") # Deslauriers-Dubuc (1989) 4-point cubic; 4 VM # lifting_scheme("cdf97") # JPEG 2000 lossy; 4 VM; smoothest reconstruction on smooth signals # lifting_scheme("db2") # Orthogonal; 2 vanishing moments # lifting_scheme("lazy") # Identity split only; for diagnostic use ## ----offline------------------------------------------------------------------ scheme = lifting_scheme("cdf53") # Pick a level depth that suits both the full signal (offline) and the # sliding window (causal/stream); keeps the comparison in Section 8 fair. levels = 4 offline_clean = denoise_signal_offline( doppler_example$noisy, scheme, levels = levels, shrinkage = "semisoft", # hard | soft | semisoft (default) | scad threshold_method = "universal", # universal | sure extension = "symmetric", # symmetric | periodic | zero | local_linear | one_sided alpha = 0.3, # threshold decay across levels (universal only) beta = 1.2 # threshold scale factor (universal only) ) ## ----causal------------------------------------------------------------------- window_size = 255 # must be odd; forced odd automatically if even is supplied causal_levels = levels # same depth as offline for a fair comparison (Section 8) causal_clean = denoise_signal_causal( doppler_example$noisy, scheme, window_size = window_size, levels = causal_levels, shrinkage = "semisoft", update_freq = 1 # recompute threshold every sample (maximum adaptivity) ) ## ----stream------------------------------------------------------------------- processor = new_wavelet_stream( scheme, window_size = window_size, levels = causal_levels, shrinkage = "semisoft", update_freq = 1 ) stream_clean = numeric(n) for (i in seq_len(n)) { stream_clean[i] = processor(doppler_example$noisy[i]) } ## ----irregular, eval=FALSE---------------------------------------------------- # set.seed(42) # n_irr = 512 # pure_irr = rLifting:::.generate_signal("doppler", n = n_irr) # x_irr = pure_irr + rnorm(n_irr, sd = 0.2) # # # Non-uniform grid: log-normal spacing # t_irr = cumsum(c(0, abs(rnorm(n_irr - 1, mean = 1, sd = 0.4)))) # # # Interpolating wavelets adapt predict steps to physical positions # sch_irr = lifting_scheme("cdf53") # # res_irr = denoise_signal_offline( # x_irr, sch_irr, # levels = 4, t = t_irr # ) ## ----stream-irregular, eval=FALSE--------------------------------------------- # proc_irr = new_wavelet_stream( # sch_irr, window_size = 127, # levels = 3, irregular = TRUE # ) # # output_irr = numeric(n_irr) # for (i in seq_len(n_irr)) { # output_irr[i] = proc_irr(x_irr[i], t_val = t_irr[i]) # } ## ----comparison, fig.cap="Figure 2: Output of the three modes on the noisy Doppler signal, zoomed to samples 400–800 (post warm-up). All modes use CDF 5/3, semisoft shrinkage and 4 decomposition levels. The grey line is the noisy input."---- df_plot = data.frame( index = rep(doppler_example$index, 5), value = c( doppler_example$noisy, doppler_example$original, offline_clean, causal_clean, stream_clean ), Signal = factor( rep(c("Noisy input", "Original", "Offline", "Causal", "Stream"), each = n), levels = c("Noisy input", "Original", "Offline", "Causal", "Stream") ) ) ggplot( df_plot, aes( x = index, y = value, colour = Signal, linewidth = Signal, alpha = Signal ) ) + geom_line() + scale_colour_manual( values = c( "Noisy input" = "grey70", "Original" = "black", "Offline" = "#0072B2", "Causal" = "#D55E00", "Stream" = "#009E73" ) ) + scale_linewidth_manual( values = c( "Noisy input" = 0.3, "Original" = 0.5, "Offline" = 0.8, "Causal" = 0.8, "Stream" = 0.8 ) ) + scale_alpha_manual( values = c( "Noisy input" = 0.4, "Original" = 1, "Offline" = 1, "Causal" = 1, "Stream" = 1 ) ) + coord_cartesian(xlim = c(400, 800)) + theme_minimal() + labs( title = "Three modes: offline, causal, stream (CDF 5/3, semisoft, 4 levels)", subtitle = "Zoom: samples 400–800 (post warm-up). Grey: noisy input.", x = "Sample index", y = "Amplitude" )