巡回群の双対群

  • 巡回群の性質から、群Gとその双対群\hat{G}の要素たちは、それぞれの生成元を用いて\sigma^0,\sigma^1,...,\sigma_{n-1}\chi^0,\chi^1,...,\chi^{n-1}と書ける。今、\chi^1という関数(双対群の要素は群の要素を体の値に変換する関数)を\sigma^1に適用して\zetaという体F(複素数だと思っておこう)上の値になるとする。
  • それを\chi^1(\sigma^1)=\zetaと書く。
  • ここでこの\zetaは1のn乗根(exp^{\frac{2\pi i}{n})だと言う。(それは、n個の要素がぐるぐる回ってn回転すると元に戻る、という巡回群の性質が決めること)
  • この\zetaを使って\chi^i(\sigma^k)=\zeta^{ik}という関係にあることも確かめられる(自分ではちゃんとは確かめられないけれど、そうなる、というのが当たり前であることは感じられる)。
  • さて。
  • 巡回群のn個の元のそれぞれに複素数を対応づけて、それをx=(x_0,...,x_{n-1}とする。
  • それを使って群行列A_{Cn}を作ることは2つ前の記事に書いた。再掲する。
n <- 5
make.Acn <- function(Xs){
	n <- length(Xs)
	nv <- 1:n
	ret <- matrix(0,n,n)
	for(i in 1:n){
		ret[i,] <- Xs[nv]
		nv <- c(nv[n],nv[-n])
	}
	ret
}
make.Acn(Xs)
make.K <- function(n){
	Xs <- c(0,1,rep(0,n-2))
	make.Acn(Xs)
}
make.Acn.2 <- function(Xs){
	n <- length(Xs)
	K <- make.K(n)
	E <- diag(rep(1,n))
	ret <- matrix(0,n,n)
	for(i in 1:n){
		ret <- ret + Xs[i] * E
		E <- K %*% E
	}
	ret
}
Xs <- runif(n) + 1i*runif(n)
Acn <- make.Acn.2(Xs)
  • 次に、\zetaを使って\chi^i (\sigma^k)を要素とする行列Pを作ろう
zeta <- exp(2*pi*1i/n)
P <- matrix(0,n,n)
for(i in 1:n){
	for(j in 1:n){
		P[i,j] <- zeta^((i-1)*(j-1))
	}
}
P
  • ここで、\zetaxとを使って、Y_k = \sum_{i=0}^{n-1} \zeta^{ik}x_iを定義する。これも以下のように計算しておく。
Y <- rep(0,n)
for(i in 1:n){
	Y[i] <- sum(zeta^((i-1)*(0:(n-1)))*Xs)
}
Y
  • このYを対角成分とする行列Dも作ろう。
D <- diag(Y)
D
  • ちなみに、ここでは
  • このとき3つの行列の間にはA_{Cn} P = P Dなる関係がある(ちなみに、これは巡回群の場合ではなく有限アーベル群に言えることらしい)。
Acn %*% P - P %*% D
  • また、Yは群行列Acnの固有値になっているという。それもRで確認しておこう。
eigen.out <- eigen(Acn)
eigen.out[[1]]
Y
  • Yの作り方とeigen()関数が出す固有値の順序が違うので、対応をとって、確かに同じであることを確認するために、複素数の絶対値でソートして表示する。
mod.Y <- Mod(Y)
ord.y <- order(mod.Y)
mod.eigen.1 <- Mod(eigen.out[[1]])
ord.e <- order(mod.eigen.1)

ord.Y <- Y[ord.y]
ord.eigen.1 <- eigen.out[[1]][ord.e]

ord.Y
ord.eigen.1
  • また、(\chi_i (\sigma_k))はn個の複素数のベクトルであるが、これがYの1つを固有値とする固有ベクトルであることも以下のように確認しておく。固有値固有ベクトルを確かめる各式の値が0になっていることが読み取りにくいので、得られるベクトルの要素の絶対値の最大値を確認し地得る
for(i in 1:n){
	print("--")
	print(Acn %*% zeta^((i-1)*(0:(n-1))) - Y[i] * zeta^((i-1)*(0:(n-1))))
	print(Acn %*% eigen.out[[2]][,i] - eigen.out[[1]][i] * eigen.out[[2]][,i])
	print("==")
	print(max(Mod(Acn %*% zeta^((i-1)*(0:(n-1))) - Y[i] * zeta^((i-1)*(0:(n-1))))))
	print(max(Mod(Acn %*% eigen.out[[2]][,i] - eigen.out[[1]][i] * eigen.out[[2]][,i])))

}
  • また群行列Acnの行列式det(A_{Cn}) = \prod (Y)となるという。Rでは複素行列の行列式を返す関数が見当たらないので、これは確かめずに、そういうものだとしておこう。逆に言うと群行列の場合、その行列式固有値の積として計算すればよい、と言っているともいえる
# 実行列の場合
AA <- matrix(runif(25),5,5)
det(AA)
prod(eigen(AA)[[1]])
  • また、Pも複素行列なわけだが、この行列式\Delta_n = \prod_{i=1}^{n-1} \prod_{k=0}^{i-1} \zeta^k (\zeta^{i-k}-1)で計算されると言う。
detP <- function(n){
	zeta <- exp(2*pi*1i/n)
	ret <- 1
	for(i in 1:(n-1)){
		for(j in 0:(i-1)){
			ret <- ret * zeta^j*(zeta^(i-j)-1)
		}
	}
	ret
}
nn <- 6
detPs <- rep(0,nn)
for(i in 1:nn){
	detPs[i] <- detP(i)
}
    • Wikipediaポントリャーギン双対の記事
      • 『G を局所コンパクト可換群とするとき、G の指標とは円周群 T に値を持つ G 上の連続群準同型のことである。G の指標全体の成す集合はそれ自身が G の双対群と呼ばれる局所コンパクト群を成すことが示される。』とある。また、『整数全体が加法に関して成す無限巡回群 Z 上の指標は、生成元である 1 の行き先によって決まる。つまり、Z 上の指標 χ に対し χ(n) = χ(1)n が成り立ち、さらにこの式は T から χ(1) となるべき値を任意に選ぶことで定まる』ともある。