https://github.com/cran/aster
Raw File
Tip revision: aa47935123bfca8a22cbc8345d658d0c1713a289 authored by Charles J. Geyer on 14 December 2023, 15:20:02 UTC
version 1.1-3
Tip revision: aa47935
penmlogl.R

library(aster)
library(trust)

data(radish)

pred <- c(0,1,2)
fam <- c(1,3,2)

### need object of type aster to supply to penmlogl and pickle

aout <- aster(resp ~ varb + fit : (Site * Region + Block + Pop),
    pred, fam, varb, id, root, data = radish)

### model matrices for fixed and random effects

modmat.fix <- model.matrix(resp ~ varb + fit : (Site * Region),
    data = radish)
modmat.blk <- model.matrix(resp ~ 0 + fit:Block, data = radish)
modmat.pop <- model.matrix(resp ~ 0 + fit:Pop, data = radish)

rownames(modmat.fix) <- NULL
rownames(modmat.blk) <- NULL
rownames(modmat.pop) <- NULL

idrop <- match(aout$dropped, colnames(modmat.fix))
idrop <- idrop[! is.na(idrop)]
modmat.fix <- modmat.fix[ , - idrop]

nfix <- ncol(modmat.fix)
nblk <- ncol(modmat.blk)
npop <- ncol(modmat.pop)

### try penmlogl

theta.start <- c(1, 1)

alpha.start <- aout$coefficients[match(colnames(modmat.fix),
    names(aout$coefficients))]
parm.start <- c(alpha.start, rep(0, nblk + npop))

tout <- trust(objfun = penmlogl, parm.start, rinit = 1, rmax = 10,
    sigma = theta.start, fixed = modmat.fix,
    random = list(modmat.blk, modmat.pop), obj = aout)
tout$converged

### crude estimate of variance components

eff.blk <- tout$argument[seq(nfix + 1, nfix + nblk)]
eff.pop <- tout$argument[seq(nfix + nblk + 1, nfix + nblk + npop)]
theta.crude <- sqrt(c(var(eff.blk), var(eff.pop)))

### now for the testing

pout <- penmlogl(tout$argument, theta.crude, fixed = modmat.fix,
    random = list(modmat.blk, modmat.pop), obj = aout)
names(pout)

eff.fix <- tout$argument[seq(1, nfix)]
eff.blk <- tout$argument[seq(nfix + 1, nfix + nblk)]
eff.pop <- tout$argument[seq(nfix + nblk + 1, nfix + nblk + npop)]
eff.blk <- theta.crude[1] * eff.blk
eff.pop <- theta.crude[2] * eff.pop

beta <- c(eff.fix, eff.blk, eff.pop)
scalevec <- rep(c(1, theta.crude), times = c(nfix, nblk, npop))
penaltyvec <- rep(c(0, 1, 1), times = c(nfix, nblk, npop))

modmat <- cbind(modmat.fix, modmat.blk, modmat.pop)
mout <- mlogl(beta, pred, fam, aout$x, aout$root, modmat, deriv = 2)

all.equal(mout$hessian * outer(scalevec, scalevec), pout$mlogl.hessian)
all.equal(tout$argument, pout$argument)
all.equal(scalevec, pout$scale)

all.equal(pout$value,
    mout$value + sum(penaltyvec * pout$argument^2) / 2)
all.equal(pout$gradient,
    mout$gradient * scalevec + penaltyvec * pout$argument)
all.equal(pout$hessian, pout$mlogl.hessian + diag(penaltyvec))

epsilon <- 1e-7
mygradient <- 0 * pout$gradient
myhessian <- 0 * pout$hessian
for (i in seq(along = mygradient)) {
    arg <- tout$argument
    arg[i] <- arg[i] + epsilon
    pout.epsilon <- penmlogl(arg, theta.crude, fixed = modmat.fix,
        random = list(modmat.blk, modmat.pop), obj = aout)
    mygradient[i] <- (pout.epsilon$value - pout$value) / epsilon
    myhessian[i, ] <- (pout.epsilon$gradient - pout$gradient) / epsilon
}
all.equal(mygradient, pout$gradient, tol = 100 * epsilon)
all.equal(myhessian, pout$hessian, tol = 100 * epsilon)

### penmlogl2

foo <- pout$argument
alpha2 <- foo[seq(1, nfix)]
parm2 <- foo[- seq(1, nfix)]
pout2 <- penmlogl2(parm2, alpha2, theta.crude, fixed = modmat.fix,
    random = list(modmat.blk, modmat.pop), obj = aout)
identical(pout$value, pout2$value)
identical(pout$argument, pout2$argument)
identical(pout$scale[- seq(1, nfix)], pout2$scale)
identical(pout$mlogl.hessian, pout2$mlogl.hessian)
identical(pout$mlogl.gradient, pout2$mlogl.gradient)
idx <- seq(nfix + 1, nfix + nblk + npop)
identical(pout2$gradient, pout$gradient[idx])
foom <- pout$hessian
foom <- foom[idx, ]
foom <- foom[ , idx]
identical(pout2$hessian, foom)

back to top