An R package for simulating positive definite matrices constrained by acyclic directed and undirected graphs.

## Installation

The package is available on CRAN, to get the latest stable version use:

install.packages("gmat")

Alternatively, using the R package devtools one may install the development version:

# install.packages("devtools")
devtools::install_github("irenecrsn/gmat")

The only R package required for gmat is igraph, which can also be installed from CRAN.

## An example of use

First, we generate a random undirected graph with 3 nodes and density 0.5. Then we generate, using our port() function, 2 matrices consistent with such random graphical structure.

library(gmat)

ug <- rgraph(p = 3, d = 0.5)
igraph::print.igraph(ug)
#> IGRAPH dcd8510 U--- 3 0 -- Erdos renyi (gnp) graph
#> + attr: name (g/c), type (g/c), loops (g/l), p (g/n)
#> + edges from dcd8510:
port(N = 2, ug = ug)
#> , , 1
#>
#>          [,1]      [,2]      [,3]
#> [1,] 1.198698 0.0000000 0.0000000
#> [2,] 0.000000 0.4941018 0.0000000
#> [3,] 0.000000 0.0000000 0.2753125
#>
#> , , 2
#>
#>           [,1]      [,2]      [,3]
#> [1,] 0.9548066 0.0000000 0.0000000
#> [2,] 0.0000000 0.3933312 0.0000000
#> [3,] 0.0000000 0.0000000 0.0190024

We appreciate how the zero pattern is shared by all of the simulated matrices. The return value is an array, and so the individual matrices can be accessed as matrices[, , n], where n is the index of the matrix we want to retrieve from the sample, ranging from 1 to N.

We may also sample correlation matrices using i.i.d. coefficients in their upper Cholesky factor U.

chol_iid(N = 2)
#> , , 1
#>
#>            [,1]       [,2]       [,3]
#> [1,]  1.0000000 -0.4925309 -0.5256998
#> [2,] -0.4925309  1.0000000 -0.2251995
#> [3,] -0.5256998 -0.2251995  1.0000000
#>
#> , , 2
#>
#>            [,1]      [,2]       [,3]
#> [1,]  1.0000000  0.610114 -0.8513245
#> [2,]  0.6101140  1.000000 -0.8179340
#> [3,] -0.8513245 -0.817934  1.0000000

A specific zero pattern can be enforced in U using an acyclic digraph.

dag <- rgraph(p = 3, d = 0.5, dag = TRUE)
m <- chol_iid(dag = dag)[, , 1]
L <- t(chol(anti_t(m)))
U <- t(anti_t(L))
igraph::print.igraph(dag)
#> IGRAPH b4978ff D--- 3 2 --
#> + edges from b4978ff:
#> [1] 1->2 2->3
print(U)
#>           [,1]       [,2]       [,3]
#> [1,] 0.8586738 -0.5125225  0.0000000
#> [2,] 0.0000000  0.8311376 -0.5560668
#> [3,] 0.0000000  0.0000000  1.0000000
print(m)
#>            [,1]       [,2]       [,3]
#> [1,]  1.0000000 -0.4259767  0.0000000
#> [2,] -0.4259767  1.0000000 -0.5560668
#> [3,]  0.0000000 -0.5560668  1.0000000

See more examples and paper references at the documentation website for the package.