I just realized how to score a major speed-up in computation time from my new Bayesian ancestral character estimation function for continuous traits (
anc.Bayes).
Last night I documented what I thought at the time was a significant speed improvement. By pulling inversion of the phylogenetic VCV matrix
out of the likelihood function (meaning that we only have to do this once instead of every generation of the MCMC), I was able to cut computation time in half (from about 60s on a 100 taxon tree to about 30s). What I didn't realize at the time was that I could also pull out calculation of the determinant of the matrix. The determinant we want is log(|σ
2C|); the way we avoid recalculating this every generation of the MCMC (in which σ
2 can potentially differ) is by taking advantage of the equality:
log(|σ
2C|) =
nlog(σ
2) + log(|
C|)
I actually described this in an earlier paper with Luke Harmon (Revell & Harmon
2008, p. 318), but did not think to apply it to this problem until now. [Note that there is actually a small error in equation (5) of our article:
n·
r·log(
k) should be
n·
r·log(
k)/2.]
This version runs
much faster: now about 4s for the same dataset as before. Unbelievable! Anyway, I have posted the new version on my website
here.
This version is so much faster that I can easily run it for a million generations on the 100 species tree from before. If I plot the estimates from the Bayesian MCMC run with an uninformative prior against the values from ML estimation using
ace() in the ape package, we can see that they are even more tightly correlated than before:
> source("anc.Bayes.R")
> source("vcvPhylo.R")
> X<-anc.Bayes(tree,x,ngen=1000000)
> plot(ace(x,tree)$ace,colMeans(X[21:10001,])[2+1:tree$Nnode])
(compare to
here). The above code took about 6 minutes to run, whereas the first version of
anc.Bayes would've needed about 100 minutes for the same calculations.
I haven't mentioned MCMC diagnostics, priors, or the utility of Bayesian inference at all yet. Hopefully, these will be addressed in future posts.