X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=R%2Frtree.R;h=46f9abd3c3cc435de4adc92fb0a32d1b73bbb1e7;hb=0875d81d5ba5e6dfe79d42c21b0284b674c73949;hp=6829b02d294be46753894cea6f074f5e09bfbd3d;hpb=3ad385892d75db5c646c92f0f631ae9c5e3da4f6;p=ape.git diff --git a/R/rtree.R b/R/rtree.R index 6829b02..46f9abd 100644 --- a/R/rtree.R +++ b/R/rtree.R @@ -1,8 +1,8 @@ -## rtree.R (2000-05-13) +## rtree.R (2010-03-09) -## Generates Random Trees +## Generates Trees -## Copyright 2004-2009 Emmanuel Paradis +## Copyright 2004-2010 Emmanuel Paradis ## This file is part of the R-package `ape'. ## See the file ../COPYING for licensing issues. @@ -94,7 +94,10 @@ rtree <- function(n, rooted = TRUE, tip.label = NULL, br = runif, ...) phy$tip.label <- if (is.null(tip.label)) paste("t", sample(n), sep = "") else sample(tip.label) - if (is.function(br)) phy$edge.length <- br(nbr, ...) + if (!is.null(br)) { + phy$edge.length <- + if (is.function(br)) br(nbr, ...) else rep(br, length.out = nbr) + } phy$Nnode <- n - 2L + rooted class(phy) <- "phylo" phy @@ -107,7 +110,7 @@ rcoal <- function(n, tip.label = NULL, br = "coalescent", ...) edge <- matrix(NA, nbr, 2) ## coalescence times by default: x <- if (is.character(br)) 2*rexp(n - 1)/(as.double(n:2) * as.double((n - 1):1)) - else br(n - 1, ...) + else if (is.numeric(br)) rep(br, length.out = n - 1) else br(n - 1, ...) if (n == 2) { edge[] <- c(3L, 3L, 1:2) edge.length <- rep(x, 2) @@ -150,3 +153,60 @@ rmtree <- function(N, n, rooted = TRUE, tip.label = NULL, br = runif, ...) class(a) <- "multiPhylo" a } + +stree <- function(n, type = "star", tip.label = NULL) +{ + type <- match.arg(type, c("star", "balanced", "left", "right")) + n <- as.integer(n) + if (type == "star") { + N <- n + m <- 1L + } else { + m <- n - 1L + N <- n + m - 1L + } + edge <- matrix(0L, N, 2) + + switch(type, "star" = { + edge[, 1] <- n + 1L + edge[, 2] <- 1:n + }, "balanced" = { + if (log2(n) %% 1) + stop("'n' is not a power of 2: cannot make a balanced tree") + foo <- function(node, size) { + if (size == 2) { + edge[c(i, i + 1L), 1L] <<- node + edge[c(i, i + 1L), 2L] <<- c(nexttip, nexttip + 1L) + nexttip <<- nexttip + 2L + i <<- i + 2L + } else { + for (k in 1:2) { # do the 2 subclades + edge[i, ] <<- c(node, nextnode) + nextnode <<- nextnode + 1L + i <<- i + 1L + foo(nextnode - 1L, size/2) + } + } + } + i <- 1L + nexttip <- 1L + nextnode <- n + 2L + foo(n + 1L, n) + }, "left" = { + edge[c(seq.int(from = 1, to = N - 1, by = 2), N), 2L] <- 1:n + nodes <- (n + 1L):(n + m) + edge[seq.int(from = 2, to = N - 1, by = 2), 2L] <- nodes[-1] + edge[, 1L] <- rep(nodes, each = 2) + }, "right" = { + nodes <- (n + 1L):(n + m) + edge[, 1L] <- c(nodes, rev(nodes)) + edge[, 2L] <- c(nodes[-1], 1:n) + }) + + if (is.null(tip.label)) + tip.label <- paste("t", 1:n, sep = "") + phy <- list(edge = edge, tip.label = tip.label, Nnode = m) + class(phy) <- "phylo" + attr(phy, "order" <- "cladewise") + phy +}