---
title: "1. Introduction: offline, causal and online analysis"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{1. Introduction: offline, causal and online analysis}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

The `rLifting` package provides a unified high-performance framework for wavelet lifting transforms in R. Uniquely, it bridges the gap between traditional offline statistical analysis and real-time signal processing.

This vignette demonstrates the three core modes of operation using a Doppler signal:

1.  Offline (batch): global denoising using future information.
2.  Causal (batch): batched processing that respects time causality (no lookahead).
3.  Online (stream): point-by-point processing for real-time applications.

## Setup and data

We utilize the `doppler_example` dataset included in the package.

```{r setup}
library(rLifting)

if (!requireNamespace("dplyr", quietly = TRUE) ||
    !requireNamespace("ggplot2", quietly = TRUE)) {
  knitr::opts_chunk$set(eval = FALSE)
  message("Required packages 'dplyr' and 'ggplot2' are missing. Vignette code will not run.")
} else {
  library(dplyr)
  library(ggplot2)
}

data("doppler_example", package = "rLifting")

# Visualize the noisy input
ggplot(doppler_example, aes(x = index, y = noisy)) +
  geom_line(color = "grey60", alpha = 0.8) +
  geom_line(aes(y = original), color = "black", alpha = 0.5, linetype = "dashed") +
  theme_minimal() +
  labs(title = "Input signal (Doppler + noise)")
```

## 1. Offline denoising (global)

In offline mode, the algorithm has access to the entire signal (past and future). This allows it to compute global thresholding statistics and perform non-causal lifting steps, resulting in the smoothest possible reconstruction.

Use case: historical data analysis, post-processing.

```{r offline}
# Define the Wavelet Scheme (Haar for this example)
scheme = lifting_scheme("haar")

# Denoise using strict offline mode
# levels = floor(log2(n)) ensures maximum decomposition depth
offline_clean = denoise_signal_offline(
  doppler_example$noisy,
  scheme,
  levels = floor(log2(nrow(doppler_example))),
  method = "semisoft"
)
```

## 2. Causal denoising (batch)

In causal mode, we process the history as if we were receiving it sequentially. The estimate at time $t$ depends *only* on $x_1, \dots, x_t$. We use a sliding window of size $W$ to calculate local statistics (see Liu et al 2014).

Use case: backtesting trading strategies, simulating real-time systems on historical data.

```{r causal}
# Causal Denoising with a window of 256 points
causal_clean = denoise_signal_causal(
  doppler_example$noisy,
  scheme,
  window_size = 256,
  levels = floor(log2(256)), 
  method = "semisoft"
)
```

## 3. Online denoising (stream)

Online mode allows you to process data point-by-point as it arrives from a sensor or API. It uses a `C++` ring buffer to maintain the sliding window state efficiently (amortized constant time per update).

Use case: IoT sensors, live financial feeds, monitoring systems.

```{r online}
# Initialize the Stream Processor
processor = new_wavelet_stream(
  scheme,
  window_size = 256,
  levels = floor(log2(256)),
  method = "semisoft"
)

# Simulate streaming (vectorized loop for demonstration)
online_clean = numeric(nrow(doppler_example))
for (i in 1:nrow(doppler_example)) {
  online_clean[i] = processor(doppler_example$noisy[i])
}
```

## Comparison

Combining all three views illustrates the trade-off. The offline method provides better smoothing (lower variance) because it "sees the future". The causal/online methods are reactive but naturally exhibit a slight phase lag.

```{r comparison}
# Combine results
df_plot = doppler_example |>
  mutate(
    Offline = offline_clean,
    Causal = causal_clean,
    Online = online_clean
  )

# Plot focusing on a specific section to see the lag
ggplot(df_plot, aes(x = index)) +
  # Add Truth curve
  geom_line(aes(y = original, color = "Truth"), linewidth = 0.8, alpha = 0.6) +
  geom_line(aes(y = Offline, color = "Offline"), alpha = 0.8) +
  geom_line(aes(y = Causal, color = "Causal"), alpha = 0.8) +
  scale_color_manual(values = c("Truth" = "black", "Offline" = "blue", "Causal" = "red")) +
  theme_minimal() +
  labs(title = "Trade-off: smoothness vs. causality") +
  coord_cartesian(xlim = c(500, 1000)) # Zoom in
```
