is.symmetric.matrix: Is a matrix symmetric or positive-definite?

View source: R/is_symmetric_matrix.R

is.symmetric.matrixR Documentation

Is a matrix symmetric or positive-definite?

Description

Determines if a matrix is square, symmetric, positive-definite, or positive semi-definite.

Usage

is.square.matrix(A)

is.symmetric.matrix(A, tol = .Machine$double.eps^0.5)

is.positive.semi.definite(A, tol = .Machine$double.eps^0.5)

is.positive.definite(A, tol = .Machine$double.eps^0.5)

Arguments

A

A numeric matrix.

tol

A numeric tolerance level used to check if a matrix is symmetric. That is, a matrix is symmetric if the difference between the matrix and its transpose is between -tol and tol.

Details

A tolerance is added to indicate if a matrix A is approximately symmetric. If A is not symmetric, a message and first few rows of the matrix is printed. If A has any missing values, NA is returned.

  • is.symmetric.matrix returns TRUE if A is a numeric, square and symmetric matrix; otherwise, returns FALSE. A matrix is symmetric if the absolute difference between A and its transpose is less than tol.

  • is.positive.semi.definite returns TRUE if a real, square, and symmetric matrix A is positive semi-definite. A matrix is positive semi-definite if its smallest eigenvalue is greater than or equal to zero.

  • is.positive.definite returns TRUE if a real, square, and symmetric matrix A is positive-definite. A matrix is positive-definite if its smallest eigenvalue is greater than zero.

Note

Functions are adapted from Frederick Novomestky's matrixcalc package in order to implement the rmatnorm function. The following changes are made:

  • I changed argument x to A to reflect usual matrix notation.

  • For is.symmetric, I added a tolerance so that A is symmetric even provided small differences between A and its transpose. This is useful for rmatnorm function, which was used repeatedly to generate matrixNormal random variates in a Markov chain.

  • For is.positive.semi.definite and is.positive.definite, I also saved time by avoiding a for-loop and instead calculating the minimum of eigenvalues.

Examples

## Example 0: Not square matrix
B <- matrix(c(1, 2, 3, 4, 5, 6), nrow = 2, byrow = TRUE)
B
is.square.matrix(B)

## Example 1: Not a matrix. should get an error.
df <- as.data.frame(matrix(c(1, 2, 3, 4, 5, 6), nrow = 2, byrow = TRUE))
df
## Not run: 
is.square.matrix(df)

## End(Not run)

## Example 2: Not symmetric & compare against matrixcalc
F <- matrix(c(1, 2, 3, 4), nrow = 2, byrow = TRUE)
F
is.square.matrix(F)
is.symmetric.matrix(F) # should be FALSE
if (!requireNamespace("matrixcalc", quietly = TRUE)) {
  matrixcalc::is.symmetric.matrix(F)
} else {
  message("you need to install the package matrixcalc to compare this example")
}

## Example 3: Symmetric but negative-definite. The functions are same.
# eigenvalues are  3 -1
G <- matrix(c(1, 2, 2, 1), nrow = 2, byrow = TRUE)
G
is.symmetric.matrix(G)
if (!requireNamespace("matrixcalc", quietly = TRUE)) {
  matrixcalc::is.symmetric.matrix(G)
} else {
  message("you need to install the package matrixcalc to compare this example.")
}
isSymmetric.matrix(G)
is.positive.definite(G) # FALSE
is.positive.semi.definite(G) # FALSE

## Example 3b: A missing value in G
G[1, 1] <- NA
is.symmetric.matrix(G) # NA
is.positive.definite(G) # NA

## Example 4: positive definite matrix
# eigenvalues are 3.4142136 2.0000000 0.585786
Q <- matrix(c(2, -1, 0, -1, 2, -1, 0, -1, 2), nrow = 3, byrow = TRUE)
is.symmetric.matrix(Q)
is.positive.definite(Q)

## Example 5: identity matrix is always positive definite
I <- diag(1, 3)
is.square.matrix(I) # TRUE
is.symmetric.matrix(I) # TRUE
is.positive.definite(I) # TRUE

matrixNormal documentation built on Sept. 16, 2022, 5:07 p.m.