[Ecopd-commits] r46 - in pkg: R man

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Fri Oct 23 18:34:50 CEST 2009


Author: regetz
Date: 2009-10-23 18:34:50 +0200 (Fri, 23 Oct 2009)
New Revision: 46

Modified:
   pkg/R/utilities.R
   pkg/man/tipLength.Rd
Log:
added internal function implementing Dijkstra's algorithm; using this in
tipLength to speed up tip-to-root distance calc by an order of magnitude


Modified: pkg/R/utilities.R
===================================================================
--- pkg/R/utilities.R	2009-10-22 21:55:25 UTC (rev 45)
+++ pkg/R/utilities.R	2009-10-23 16:34:50 UTC (rev 46)
@@ -54,6 +54,38 @@
   return(branch.length)
 }
 
+# internal function to compute distances from one node to all others
+# NOTE: assumes node IDs are always 1:n (currently true of phylo4 objs)
+dijkstra <- function(phy, node) {
+  edge <- edges(phy, drop.root=TRUE)
+  elen <- edgeLength(phy)
+  nodes <- nodeId(phy, "all")
+  n <- length(nodes)
+  d <- rep(Inf, length=n)
+  names(d) <- nodes
+  d[node] <- 0
+  while (length(nodes)>0) {
+    u <- nodes[which.min(d[nodes])[[1]]]
+    if (is.infinite(d[u])) break
+    nodes <- nodes[-match(u, nodes)]
+    anc <- edge[edge[,2]==u,1]
+    for (parent in anc[anc %in% nodes]) {
+      alt <- d[u] + elen[paste(parent, u, sep="-")]
+      if (alt < d[parent]) {
+        d[parent] <- alt
+      }
+    }
+    des <- edge[edge[,1]==u,2]
+    for (child in des[des %in% nodes]) {
+      alt <- d[u] + elen[paste(u, child, sep="-")]
+      if (alt < d[child]) {
+        d[child] <- alt
+      }
+    }
+  }
+  d
+}
+
 # tip length extractor
 tipLength <- function(phy, from=c("parent", "root")) {
   from <- match.arg(from)
@@ -61,11 +93,8 @@
   if (from=="parent") {
     len <- edgeLength(phy, tips)
   } else if (from=="root") {
-    root.node <- rootNode(phy)
-    anc <- ancestors(phy, tips, "ALL")
-    len <- sapply(anc, function(n) {
-      sumEdgeLength(phy, setdiff(n, root.node))
-    })
+    len <- dijkstra(phy, rootNode(phy))
+    len <- len[match(tips, names(len))]
   }
   names(len) <- tipLabels(phy)
   return(len)

Modified: pkg/man/tipLength.Rd
===================================================================
--- pkg/man/tipLength.Rd	2009-10-22 21:55:25 UTC (rev 45)
+++ pkg/man/tipLength.Rd	2009-10-23 16:34:50 UTC (rev 46)
@@ -10,10 +10,17 @@
   tipLength(phy, from=c("parent", "root"))
 }
 \arguments{
-  \item{phy}{a \code{phylo4} object (or one that inherits from it)}
+  \item{phy}{A \code{phylo4} object (or one that inherits from it)}
   \item{from}{Should lengths represent distance from parents only (i.e.,
     simply the lengths of terminal branches), or from the root node?}
 }
+\details{
+  When \code{from} is \code{"parent"}, the function is a straightforward
+  wrapper of the \code{edgeLength} function in the phylobase package.
+  When \code{from} is \code{"root"}, the function uses an implementation
+  of Dijkstra's algorithm to compute the total distance from the root to
+  each of the tips.
+}
 \value{
   Numeric vector of lengths, with the associated tip node labels as
   names.
@@ -25,8 +32,7 @@
 }
 \author{Jim Regetz (regetz at nceas.ucsb.edu)}
 \seealso{
-  Methods \code{\link[phylobase:phylo4-accessors]{edgeLength}} and
-  \code{\link[phylobase:phylo4-accessors]{sumEdgeLength}} in the
+  Method \code{\link[phylobase:phylo4-accessors]{edgeLength}} in the
   phylobase package.
 }
 \examples{



More information about the Ecopd-commits mailing list