メモ

  • 昨日の記事でn次元オブジェクトをn-1次元視覚で眺めるために、適当なベクトルを与えて、その超接平面に像を作りたかった
  • それをするのに超接平面の接ベクトルと超平面上のn-1個のベクトルとを取り出したい
# あるベクトルを1つの軸とする正規直交基底
# vは接ベクトル
base.v <- function(v){
# 次元d
	d <- length(v)
# 単位ベクトル化
	v <- v/sqrt(sum(v^2))
	ret <- matrix(0,d,d)
# 第1列は接ベクトルそのもの
# 第2列以降は次の通り
# 第i列については、1,2,...,(i-1)行の成分はvの1,2,...,(i-1)成分に
# 比例した値としておき
# 第i行成分を接ベクトルと直交するための調節成分とする
# このようにすると、求めたいn-1個のベクトルと接ベクトルとの内積の計算と
# 求めたいn-1個のベクトル同士の内積の計算とが、同じになるので、
# 求めたいベクトルの値を接ベクトルとの関係で求めると、
# 漏れなく、他のベクトルとの関係も調整されることを使う
	for(i in 2:(d)){
		ret[1:(i-1),i] <- v[1:(i-1)]
		ret[i,i] <- -sum(v[1:(i-1)]^2)/v[i]
	}
	ret[,1] <- v
# 最後にノルムをそろえて回転行列化する
	q <- sqrt(apply(ret^2,2,sum))
	t(t(ret)/q)
}
out <- base.v(runif(4))
out %*% t(out) # 単位ベクトルが得られる
  • 今、d次元であるベクトルがある理由で選ばれて、それをd次元正規直交基底の1つのベクトルとして取ることにする。
  • 次に、そのベクトルに垂直なベクトルの中から、ある理由でd次元正規直交基底の第2のベクトルを取ることにする(この部分、ある理由、はひとまずおいておいて、ランダムに作って処理を回すことにする)
  • 順次、そんな風にやっていって、d次元正規直交基底を作るには…
# 順次ベクトルを取って正規直交基底を作る関数
serial.ort.base <- function(d){
	m <- matrix(0,d,d)
# だんだんに正規直交基底行列を改変していく
	b.list <- list()
	for(i in 1:(d-1)){
# 次元を減らしつつ、ひとまず減次元空間の単位ベクトルを適当に採用したことにする
		tmp.v <- rnorm(d+1-i)
		tmp.v <- tmp.v/sqrt(sum(tmp.v^2))
# その減次元ベクトルに関して、それを第1の列ベクトルとして、減次元正規直交基底を作る
		tmp.b <- base.v(tmp.v)
		if(i == 1){
			b.list[[i]] <- tmp.b
		}else{
# そのうえで、減次元をd次元に戻す
# 戻すにあたっては取り扱っていない次元の成分は0であって
			tmp.m <- matrix(0,length(tmp.b[,1]),i-1)
			tmp.b2 <- cbind(tmp.m,tmp.b)
# そのうえで、「成分が0」なのは、作りたい正規直交基底で回転した後なので、逆回転しておく
			b.list[[i]] <- cbind(b.list[[i-1]][,1:(i-1)],(b.list[[i-1]]) %*% t(tmp.b2))
		}
	}
	b.list
}
d <- 4
serial.ort.base(d)