-## ace.R (2009-03-22)
+## ace.R (2010-02-03)
-## Ancestral Character Estimation
+## Ancestral Character Estimation
-## Copyright 2005-2009 Emmanuel Paradis and Ben Bolker
+## Copyright 2005-2010 Emmanuel Paradis and Ben Bolker
## This file is part of the R-package `ape'.
## See the file ../COPYING for licensing issues.
model = if (type == "continuous") "BM" else "ER",
scaled = TRUE, kappa = 1, corStruct = NULL, ip = 0.1)
{
- if (class(phy) != "phylo")
+ if (!inherits(phy, "phylo"))
stop('object "phy" is not of class "phylo".')
if (is.null(phy$edge.length))
stop("tree has no branch lengths")
if (model == "BM") {
tip <- phy$edge[, 2] <= nb.tip
dev.BM <- function(p) {
+ if (p[1] < 0) return(1e100) # in case sigma² is negative
x1 <- p[-1][phy$edge[, 1] - nb.tip]
x2 <- numeric(length(x1))
x2[tip] <- x[phy$edge[tip, 2]]
}
if (model == "SYM") {
np <- nl * (nl - 1)/2
- rate[col(rate) < row(rate)] <- 1:np
+ sel <- col(rate) < row(rate)
+ rate[sel] <- 1:np
rate <- t(rate)
- rate[col(rate) < row(rate)] <- 1:np
+ rate[sel] <- 1:np
}
} else {
if (ncol(model) != nrow(model))
np <- max(rate)
}
index.matrix <- rate
- index.matrix[cbind(1:nl, 1:nl)] <- NA
- rate[cbind(1:nl, 1:nl)] <- 0
- rate[rate == 0] <- np + 1 # to avoid 0's since we will use this an numeric indexing
+ tmp <- cbind(1:nl, 1:nl)
+ index.matrix[tmp] <- NA
+ rate[tmp] <- 0
+ rate[rate == 0] <- np + 1 # to avoid 0's since we will use this as numeric indexing
liks <- matrix(0, nb.tip + nb.node, nl)
- for (i in 1:nb.tip) liks[i, x[i]] <- 1
+ TIPS <- 1:nb.tip
+ liks[cbind(TIPS, x)] <- 1
phy <- reorder(phy, "pruningwise")
Q <- matrix(0, nl, nl)
+ ## from Rich FitzJohn:
+ comp <- numeric(nb.tip + nb.node) # Storage...
dev <- function(p, output.liks = FALSE) {
Q[] <- c(p, 0)[rate]
diag(Q) <- -rowSums(Q)
anc <- phy$edge[i, 1]
des1 <- phy$edge[i, 2]
des2 <- phy$edge[j, 2]
- tmp <- eigen(Q * phy$edge.length[i], symmetric = FALSE)
- P1 <- tmp$vectors %*% diag(exp(tmp$values)) %*% solve(tmp$vectors)
- tmp <- eigen(Q * phy$edge.length[j], symmetric = FALSE)
- P2 <- tmp$vectors %*% diag(exp(tmp$values)) %*% solve(tmp$vectors)
- liks[anc, ] <- P1 %*% liks[des1, ] * P2 %*% liks[des2, ]
+ v.l <- matexpo(Q * phy$edge.length[i]) %*% liks[des1, ]
+ v.r <- matexpo(Q * phy$edge.length[j]) %*% liks[des2, ]
+ v <- v.l * v.r
+ comp[anc] <- sum(v)
+ liks[anc, ] <- v/comp[anc]
}
- if (output.liks) return(liks[-(1:nb.tip), ])
- - 2 * log(sum(liks[nb.tip + 1, ]))
+ if (output.liks) return(liks[-TIPS, ])
+ -2 * sum(log(comp[-TIPS]))
}
out <- nlminb(rep(ip, length.out = np), function(p) dev(p),
lower = rep(0, np), upper = rep(Inf, np))
else obj$se <- sqrt(diag(solve(h)))
obj$index.matrix <- index.matrix
if (CI) {
- lik.anc <- dev(obj$rates, TRUE)
- lik.anc <- lik.anc / rowSums(lik.anc)
- colnames(lik.anc) <- lvls
- obj$lik.anc <- lik.anc
+ obj$lik.anc <- dev(obj$rates, TRUE)
+ colnames(obj$lik.anc) <- lvls
}
}
obj$call <- match.call()
table <- data.frame(ll, df, ddf, dev,
pchisq(dev, ddf, lower.tail = FALSE))
dimnames(table) <- list(1:length(X), c("Log lik.", "Df",
- "Df change", "Deviance",
+ "Df change", "Resid. Dev",
"Pr(>|Chi|)"))
structure(table, heading = "Likelihood Ratio Test Table",
class = c("anova", "data.frame"))