Learn R Programming

BACCO (version 1.0-50)

quad.form: Evaluate a quadratic form efficiently

Description

Given a square matrix M of size $n\times n$, and a matrix $x$ of size $n\times p$ (or a vector of length $n$), evaluate $x^TMx$ in an efficient manner.

Function quad.form.inv() returns $x^TM^{-1}x$ using an efficient method that avoids inverting $M$. Function quad.3form() returns $l^TMr$ using nested calls to crossprod(). It's no faster than calling crossprod() directly, but makes code neater (IMHO)

Function quad.tform() returns $xMx^T$ using tcrossprod() in such a way as to not take a transpose.

Usage

quad.form(M, x, chol=FALSE)
quad.form.inv(M, x)
quad.tform(M, x)
quad.3form(M,left,right)

Arguments

M
Square matrix of size $n\times n$
x
Matrix of size $n\times p$, or vector of length $n$
chol
Boolean, with TRUE meaning to interpret argument M as the lower triangular Cholesky decomposition of the quadratic form. Remember that M.lower %*% M.upper == M, and chol() returns the
left,right
In function quad.3form(), matrices with $n$ rows and arbitrary number of columns

Details

The meat of quad.form() for chol=FALSE is just crossprod(crossprod(M, x), x), and that of quad.form.inv() is crossprod(x, solve(M, x)). If the Cholesky decomposition of M is available, then calling with chol=TRUE and supplying M.upper should generally be faster (for large matrices) than calling with chol=FALSE and using M directly. The time saving is negligible for matrices smaller than about $50\times 50$, even if the overhead of computing M.upper is ignored.

See Also

optimize

Examples

Run this code
jj <- matrix(rnorm(80),20,4)
M <- crossprod(jj,jj)
M.lower <- t(chol(M))
x <- matrix(rnorm(8),4,2)

jj.1 <- t(x) %*% M %*% x
jj.2 <- quad.form(M,x)
jj.3 <- quad.form(M.lower,x,chol=TRUE)

print(jj.1)
print(jj.2)
print(jj.3)

## Now consider accuracy:
quad.form(solve(M),x) - quad.form.inv(M,x)  # should be zero

quad.form(M,x) - quad.tform(M,t(x)) # Should be zero

Run the code above in your browser using DataLab