mD {lazy.symbolic} | R Documentation |
Derivative of a Scalar Function with respect to a Matrix
Description
This is the wrapper function that calls mD0
function.
It pre-processes the input and post-processes the output .
Usage
mD(
expr,
X_ = "X",
sym = 0,
simplify = 1,
trace_chain = 1,
print = 0,
debug = 0
)
Arguments
expr |
an expression or a string containing a scalar function of X_ |
X_ |
the differentiating variable |
sym |
= 1 if |
simplify |
= 0 not to simplify the result |
trace_chain |
= TRUE if to print the history of the rules applied |
print |
= 1 to print the result |
debug |
= 1 to print intermediate results |
Details
To numerically check the result, use
gramdmn
and gradma
functions. (See example below.)
Currently, tr
and det
are the only functions
available as the input.
Whe simplify=1
is given,
Expand
, distribute_t
and remove_paren
will be used to simplify the result.
Value
a string containing the first derivative of rss w.r.t. X_.
Examples
# we need this.
modify_math_operators()
mD("tr(X)","X")
mD("tr(A%*%X)","X")
mD("tr(A%*%t(X))","X")
mD("tr(X%*%A)","X")
mD("tr(t(X)%*%A)","X")
mD("tr(A%*%t(X)%*%B%*%X%*%C)","X")
mD("tr(A%*%X%*%B%*%X%*%C)","X")
mD("tr(A%*%inv(X))","X")
mD("tr(A%*%inv(t(X)))","X")
mD("tr(A%*%inv(B%*%X%*%C)%*%D)","X")
mD("tr(A%*%inv(t(X)%*%B%*%X)%*%C)","X")
mD("tr(Diag(t(X)%*%X))","X")
mD("tr(A%*%(Diag(t(X)%*%C%*%X))%*%B)","X")
mD("tr((X%.%B))","X")
mD("tr(A%*%(X%.%B)%*%C)","X")
mD("tr((t(X)%.%X))","X")
mD("tr(A%*%(t(X)%.%B%.%X)%*%C)","X")
mD("det(X)","X")
mD("det(t(X))","X")
mD("det(A%*%X)","X")
# symmetric X
mD("tr(A%*%X)", "X", sym=1)
mD("tr(t(X)%*%A%*%X)", "X", sym=1)
## Not run:
# Must copy and paste to run the following examples.
# Examples of numerical checking
# inverse: tr(A%*%inv(t(X)%*%B%*%X)%*%C)
expr <- "tr(A%*%inv(t(X)%*%B%*%X)%*%C)"
dexpr <- mD(expr,"X")
printm(dexpr)
nvar1 <- 2; nvar2 <- 3
set.seed(1701)
Xn <- matrix(rnorm(nvar1*nvar1),nvar1,nvar1)
An <- matrix(rnorm(nvar2*nvar1),nvar2,nvar1)
Bn <- matrix(rnorm(nvar1*nvar1),nvar1,nvar1)
Cn <- matrix(rnorm(nvar1*nvar2),nvar1,nvar2)
values <- "X=Xn; A=An; B=Bn; C=Cn"
Ga <- 0; Gn <- 9999
Ga <- gradma( expr, dexpr=dexpr, values=values)
Gn <- gradmn( expr, values=values)
printm(Ga,Gn)
printm(max(abs(Ga-Gn))/mean(abs(Gn)))
# diag: tr(A%*%(Diag(t(X)%*%C%*%X))%*%B)
expr <- "tr(A%*%(Diag(t(X)%*%C%*%X))%*%B)"
dexpr <- mD(expr, "X")
printm(dexpr)
nvar1 <- 2; nvar2 <- 3
set.seed(1701)
Xn <- matrix(rnorm(nvar1*nvar1),nvar1,nvar1)
An <- matrix(rnorm(nvar2*nvar1),nvar2,nvar1)
Bn <- matrix(rnorm(nvar1*nvar2),nvar1,nvar2)
Cn <- matrix(rnorm(nvar1*nvar1),nvar1,nvar1)
values <- "X=Xn; A=An; B=Bn; C=Cn; I=In"
rm(Ga,Gn)
Ga=Eval(dexpr, values=values, fullsymb=1)
Gn=gradmn( expr, values=values )
printm(Ga,Gn)
printm(max(abs(Ga-Gn))/mean(abs(Gn)))
# Hadamar product: tr(A%*%(t(X)%.%C%.%X)%*%B)
expr <- "tr(A%*%(t(X)%.%C%.%X)%*%B)"
dexpr <- mD(expr, "X")
printm(dexpr)
nvar1 <- 2; nvar2 <- 3
set.seed(1701)
Xn <- matrix(rnorm(nvar1*nvar1),nvar1,nvar1)
An <- matrix(rnorm(nvar2*nvar1),nvar2,nvar1)
Bn <- matrix(rnorm(nvar1*nvar2),nvar1,nvar2)
Cn <- matrix(rnorm(nvar1*nvar1),nvar1,nvar1)
values <- "X=Xn; A=An; B=Bn; C=Cn; D=Dn"
rm(Ga,Gn)
Ga=Eval(dexpr, values=values, fullsymb=1)
Gn=gradmn( expr, values=values )
printm(Ga,Gn)
printm(max(abs(Ga-Gn))/mean(abs(Gn)))
# determinant: det(A%*%X%*%B)+det(C%*%t(X)%*%D)
expr <- "det(A%*%X%*%B)+det(C%*%t(X)%*%D)"
dexpr <- mD(expr,"X")
printm(dexpr)
nvar1 <- 3
set.seed(1701)
Xn <- matrix(rnorm(nvar1*nvar1),nvar1,nvar1)
An <- matrix(rnorm(nvar1*nvar1),nvar1,nvar1)
Bn <- matrix(rnorm(nvar1*nvar1),nvar1,nvar1)
Cn <- matrix(rnorm(nvar1*nvar1),nvar1,nvar1)
Dn <- matrix(rnorm(nvar1*nvar1),nvar1,nvar1)
values <- "X=Xn; A=An; B=Bn; C=Cn; D=Dn"
Ga <- 0; Gn <- 9999
Ga <- gradma( expr, dexpr=dexpr, values=values)
Gn <- gradmn( expr, values=values)
printm(Ga,Gn)
printm(max(abs(Ga-Gn))/mean(abs(Gn)))
# Some complex examples
# rss of doubly weighted multivariate multiple regression
rss <- ssq("Y-X%*%B", U="W", V="V", expand=2) |> printm()
# differantiate rss w.r.t the regression coefficient matrix B.
dexpr <- mD(rss, "B", trace_chain=1, print=1)
printm(dexpr)
# numerical checking by gradma and gradmn functions
set.seed(1701)
n <- 5; ny <- 4; nx <- 3
Vn <- diag(ny)*2
Wn <- diag(n)*3
Xn <- matrix(rnorm(n*nx),n,nx)
Bn <- matrix(rnorm(nx*ny),nx,ny)
Yn <- matrix(rnorm(n*ny),n,ny)
values <- c("B=Bn; Y=Yn; X=Xn; V=Vn; W=Wn")#'
Ga <- 0; Gn <- 9999
Ga <- gradma( rss, dexpr=dexpr, values=values)
Gn <- gradmn( rss, values=values)
printm(Ga,Gn)
printm(max(abs(Ga-Gn))/mean(abs(Gn)))
# LS fa
rss <- ssq("S-(L%*%Phi%*%t(L)+Psi)", expand=2)
# d ssq / d L
dexpr <- mD(rss,"L", trace_chain=1, print=1)
printm(dexpr)
set.seed(1701)
nvar <- 3; ndim <- 2
Ln <- matrix(rnorm(nvar*ndim),nvar,ndim)
Phin <- matrix(runif(ndim*ndim),ndim,ndim)
Phin <- (Phin+t(Phin))/2; Phin <- Phin-Diag(Phin)+diag(ndim)
Psin <- diag(nvar) / 10
Sn <- matrix(runif(nvar*nvar),nvar,nvar); Sn=(Sn+t(Sn))/2; diag(Sn)=1
values <- "L=Ln; Phi=Phin; Psi=Psin; S=Sn"
Ga <- 0; Gn <- 9999
Ga <- gradma( rss, dexpr=dexpr, values=values)
Gn <- gradmn( rss, values=values)
printm(Ga,Gn)
printm(max(abs(Ga-Gn))/mean(abs(Gn)))
# d ssq / d Phi
dexpr <- mD(rss,"Phi", print=1)
printm(dexpr)
values <- "Phi=Phin; L=Ln; Psi=Psin; S=Sn"
Ga <- 0; Gn=9999
Ga <- gradma( rss, dexpr=dexpr, values=values)
Gn <- gradmn( rss, values=values)
printm(Ga,Gn)
printm(max(abs(Ga-Gn))/mean(abs(Gn)))
# d ssq / d Psi
dexpr <- mD(rss,"Psi", print=1)
printm(dexpr)
values <- "Psi=Psin; Phi=Phin; L=Ln; S=Sn"
Ga <- 0; Gn <- 9999
Ga <- gradma( rss, dexpr=dexpr, values=values)
Gn <- gradmn( rss, values=values)
printm(Ga,Gn)
printm(max(abs(Ga-Gn))/mean(abs(Gn)))
# ML fa
expr1 <- "tr(inv(L%*%Phi%*%t(L)+Psi)%*%S)"
expr2 <- "log(det(inv(L%*%Phi%*%t(L)+Psi)%*%S))"
F <- expr1+expr2
# d F / d L
dexpr <- mD(F,"L")
printm(dexpr)
set.seed(1701)
nvar <- 3; ndim <- 2
Ln <- matrix(rnorm(nvar*ndim),nvar,ndim)
Phin <- matrix(runif(ndim*ndim),ndim,ndim)
Phin <- (Phin+t(Phin))/2; Phin <- Phin-Diag(Phin)+diag(ndim)
Psin <- diag(nvar) / 10
Sn <- matrix(runif(nvar*nvar),nvar,nvar); Sn=(Sn+t(Sn))/2; diag(Sn)=1
values <- "L=Ln; Phi=Phin; Psi=Psin; S=Sn"
Ga <- 0; Gn <- 9999
Ga <- gradma( F, dexpr=dexpr, values=values)
Gn <- gradmn( F, values=values)
printm(Ga,Gn)
printm(max(abs(Ga-Gn))/mean(abs(Gn)))
# d F / d Phi
dexpr <- mD(F,"Phi", sym=1)
printm(dexpr)
values <- "Phi=Phin; L=Ln; Psi=Psin; S=Sn"
Ga <- 0; G <- 9999
Ga <- gradma( F, dexpr=dexpr, values=values)
Gn <- gradmn( F, values=values, sym=1)
printm(Ga,Gn)
printm(max(abs(Ga-Gn))/mean(abs(Gn)))
# d F / d Psi
dexpr <- mD(F,"Psi", sym=1)
printm(dexpr)
values <- "Psi=Psin; Phi=Phin; L=Ln; S=Sn"
Ga <- 0; G <- 9999
Ga <- gradma( F, dexpr=dexpr, values=values)
Gn <- gradmn( F, values=values, sym=1)
printm(Ga,Gn)
printm(max(abs(Ga-Gn))/mean(abs(Gn)))
## End(Not run)
[Package lazy.symbolic version 1.0.0.20250803 ]