グラフのゼータ関数

  • 資料
  • 伊原のゼータ関数を非正則グラフにまで拡張したのが橋本のゼータ関数
    • \zeta_G(u)^{-1} = (1-u^2)^{m-n} det(I-uA + u^2(D-I))
      • ただし、uは複素数、mとnはグラフGのエッジ数とノード数、det(M)はMの行列式で、Iはノード数xノード数の単位行列、AはGの隣接行列、DはGのノードの次数を対角成分とする対角行列
    • ちなみに、グラフラプラシアンL=D-Aで、これは、ゼータ関数行列式を取っている部分のu=1に相当する(I- 1A +1^2(D-I) = I -A + D - I = D-A)。
  • Bartholdiのゼータ関数は、2つの複素数を取る関数
    • \zeta_G(u,t)^{-1}_{Barthroldi} = (1-(1-u)^2)t^2)^{m-n} det(I-tA + (1-u)(D-(1-u)I)t^2)
      • ここで\zeta_G(u=0,t)^{-1}_{Barthroldi} = \zeta_G(t)^{-1}という関係が成り立つ
  • 以下では、複素行列の行列式の計算をするためにcomplexplusパッケージを使っている。伊原のゼータ関数(橋本版)は、Barthroldiの特殊版として書いてある
  • 検算例として、ノード数5の完全グラフK5を用いている。K5の伊原のゼータ関数多項式表現はこちらにあるように(そしてsagemathを導入すれば引き出せるように)、(-1) \times (3\times t - 1) \times (t + 1)^5 \times (t - 1)^6 \times (3 \times t^2 + t + 1)^4
library(igraph)
library(complexplus)
my.Ihara.zeta.elem <- function(g){
	A <- as.matrix(as_adjacency_matrix(g))
	n.v <- length(V(g))
	n.e <- length(E(g))
	r <- n.e - n.v
	D <- diag(degree(g))
	H <- diag(degree(g)-1) 
	I <- diag(rep(1,n.v))
	return(list(r=r,A=A,H=H,I=I,D=D))
}
my.Ihara.zeta.ori <- function(g,u){
	elem <- my.Ihara.zeta.elem(g)
	1/((1-u^2)^elem$r * Det(elem$I-u*elem$A + u^2*elem$H))
}

my.Bartholdi.zeta <- function(g,u,t){
	elem <- my.Ihara.zeta.elem(g)
	tmp <- (1-(1-u)^2*t^2)^elem$r * Det(elem$I-t*elem$A+(1-u)*(elem$D-(1-u)*elem$I)*t^2)
	return(1/tmp)
}

my.Ihara.zeta <- function(g,u){
	my.Bartholdi.zeta(g,0,u)
}
fu <- function(u){
	tmp <- (-1)*(3*u-1)*(u+1)^5*(u-1)^6*(3*u^2+u+1)^4
	return(1/tmp)
}

#g <- sample_gnp(10, 2/10)
n <- 5
adj <- matrix(1,n,n)
diag(adj) <- 0
g <- graph.adjacency(adj,mode="undirected")

x <- y <- seq(from=-0.8,to=0.8,length=100)

xy <- expand.grid(x,y)
xy. <- xy[,1] + 1i*xy[,2]

vs <- rep(0,length(xy.))
vs2 <- vs
for(i in 1:length(vs)){
	vs[i] <- my.Ihara.zeta(g,xy.[i])
	vs2[i] <- fu(xy.[i])
}
my.Ihara.zeta(g,vs[55])
fu(vs[55])
plot(xy,col=abs(Mod(vs)))