--- title: "Brobdingnagian matrices" author: "Robin K. S. Hankin" output: html_vignette bibliography: brob.bib vignette: > %\VignetteIndexEntry{brobmat} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r set-options, echo = FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>", dev = "png", fig.width = 7, fig.height = 3.5, message = FALSE, warning = FALSE) options(width = 80, tibble.width = Inf) ``` ```{r out.width='20%', out.extra='style="float:right; padding:10px"',echo=FALSE} knitr::include_graphics(system.file("help/figures/Brobdingnag.png", package = "Brobdingnag")) ``` To cite the Brobdingnag package in publications, please use @hankin2007. R package `Brobdingnag` has basic functionality for matrices. It includes matrix multiplication and addition, but determinants and matrix inverses are not implemented. First load the package: ```{r} library("Brobdingnag") ``` The standard way to create a Brobdgingnagian matrix (a `brobmat`) is to use function `brobmat()` which takes arguments similar to `matrix()` and returns a matrix of entries created with `brob()`: ```{r} M1 <- brobmat(-10:13,4,6) colnames(M1) <- state.abb[1:6] M1 ``` Above, note that all entries of `M1` are greater than zero; `M1[1,1]`, for example, is `exp(-10)`, or $e^{-10}\simeq 4.54\times 10^{-5}$. For negative matrix entries, function `brobmat()` takes a Boolean argument `positive` that specifies the sign: ```{r} M2 <- brobmat( c(1,104,-66,45,1e40,-2e40,1e-200,232.2),2,4, positive=c(T,F,T,T,T,F,T,T)) M2 ``` Standard matrix arithmetic is implemented, thus: ```{r} rownames(M2) <- c("a","b") colnames(M2) <- month.abb[1:4] M2 M2[2,3] <- 0 M2 M2+1000 ``` We can also do matrix multiplication, although it is slow: ```{r} M2 %*% M1 ``` ## Numerical verification: matrix multiplication We will verify matrix multiplication by carrying out the same operation in two different ways. First, create two largish Brobdingnagian matrices: ```{r} nrows <- 11 ncols <- 18 M3 <- brobmat(rnorm(nrows*ncols),nrows,ncols,positive=sample(c(T,F),nrows*ncols,replace=T)) M4 <- brobmat(rnorm(nrows*ncols),ncols,nrows,positive=sample(c(T,F),nrows*ncols,replace=T)) M3[1:3,1:3] ``` Now calculate the matrix product by coercing to numeric matrices and using base R matrix multiplication: ```{r} p1 <- as.matrix(M3) %*% as.matrix(M4) ``` Secondly, we use Brobdingnagian matrix multiplication, and then coercing to numeric: ```{r} p2 <- as.matrix(M3 %*% M4) ``` The difference: ```{r} max(abs(p1-p2)) ``` is small. Now the other way: ```{r} q1 <- M3 %*% M4 q2 <- as.brobmat(as.matrix(M3) %*% as.matrix(M4)) max(abs(as.brob(q1-q2))) ``` Above we see that the difference of `exp(-30.267)` (about $7\times 10^{-14}$), is small. ## Numerical verification: integration with the `cubature` package The matrix functionality of the `Brobdingnag` package was originally written to leverage the functionality of the `cubature` package. Here I give some numerical verification for this. Suppose we wish to evaluate \[ \int_{x=0}^{x=4}(x^2-4)\,dx \] using numerical methods. See how the integrand includes positive and negative values; the theoretical value is $\frac{16}{3}=5.33\ldots$. The `cubature` idiom for this would be ```{r,label = numericalintegration} library("cubature") f.numeric <- function(x){x^2 - 4} out.num <- cubature::hcubature(f = f.numeric, lowerLimit = 0, upperLimit = 4, vectorInterface = TRUE) out.num ``` and the Brobdingnagian equivalent would be ```{r,label = numericalintegrationbrob} f.brob <- function(x) { x <- as.brob(x[1, ]) as.matrix( brobmat(x^2 - 4, ncol = length(x))) } out.brob <- cubature::hcubature(f = f.brob, lowerLimit = 0, upperLimit = 4, vectorInterface = TRUE) out.brob ``` We may compare the two methods: ```{r,label=comparebrobandnumeric} out.brob$integral - out.num$integral ``` ### References {-}