library(onion)
a <- runif(4)
q <- a[1] * H1 + a[2] * Hi + a[3] * Hj + a[4] * Hk
q. <- a[1] * 1 + a[2] * 1i + a[3] *Hj + a[4] * Hk
q == q.
qs <- c(H1,Hi,Hj,Hk)
lab <- c("1","i","j","k")
for(i in 1:4){
for(j in 1:4){
tmp <- paste(lab[i],lab[j],sep="*")
print(tmp)
print(qs[i]*qs[j])
}
}
q[[1]]
c(q[[2]],q[[3]],q[[4]])
get.comp(q,1)
get.comp(q,2)
Re(q)
Im(q)
i(q)
j(q)
k(q)
-
- 四元数の積の分解
-
- commutative partとnon-commutative part(cross-product部分)とに分けてある
- さらに右辺第1項は[tex:\frac{qp+pq}{2}=S(q)S(p) - + S(q)V(p)+S(p)V(q)]となる
- 第2項は、虚ベクトル部分のみで計算しても同じなので[tex:qp=S(q)S(p) - + S(q)V(p)+S(p)V(q)+V(q) \times V(p)]
- これをRで書くと
p <- rquat(1)
q <- rquat(1)
q
p
-g.even(Im(q),Im(p))
g.odd(Im(q),Im(p))
q * p
g.even(q,p) + g.odd(q,p)
Re(q) * Re(p) + g.even(Im(q),Im(p)) + Re(q) * Im(p) + Re(p) * Im(q) + g.odd(Im(q),Im(p))
Norm(q)
Norm(p)
Norm(q*p)
Norm(q)*Norm(p)
-
- 共役四元数
- 実部・虚部の取り出しと共役四元数
- 共役と積の順序交換
q
Conj(q)
(q+Conj(q))/2
Re(q)
(q-Conj(q))/2
Im(q)
Conj(q*p)
Conj(p)*Conj(q)
-
- Involutions( を満足する関数)
- Hi,Hj,Hkごとに定まるInvolutionのセットがCanonical involutions
q
-Hi * q * Hi
-(Hi * (-Hi * q * Hi) * Hi)
my.involution <- function(q,p){
p. <- Im(p)
p. <- p./sqrt(Norm(p.))
-p. * q * p.
}
my.involution(my.involution(q,Hi),Hi)
my.involution(my.involution(q,Hj),Hj)
my.involution(my.involution(q,Hk),Hk)
p
p. <- Im(p)
p. <- p./sqrt(Norm(p.))
Norm(p.)
q
my.involution(my.involution(q,p.),p.)
p <- rquat(1)
q <- rquat(1)
r <- rquat(1)
my.involution(q*p,r) - my.involution(q,r) * my.involution(p,r)
my.involution(my.involution(q,r),r) - q
my.involution(my.involution(q,Hi),Hj) - my.involution(q,Hk)
q^(-1)
Conj(q)/sqrt(Norm(q))
q * q^(-1)
-
- 除算
- p/q はp*(q^(-1))か(q^(-1)) * pかの区別がつかないので注意
- 角座標的にunit quaternionとスカラーの積で表す
q
q. <- q/sqrt(Norm(q))
sqrt(Norm(q))
q.
Norm(q.)
n <- 3
library(GPArotation)
R <- Random.Start(n)
p <- q <- quaternion(1)
Im(p) <- R[,1]
Im(q) <- R[,2]
r <- p*q
r. <- q*p
g.even(p,q)
r
R[,3]
-
- 指数・対数
- 複素数を長さと角とに分けたとき、角の方の指数は単位円周をぐるぐる回り、長さが実数の指数関数になったように、四元数でも単位四元数とそのスカラー倍に分けて扱う
- 、ただしはV(q)の単位純虚四元数
- 対数は
- 複素数の対数は、複素数で、実部と虚部とに分けられる。四元数のそれも、実部と虚部とに分ける。
q <- rquat(1)
Sq <- Re(q)
Vq <- Im(q)
Vq.len <- sqrt(Norm(Vq))
V.st <- Vq/Vq.len
exp(Sq) * (cos(Vq.len) + V.st*sin(Vq.len))
exp(q)
log(q)
log(sqrt(Norm(q))) + log(q/sqrt(Norm(q)))
q
mu <- Im(q)/sqrt(Norm(Im(q)))
phi <- atan(sqrt(Norm(Im(q)))/Re(q))
sqrt(Norm(q)) * exp(phi * mu)
sqrt(Norm(q)) * (cos(phi) + mu * sin(phi))
-
-
- 四元数の表記法はいろいろある
- オイラー
- オイラー角
- Cayley-Dickson。二つの複素数に分解する
- のようにiのみの虚部を持つ二つの複素数に分ける
- Ortho-split/symplectic
- もしくはのように、「共役複素数」的な分解もあって、これがCayley-Dicksonの「一般形」
- i,j,kのような特定の軸に依存させずに方向をとった上で、と垂直なと併せてCayley-Dickson的に表す
- 2つの直交純虚単位四元数を取り、それによって分解する
q <- rquat(1)
R <- Random.Start(n)
m <- n <- quaternion(1)
Im(m) <- R[,1]
Im(n) <- R[,2]
q.p <- 1/2*(q+m*q*n)
q.n <- 1/2*(q-m*q*n)
q.p + q.n - q
-
-
- Cj ペア記法
- Ortho-split記法の軸をHjにして、四元数を複素数のペアで表すことにすると、四元数の演算が簡略化される。それは、Hi,Hj,Hkの間にあるぐるぐる回って、その3つ以外は現れない、という性質からくる
- また、non-commutative であったはずの四元数積がcommutativeに扱えるようになる
- と分解してのペアを考えるということ
- いくつかの計算例を以下に示す
my.Cj <- function(H){
ret <- rep(0,2)
ret[1] <- Re(H)+1i*j(H)
ret[2] <- i(H)+1i*k(H)
ret
}
q <- rquat(1)
q
q.Cj <- my.Cj(q)
q.Cj
my.Cj(Conj(q))
q.conj.Cj <- c(Conj(q.Cj[1]),-q.Cj[2])
q.conj.Cj
my.Cj(q^(-1))
c(Conj(q.Cj[1])/Norm(q),-q.Cj[2]/Norm(q))
M1 <- diag(rep(1,4))
Mi <- Mj <- Mk <- matrix(0,4,4)
Mi[1,2] <- Mi[4,3] <- 1
Mi[2,1] <- Mi[3,4] <- -1
Mj[1,3] <- Mj[2,4] <- 1
Mj[3,1] <- Mj[4,2] <- -1
Mk[1,4] <- Mk[3,2] <- 1
Mk[2,3] <- Mk[4,1] <- -1
q <- rquat(1)
p <- rquat(1)
p.mat <- Re(p)*M1 + i(p)*Mi + j(p)*Mj + k(p)*Mk
q.mat <- Re(q)*M1 + i(q)*Mi + j(q)*Mj + k(q)*Mk
p*q
p.mat %*% q.mat
Mc1 <- diag(rep(1,2))
Mci <- Mcj <- Mck <- matrix(0,2,2)
Mci[1,1] <- 1i
Mci[2,2] <- -1i
Mcj[1,2] <- -1
Mcj[2,1] <- 1
Mck[1,2] <- -1i
Mck[2,1] <- -1i
p.matc <- Re(p)*Mc1 + i(p)*Mci + j(p)*Mcj + k(p)*Mck
q.matc <- Re(q)*Mc1 + i(q)*Mci + j(q)*Mcj + k(q)*Mck
p*q
p.matc %*% q.matc