[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