Setup

This section contains the setup and the various utility functions used throughout.

Libraries used:

library(data.table)

Compiled code (any models used are shown later):

Introduction

The Kronecker product is a multiplication operation on two matrices that gives you a block matrix. For example,

A <- matrix(c(1, 2, 3, 4), ncol = 2, byrow = TRUE)
B <- diag(3)
kronecker(A, B)
##      [,1] [,2] [,3] [,4] [,5] [,6]
## [1,]    1    0    0    2    0    0
## [2,]    0    1    0    0    2    0
## [3,]    0    0    1    0    0    2
## [4,]    3    0    0    4    0    0
## [5,]    0    3    0    0    4    0
## [6,]    0    0    3    0    0    4

The Kronecker product can be quite handy for easily duplicating a matrix multiple times, as you might need when forming a design matrix. Here are a few examples of its use:

Duplicate a matrix horizontally when \(A\) is a row vector:

A <- matrix(1, ncol = 3, nrow = 1)
B <- matrix(c(1, 2, 3, 4), ncol = 2, byrow = TRUE)
kronecker(A, B)
##      [,1] [,2] [,3] [,4] [,5] [,6]
## [1,]    1    2    1    2    1    2
## [2,]    3    4    3    4    3    4

Duplicate each element from a matrix horizontally:

kronecker(B, A)
##      [,1] [,2] [,3] [,4] [,5] [,6]
## [1,]    1    1    1    2    2    2
## [2,]    3    3    3    4    4    4

Duplicate a matrix vertical when \(A\) is a vector:

A <- matrix(1, ncol = 1, nrow = 3)
B <- matrix(c(1, 2, 3, 4), ncol = 2, byrow = TRUE)
kronecker(A, B)
##      [,1] [,2]
## [1,]    1    2
## [2,]    3    4
## [3,]    1    2
## [4,]    3    4
## [5,]    1    2
## [6,]    3    4

Duplicate each element from a matrix vertically:

kronecker(B, A)
##      [,1] [,2]
## [1,]    1    2
## [2,]    1    2
## [3,]    1    2
## [4,]    3    4
## [5,]    3    4
## [6,]    3    4

Create a matrix formed from blocks of \(B\):

J <- matrix(1, ncol = 2, nrow = 2)
B <- matrix(c(1, 2, 3, 4), ncol = 2, byrow = TRUE)
kronecker(J, B)
##      [,1] [,2] [,3] [,4]
## [1,]    1    2    1    2
## [2,]    3    4    3    4
## [3,]    1    2    1    2
## [4,]    3    4    3    4

Create a block from each element of \(B\):

kronecker(B, J)
##      [,1] [,2] [,3] [,4]
## [1,]    1    1    2    2
## [2,]    1    1    2    2
## [3,]    3    3    4    4
## [4,]    3    3    4    4

Create a block matrix based that contains \(B\) along the diagonal:

I <- diag(3)
B <- matrix(c(1, 2, 3, 4), ncol = 2, byrow = TRUE)
kronecker(I, B)
##      [,1] [,2] [,3] [,4] [,5] [,6]
## [1,]    1    2    0    0    0    0
## [2,]    3    4    0    0    0    0
## [3,]    0    0    1    2    0    0
## [4,]    0    0    3    4    0    0
## [5,]    0    0    0    0    1    2
## [6,]    0    0    0    0    3    4

A diagonal block based on each element from \(B\):

kronecker(B, I)
##      [,1] [,2] [,3] [,4] [,5] [,6]
## [1,]    1    0    0    2    0    0
## [2,]    0    1    0    0    2    0
## [3,]    0    0    1    0    0    2
## [4,]    3    0    0    4    0    0
## [5,]    0    3    0    0    4    0
## [6,]    0    0    3    0    0    4