38 lines
1008 B
R
38 lines
1008 B
R
# Derivative of matrix product
|
|
A <- matrix(rnorm(3 * 3), 3, 3)
|
|
A <- A + t(A)
|
|
B <- matrix(rnorm(3 * 4), 3, 4)
|
|
|
|
# F(A) = A B
|
|
# DF(A) = B' %x% I
|
|
exprs.all.equal({
|
|
t(B) %x% diag(nrow(A))
|
|
num.deriv(function(X) X %*% B, A)
|
|
num.deriv(A %*% B, A)
|
|
num.deriv(X %*% B, X = A)
|
|
})
|
|
|
|
# Symmetric case, constraint A = A' (equiv to being a function of vech(A) only)
|
|
# F(A) = A B for A = A'
|
|
# DF(A) = B' %x% I
|
|
stopifnot(all.equal(
|
|
num.deriv(function(X) X %*% B, A, sym = TRUE),
|
|
(t(B) %x% diag(nrow(A))) %*% D(nrow(A)) %*% t(D(nrow(A)))
|
|
))
|
|
|
|
# Derivative of Kronecker Product
|
|
A <- matrix(rnorm(3 * 7), 3)
|
|
B <- matrix(rnorm(5 * 4), 5)
|
|
|
|
P <- diag(ncol(A)) %x% K(ncol(B), nrow(A)) %x% diag(nrow(B))
|
|
# DF(A) numeric approximation and exact solution
|
|
stopifnot(all.equal(
|
|
num.deriv(function(X) X %x% B, A),
|
|
P %*% (diag(prod(dim(A))) %x% c(B))
|
|
))
|
|
# DF(B) numeric approximation and exact solution
|
|
stopifnot(all.equal(
|
|
num.deriv(function(X) A %x% X, B),
|
|
P %*% (c(A) %x% diag(prod(dim(B))))
|
|
))
|