---
title: "StrucDiv"
author: "Leila Schuh"
date: "`r Sys.Date()`"
output: 
  rmarkdown::html_vignette:
    #number_sections: true
    toc: true
    #toc_depth: 2
bibliography: bibliography.bib
vignette: >
  %\VignetteIndexEntry{StrucDiv}
  %\VignetteEngine{knitr::rmarkdown}
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.path = "figure/StrucDiv-",
  out.width = "100%"
)
```

## StrucDiv: Spatial structural diversity quantification in raster data

Spatial structural diversity refers to the spatial, i.e. horizontal, configuration of landscape elements. Hereafter, 'spatial structural diversity' will be used synonymous to 'structural diversity'. The [StrucDiv](https://CRAN.R-project.org/package=StrucDiv) package provides methods to quantify structural diversity in raster data, i.e in data containing pixels. With these methods, structural diversity features can be detected. Structural diversity features have also been called latent landscape features. Typical structural diversity features include patches and linear features, and they can reveal transition zones between spatial regimes. [@Schuhetal2020, @Schuhetal2022a].
Structural diversity can also be quantified in categorical raster data, required method specifications are described in @Schuhetal2022a.
The methods are based on the spatial arrangement of pixel values as pairs, based on @Haralick1973. Pixels are considered as pairs at user-specified distances and angles. Distance refers to the distance between two pixels that are considered a pair. Angle refers to the angle at which two pixels are considered a pair. Angles can be horizontal or vertical direction, or the diagonals at 45° or 135°. The direction-invariant version considers all angles.
Structural diversity can be quantified on different spatial scales, whereby pixel resolution is an input to these methods, and different extents can be implemented.
Scale-specific structural diversity can be quantified, either of the domain, or of smaller areas therein. The latter is done with a moving window approach. Multi-scale structural diversity can be quantified by combining information from different scales (i.e. extents), as further described below. The methods are described in detail in @Schuhetal2022a and in @Schuhetal2022b, and the R package is described in @Schuhetal2022c. The R package contains three main functions:

### `strucDiv()`: Scale-specific structural diversity quantification

The `strucDiv()` function quantifies structural diversity on a particular scale, which is defined by the size of the moving window. Within the area captured by the moving window, pixel values are considered as pairs with the specified spatial arrangement, as described above.
The frequencies of pixel pair occurrences are normalized by the total number of pixel pairs, which returns the gray level co-occurrence matrix (GLCM). The GLCM contains the empirical probabilities $p_{i,j}$ that pixel values v$_{i}$ and v$_{j}$ occur as a pair at the specified distance and angle(s), in the area captured by the moving window. The total number of pixel pairs depends on the spatial scale, i.e. on the size of the moving window. The size of the square moving window is defined by its window side length (WSL), which must be an uneven integer.
Values v$_{i}$ and v$_{j}$ that are considered a pair enter the GLCM as row and column names, hence $i$ and $j$ index the position of a pixel value in the GLCM. The values at positions $i$ and $j$ can differ between GLCMs. Instead of pixel values v$_{i}$ and  v$_{j}$, ranks (r, s) can be considered. Ranks refer to the position of the pixel value in the GLCM, hence the value associated with a rank can differ between GLCMs. The total (GLCM-specific) number of values is denoted with $m$, and the total (GLCM-specific) number of ranks is denoted with $l$.
Structural diversity metrics are calculated for every element of the GLCM, and their sum is assigned to the center pixel of the moving window and represents the structural diversity of the area captured by the window. The final map is called a '(spatial) structural diversity map' and it represents structural diversity quantified on a particular scale.

### `strucDivNest()`: Multi-scale structural diversity quantification

The `strucDivNest()` function allows to combine information from different scales with an empirical Bayesian approach and a Beta-Binomial model. Two scales are nested inside each other - a larger, outer scale and a smaller, inner scale. Three different nesting schemes are available, whereby the inner scale is always a moving window. 
The outer scale can either be another mowing window, a block, or the domain (i.e. the input raster). 
The outer scale is used as prior information, and the inner scale serves as likelihood to estimate posterior probabilities of pixel value co-occurrences. 
In the beta-binomial model both, the prior and the posterior follow a beta distribution, and the likelihood follows a conditional binomial distribution. 
Posterior probabilities are estimated with mean estimates. 
Structural diversity is quantified based on these posterior probabilities. 
The final map is called a '(spatial) structural diversity map' and is returned as a raster layer. The output map represents structural diversity, quantified across different spatial scales, which are defined by the outer scale and the inner scale. This method is described in detail in @Schuhetal2022b.

### `strucDivDom()`: Structural diversity quantification of the domain

The function `strucDivDom()` quantifies structural diversity of the domain and returns a list including the structural diversity value, the GLCM and the 'diversity matrix'. Structural diversity is calculated for every element of the GLCM, which returns the diversity matrix. The sum of this matrix represents the structural diversity value of the area under consideration. The same structural diversity metrics are available that are available for `strucDiv()` and `strucDivNest()`, but they are named slightly different, for programming reasons. More specifically, entropy is called entropyDom, contrast is called contrastDom and so forth. The mathematical formulations remain the same and therefore we do not list them separately (see below).


### Structural diversity metrics

The following metrics are available: structural diversity entropy, normalized entropy, contrast, dissimilarity, and homogeneity. Structural diversity entropy includes a difference weight $\delta \in \{0, 1, 2\}$, which weighs the differences between pixel values  v$_{i}$ and v$_{j}$, using either absolute, or square weights. When $\delta$ = 0, structural diversity entropy corresponds to Shannon entropy [@Shannon]. Shannon entropy has a scale-specific maximum, however, when the `strucDivNest()` function is used, this maximum may be violated, depending on the posterior probabilities of pixel value co-occurrences.
The values of structural diversity entropy with $\delta \in \{1, 2\}$ are not restricted and depend on the values of the input raster.
Normalized entropy is Shannon entropy normalized over maximum entropy. When the `strucDiv()` function is used, normalized entropy ranges between 0 and 1. When the `strucDivNest()` function is used, normalized entropy may be larger than 1, depending on the posterior probabilities of pixel value co-occurrences.
Dissimilarity naturally employs $\delta = 1$, contrast employs $\delta = 2$, and homogeneity employs $\delta = 2$ in the denominator.
The values of dissimilarity and contrast are not restricted and depend on the values of the input raster.
Homogeneity measures the closeness of $p_{ij}$ to the diagonal in the GLCM, and ranges between 0 and 1 when the `strucDiv()` function is used. When the `strucDivNest()` function is used, homogeneity may be larger than 1, depending on the posterior probabilities of pixel value co-occurrences.

#### Structural diversity metrics using pixel values

\begin{align}
  \text{Structural diversity entropy} & = \ - \sum_{i,j=1}^{m} p_{ij} \ln p_{ij} \ |v_{i}-v_{j}| ^ \delta,  \delta \in \{0,1,2\}
     \label{DivEnt} \\
       \text{Normalized entropy} & = \ - \sum_{i,j=1}^{m} p_{ij} \ln p_{ij} / \ln n 
     \label{EntNorm} \\
   \text{Contrast} & = \sum_{i,j=1}^{m} p_{ij} \ |v_{i}-v_{j}| ^ \delta, \delta = 2
    \label{ValCon} \\
   \text{Dissimilarity} & = \sum_{i,j=1}^{m} p_{ij} \ |v_{i}-v_{j}| ^\delta, \delta = 1
\label{ValDis} \\
     \text{Homogeneity} & = \sum_{i,j=1}^{m} p_{ij} / (1 + |i-j|^\delta), \delta = 2
  \label{ValHom}
\end{align}

#### Structural diversity metrics using ranks

\begin{align}
   \text{Structural diversity entropy} & = \ - \sum_{r,s=1}^{l} p_{rs} \ln p_{rs} \ |r-s| ^ \delta,  \delta \in \{0,1,2\} 
    \label{RankDivEnt}\\
    \text{Normalized entropy} & = \ - \sum_{r,s=1}^{l} p_{rs} \ln p_{rs} / \ln l 
    \label{RankEntnorm}\\
    \text{Contrast} & = \sum_{r,s=1}^{l} p_{rs} \ |r-s| ^ \delta, \delta = 2
   \label{RankCon} \\
   \text{Dissimilarity} & = \sum_{r,s=1}^{l} p_{rs} \ |r-s| ^ \delta, \delta = 1
   \label{ConDis} \\
     \text{Homogeneity} & = \sum_{r,s=1}^{l} p_{rs} / (1 + |r-s|^\delta), \delta = 2
  \label{HomRank}
\end{align}

## Data

These methods can be applied to any continuous raster data. However, for entropy, normalized entropy, and homogeneity, the possible number of gray levels (GL) is restricted, i.e. high numbers of GL lead to structureless diversity maps [@Schuhetal2020]. The methods can also be applied to categorical data if categories are numbered in a meaningful way, or if entropy or normalized entropy are used. This is because when $\delta \in \{1, 2\}$, the difference between $v_{i}$ and $v_{j}$ cannot be computed or is meaningless. 

## Installation

The [StrucDiv](https://CRAN.R-project.org/package=StrucDiv) package can be installed from [CRAN](https://CRAN.R-project.org) with:
``` r
install.packages("StrucDiv")
```

## Example

Calculate normalized entropy on Normalized Difference Vegetation Index (NDVI) data, which was binned to 15 gray levels (see data documentation). Scale is defined by window size length (WSL) 3, direct value neighbors are considered, and the direction-invariant version is employed.

```{r data, echo=FALSE, message = FALSE, eval = FALSE}
library(raster)
library(StrucDiv)
ndvi.15gl <- raster(ndvi.15gl)
extent(ndvi.15gl) <-  c(165.0205, 174.8301, 66.62804, 68.61332)
```

```{r example, echo=TRUE, message = FALSE, eval=FALSE}

entNorm <- strucDiv(ndvi.15gl, wsl = 5, dist = 1, angle = "all", fun = entropyNorm,
                  na.handling = na.pass)

```

![title](figIn/vign.png)
<figcaption align = "left">Fig.1 Left: NDVI data reduced to 15 GL. 
Right: structural diversity quantified with normalized entropy.</figcaption>

## References

