--- title: "2. Benchmark: speed and reconstruction accuracy" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{2. Benchmark: speed and reconstruction accuracy} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` This vignette compares `rLifting` against established R packages (`wavethresh`, `adlift`, `nlt`) on a standard offline denoising task, evaluating both execution speed and reconstruction accuracy (MSE). ## Setup and methodology All benchmarks denoise a Doppler signal ($n = 1024$, $\sigma = 0.3$) over 50 independent noise realizations. Timing covers the full pipeline (forward transform, thresholding, and inverse transform) and is measured with nanosecond precision via `microbenchmark`. To comply with CRAN time limits, the results are pre-computed by the script `data-raw/generate_vignette_data.R` and shipped as package data. The raw data is available via `data("benchmark_offline")`. For comparability, all packages use a Haar (or equivalent first-order) wavelet. Note that `rLifting` supports additional wavelet families (CDF 5/3, CDF 9/7); the Haar filter is used here solely to ensure a fair comparison. | Package | Paradigm | Thresholding | Implementation | |:--------|:---------|:-------------|:---------------| | `rLifting` | Lifting scheme | Semisoft (adaptive) | C++ core via Rcpp | | `wavethresh` | DWT | Universal soft | R with C internals | | `adlift` | Adaptive lifting | EbayesThresh | Pure R, local polynomial prediction | | `nlt` | Nonnested lifting | EbayesThresh | Pure R, permutation-based prediction | ```{r setup} library(rLifting) if (!requireNamespace("dplyr", quietly = TRUE) || !requireNamespace("ggplot2", quietly = TRUE) || !requireNamespace("knitr", quietly = TRUE)) { knitr::opts_chunk$set(eval = FALSE) message("Required packages 'dplyr', 'ggplot2' or 'knitr' are missing. Vignette code will not run.") } else { library(ggplot2) library(dplyr) library(knitr) } data("benchmark_offline", package = "rLifting") ``` ## 1. Execution speed ```{r speed_table} df_speed = benchmark_offline |> filter(!is.na(Time)) |> group_by(Pkg) |> summarise( Median_ms = median(Time) * 1000, Mean_ms = mean(Time) * 1000, .groups = "drop" ) |> arrange(Median_ms) |> mutate( Paradigm = case_when( Pkg == "wavethresh" ~ "DWT", Pkg %in% c("adlift", "nlt") ~ "Adaptive Lifting", TRUE ~ "Lifting" ) ) |> select(Pkg, Paradigm, Median_ms, Mean_ms) kable(df_speed, col.names = c("Package", "Paradigm", "Median (ms)", "Mean (ms)"), digits = 2, caption = "Execution time for the full denoising pipeline (1024 points, Haar).") ``` `rLifting` is the fastest package, thanks to its zero-allocation C++ core (via Rcpp). `wavethresh`, the standard DWT implementation in R, is moderately slower but still fast. The adaptive lifting packages (`adlift` and `nlt`) are orders of magnitude slower than both `rLifting` and `wavethresh`, because they fit local polynomial predictors at every lifting step. ## 2. Reconstruction accuracy (MSE) Speed means nothing without accuracy. Here we compare the MSE of each denoised signal against the ground truth. ```{r mse_plot, fig.width=7, fig.height=4.5} df_mse = benchmark_offline |> filter(!is.na(MSE)) ggplot(df_mse, aes(x = reorder(Pkg, MSE), y = MSE, fill = Pkg)) + geom_boxplot() + labs( title = "Reconstruction error (MSE)", subtitle = "Doppler signal, n = 1024, \u03c3 = 0.3 (lower is better)", x = "Package", y = "MSE" ) + theme_minimal() + theme(legend.position = "none") ``` ## 3. The speed-accuracy trade-off The lifting-based packages (`adlift`, `nlt`, and `rLifting`) achieve the lowest MSE values. This is not a coincidence: the lifting scheme operates directly in the spatial domain and can accommodate adaptive thresholding strategies that are difficult to implement in a classical DWT framework. `adlift` achieves the best MSE because it uses adaptive local polynomial prediction, choosing the predictor that best fits each local neighborhood. `nlt` uses a permutation-based ordering to find an optimal lifting path and applies EbayesThresh for coefficient shrinkage. Both strategies adapt the wavelet basis itself to the signal, yielding excellent reconstruction for smooth or piecewise-smooth functions. `rLifting` uses a fixed wavelet (Haar in this example) but applies adaptive semisoft thresholding. This combination yields MSE values competitive with `nlt` and close to `adlift`, while running orders of magnitude faster. The classical DWT package (`wavethresh`) applies a fixed wavelet with universal soft thresholding. While it is fast, its reconstruction accuracy is lower than all three lifting-based approaches. In summary, the marginal MSE improvement of `adlift` and `nlt` comes at a steep computational cost, making them impractical for real-time or large-scale applications. `rLifting` offers a practical balance: near-optimal accuracy at a fraction of the computational budget.