- Brownian excursionというのがある
- どういうことかというと、1次元数直線の原点から正の方向に出発し、酔歩する。ただし、原点に戻ってしまったら終わり、というルール
- このブラウン運動的な小旅行(excursion)、ブラウン散歩は、「木」のルートから『木の外側』をたどって歩くのと同じである、という話
- ブラウン散歩の位置座標を表す関数をgとすれば、gの値が増えているときというのは、木の枝が成長しているとき
- gが小さくなっているときは、ルートに向かって歩いているとき
- gが減少から増加に転ずるときに、分岐することにする
- そうすると、この関数gによって木が一意に決まる
- gの最大値は、木のルートからの最遠点になる
- gが単調増加して、ピークになって単調減少するような場合には、ルートから枝が一本伸びているだけの構造で、それを往復することになる
- これを用いて離散ブラウン散歩データから木構造を作ろう…とがんばってみて、「できた!」と思ったのだが、そしてできていたのだが
- できた瞬間に、馬鹿みたいに簡単な方法があることに気づくことは、ままあって…
- ブラウン散歩の各点の間に距離を計算する。ただし、その距離は、時刻s,tの位置、g(s),g(t)と、時刻s~tの間のもっとも値の小さいgの値、min(g,s,t)とを使って、g(s)+g(t)-2min(g,s,t)で定まる
- こうすると、すべての点ペアの木構造上の距離になっている
- すべての点ペアの距離が行列で作れるので、neighbor joiningを使えば、節ノードも適切に発生しつつ、木構造が得られる(今の場合、もとの距離データが正確に木になっているので、必ず正解が返ってくる)
- それだけ!
library(ape)
my.tree.dist <- function(g){
n <- length(g)
ret <- matrix(0,n,n)
for(i in 1:(n-1)){
for(j in (i+1):n){
ret[i,j] <- ret[j,i] <- g[i]+g[j]-2*min(g[i:j])
}
}
ret
}
n <- 200
t <- c(0,sort(runif(n)),1)
s <- rnorm(length(t))
S <- cumsum(s)
S <- S-S[1]
S <- S-t*S[length(S)]
Splus <- abs(S)
d.mat.2 <- my.tree.dist(Splus)
nj.out2 <- nj(d.mat.2)
plot(nj.out2,"f",show.tip.label=FALSE)
- 延々と書いたコードもいつか役に立つかもしれないので貼っておく
t2 <- t[1:2]
Splus2 <- Splus[1:2]
Splus.diff <- diff(Splus)
for(i in 2:length(Splus.diff)){
if(sign(Splus.diff[i-1])==sign(Splus.diff[i])){
t2 <- c(t2,t2[length(t2)],t[i+1])
Splus2 <- c(Splus2,Splus2[length(Splus2)],Splus[i+1])
}else{
t2 <- c(t2,t[i+1])
Splus2 <- c(Splus2,Splus[i+1])
}
}
matplot(t,cbind(S,Splus),type="l")
points(t2,Splus2,col=3)
Splus.diff2 <- diff(Splus2)
N <- length(Splus2)
Edges <- t(matrix(Splus2[-N],nrow=2))
Elen <- Edges[,2]-Edges[,1]
Branch <- rep(0,length(Elen))
Branch <- (1:length(Elen))-1
for(i in 2:length(Branch)){
Inside <- which((Edges[,1]-Edges[i,1])*(Edges[,2]-Edges[i,1]) < 0)
if(length(which(Inside < i))>0){
Branch[i] <- max(Inside[which(Inside < i)])
}
}
plot(t2,Splus2,type="b")
abline(h=Edges[,1],col=2)
Branch
vs <- c(1,2)
es <- matrix(c(1,2),nrow=1)
elen <- c(Elen[1])
stend.E <- matrix(0,nrow(Edges),2)
stend.E[1,] <- c(1,2)
for(i in 1:length(Elen)){
selected <- which(Branch==i)
if(length(selected)==0){
next
}
selected.st <- Edges[selected,1]
vs.on.this.edge <- sort(unique(c(Edges[i,],selected.st)))
tmp.n <- length(vs.on.this.edge)-2
new.vs <- c()
if(tmp.n>0){
new.vs <- length(vs)+(1:tmp.n)
}
vid.on.this.edge <- c(stend.E[i,1],new.vs,stend.E[i,2])
if(tmp.n>0){
vs <- c(vs,new.vs)
remove.edge <- which(es[,1]==stend.E[i,1] & es[,2]==stend.E[i,2])
new.edge <- cbind(c(es[remove.edge,1],new.vs),c(new.vs,es[remove.edge,2]))
new.edge.len <- diff(sort(unique(c(Edges[i,],selected.st))))
es <- rbind(es,new.edge)
es <- es[-remove.edge,]
elen <- c(elen,new.edge.len)
elen <- elen[-remove.edge]
}
for(j in 1:length(selected)){
tmp.v <- which(vs.on.this.edge == selected.st[j])
tmp.new.v <- length(vs)+1
vs <- c(vs,tmp.new.v)
es <- rbind(es,c(tmp.v,tmp.new.v))
stend.E[selected[j],] <- c(tmp.v,tmp.new.v)
elen <- c(elen,Elen[selected[j]])
}
tmp.g <- graph.edgelist(es,directed=FALSE)
}
g3 <- graph.edgelist(es,directed=FALSE)
E(g3)$weight <- elen
plot(g3)
d.mat <- shortest.paths(g3,weights=elen)
nj.out <- nj(d.mat)
plot(nj.out)