/auteur/R/likelihood.R

http://github.com/eastman/auteur · R · 99 lines · 73 code · 16 blank · 10 comment · 10 complexity · 1559bfe06110024a3628dd91d9552af4 MD5 · raw file

  1. #primary function for computing the likelihood of data, given a root state, VCV matrix, and Brownian motion model
  2. #author: LJ HARMON 2009 and JM EASTMAN 2010
  3. bm.lik.fn <-
  4. function(root, dat, vcv, SE) {
  5. # mod 12.02.2010 JM Eastman: using determinant()$modulus rather than det() to stay in log-space
  6. y=dat
  7. b <- vcv
  8. if(any(SE!=0)) diag(b)=diag(b)+SE^2
  9. w <- rep(root, nrow(b))
  10. num <- -t(y-w)%*%solve(b)%*%(y-w)/2
  11. den <- 0.5*(length(y)*log(2*pi) + as.numeric(determinant(b)$modulus))
  12. list(
  13. root=root,
  14. lnL = (num-den)[1,1]
  15. )
  16. }
  17. #primary function for computing the likelihood of data, using REML, under Brownian motion model
  18. #author: LJ HARMON, LJ REVELL, and JM EASTMAN 2011
  19. bm.reml.fn <-
  20. function(pruningwise.tre, pruningwise.rates, ic) {
  21. new.tre=updatetree(pruningwise.tre, pruningwise.rates)
  22. new.var=pic_variance(new.tre)
  23. reml=dnorm(ic, mean=0, sd=sqrt(new.var), log=TRUE)
  24. list(
  25. root=NA,
  26. lnL = sum(reml)
  27. )
  28. }
  29. #compute expected PIC variance given tree: used for bm.reml.fn()
  30. #author: JM EASTMAN 2011
  31. pic_variance <- function(phy)
  32. {
  33. nb.tip <- Ntip(phy)
  34. nb.node <- phy$Nnode
  35. if (nb.node != nb.tip - 1) stop("'phy' is not rooted and fully dichotomous")
  36. phy <- reorder(phy, "pruningwise")
  37. ans <- .C("pic_variance", as.integer(nb.tip), as.integer(nb.node),
  38. as.integer(phy$edge[, 1]), as.integer(phy$edge[, 2]),
  39. as.double(phy$edge.length), double(nb.node),
  40. PACKAGE = "auteur")
  41. var <- ans[[6]]
  42. names(var) <- as.character(1:nb.node + nb.tip)
  43. var
  44. }
  45. ou.lik.fn <- function(dat, phy, epochs, phyobject, ancestors, vcvSE, rate, alpha, regimes) {
  46. # mod 02.22.2010 JM Eastman
  47. phyobject$regimes=regimes
  48. ww <- ouweights(phy, epochs, phyobject, ancestors, alpha)
  49. w <- ww$W
  50. v <- oumat(vcvSE, alpha, rate)
  51. y <- matrix(ww$optima, ncol=1)
  52. e <- w%*%y - dat
  53. dim(e) <- n <- length(dat)
  54. q <- e%*%solve(v,e)
  55. det.v <- determinant(v,logarithm=TRUE)
  56. dev <- n*log(2*pi)+as.numeric(det.v$modulus)+q[1,1]
  57. list(
  58. weight=w,
  59. vcov=v,
  60. resid=e,
  61. predict=y,
  62. lnL=-0.5*dev
  63. )
  64. }
  65. #general phylogenetic utility for determining whether to accept ('r'=1) or reject ('r'=0) a proposed model in Markov chain Monte Carlo sampling
  66. #author: JM EASTMAN 2010
  67. assess.lnR <-
  68. function(lnR) {
  69. if(is.na(lnR) || abs(lnR)==Inf) {
  70. error=TRUE
  71. r=0
  72. } else {
  73. if(lnR < -20) {
  74. r=0
  75. } else if(lnR > 0) {
  76. r=1
  77. } else {
  78. r=exp(lnR)
  79. }
  80. error=FALSE
  81. }
  82. return(list(r=r, error=error))
  83. }