---
title: "2-Wasserstein Distance calculation"
output: rmarkdown::html_vignette
vignette: >
    %\VignetteIndexEntry{wasserstein_metric}
    %\VignetteEngine{knitr::rmarkdown}
    %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
    collapse = TRUE,
    comment = "#>"
)
```


## Background

The 2-Wasserstein distance W is a metric to describe the distance
between two distributions, representing two different conditions $A$ and $B$.

For continuous distributions, it is given by

$$W := W(F_A, F_B) 
= \bigg( \int_0^1 \big|F_A^{-1}(u) 
- F_B^{-1}(u) \big|^2 du \bigg)^\frac{1}{2},$$

where $F_A$ and $F_B$ are the corresponding cumulative distribution functions
(CDFs) and $F_A^{-1}$ and $F_B^{-1}$ the respective quantile functions.

We specifically consider the squared 2-Wasserstein distance $d := W^2$ which
offers the following decomposition into location, size, and shape terms:
$$d := d(F_A, F_B) 
= \int_0^1 \big|F^{-1}(u) - F^{-1}(u) \big|^2 du 
= \underbrace{\big(\mu_A - \mu_B\big)^2}_{\text{location}} 
+ \underbrace{\big(\sigma_A - \sigma_B\big)^2}_{\text{size}} 
+ \underbrace{2\sigma_A \sigma_B \big(1 - \rho^{A,B}\big)}_{\text{shape}},$$

where $\mu_A$ and $\mu_B$ are the respective means, $\sigma_A$ and$\sigma_B$
are the respective standard deviations, and $\rho^{A,B}$ is the Pearson
correlation of the points in the quantile-quantile plot of $F_A$ and $F_B$.


## Usage in two-sample setting

In case the distributions $F_A$ and $F_B$ are not explicitly given and
information is only availbale in the form of samples from $F_A$ and $F_B$,
respectively, we use the corresponding empirical CDFs  $\hat{F}_A$ and
$\hat{F}_B$. Then, the 2-Wasserstein distance is computed by 

$$d(\hat{F}_A, \hat{F}_B) 
\approx \frac{1}{K} \sum_{k=1}^K \big(Q_A^{\alpha_k} - Q_B^{\alpha_k} \big)
\approx \big(\hat{\mu}_A - \hat{\mu}_B\big)^2 
+  \big(\hat{\sigma}_A - \hat{\sigma}_B\big)^2
+ 2\hat{\sigma}_A \hat{\sigma}_B \big(1 - \hat{\rho}^{A,B}\big).$$

Here, $Q_A$ and $Q_B$ denote equidistant quantiles of $F_A$ and $F_B$,
respectively, at the levels $\alpha_k := \frac{k-0.5}{K}, k = 1, \dots , K$
using $K=1000$ in our implementation.
Moreover, $\hat{\mu}_A, \hat{\mu}_B, \hat{\sigma}_A, \hat{\sigma}_B,$ and
$\hat{\rho}_{A,B}$ denote the empirical versions of the corresponding quantiles
from the original decomposition of $d$.

## Three Implementations


The package `waddR` offers three functions to compute the 2-Wasserstein
distance in two-sample settings.

We will use samples from normal distributions to illustrate them.
```{r setup}
library(waddR)

set.seed(24)
x <- rnorm(100, mean=0, sd=1)
y <- rnorm(100, mean=2, sd=1)
```

The first function, `wasserstein_metric` offers a faster reimplementation in
Cpp of the function `wasserstein1d` from the R package `transport`, which
computes the original 2-Wasserstein distance $W$.

```{r wasserstein_exact}
wasserstein_metric(x, y)
```

The corresponding value of the squared 2-Wasserstein distance $d$ is then:

```{r sq_wasserstein_exact}
wasserstein_metric(x, y)**2
```

The second function, `squared_wass_approx`, computes the squared 2-Wasserstein
distance by calculating the mean squared difference of the equidistant
quantiles (first approximation in the previous formula).
This function is currently used to compute the 2-Wasserstein distance in the
testing procedures.

```{r sq_wassersein_approx}
squared_wass_approx(x, y)
```

The third function, `squared_wass_decomp`, approximates the squared
2-Wasserstein distance by addding the location, size, and shape terms from the
above decomposition (second apporximation in the previous formula).
It also returns the respective decomposition values.

```{r sq_wassersein_decomp}
squared_wass_decomp(x, y)
```

The decomposition results reflect that in the considered example, the two
distributions differ with respect to location (mean), but not in terms of size
and shape, thus confirming the underlying normal model.


## See Also

* The [`waddR` package](waddR.html)

* [Two-sample test](wasserstein_test.html) based on a decomposition of the
Wasserstein distance between two distributions to check for differences

* Detect 
[differential gene expression distributions](wasserstein_singlecell.html)
in scRNAseq data

## Session Info

```{r session-info}
sessionInfo()
```
