- こちらで、多次元の無限空間を有限な角張った空間に納めることについて書いた
- それは、そもそも、「この世の偏微分方程式」が動く世界をそのような空間にしたかったから(昨日の記事がその関係)
- このことを復習する
- n個の変数がを満足する(保存則)
- n個の変数はもしくは(存在則)
- このとき、n個の変数をn個のデカルト座標軸に取れば、保存則と存在則を満足する部分空間は、n-1次元多様体であるn-1正単体(こちら)
- ここで、n-1次元の無限空間に「アトラクタ」や「軌道」「運動」をシミュレーションする(それは、無限空間に取り扱いやすい性質を持つ図形(球とか、(常)らせんとか)を用いると便利)
- その上で、無限空間をn-1正単体に圧縮してやれば、「アトラクタ」「軌道」「運動」が『この世』としての部分空間に納められる
- さて。
- まず、n次元空間をn-1正単体に縮める方法を考える
- 2段階ある
- 無限を有限に
- 無限空間は中心からの距離が一定な球殻が無限距離まで広がっているような空間であるとする
- 距離を有限にする
- tangentを用いて、無限大をMaxXという有限正値に、0を0にマッピングする(以下のソース)
TangentDist<-function(R,MaxX){
tmax<-atan(MaxX)
tan(atan(R)/(pi/2)*tmax)
}
-
- 球を単体に
- 球とは、
- 正単体とは、
- この球にこの正単体は、n個の点で内接する
- この球に内接し、正単体よりも大きく、『球』のように丸味を帯びていて、正単体のように、n方向への突出傾向をもつような図形はで表せる
- Rが大きいとき(R=Rmax)に球であって、Rが小さいとき(R=Rmin)に正単体になるように空間圧縮をするとすれば、のように線形性を持ってkを決めてもよい。
- n-1正単体では、となっているので、以下のようにして縮めることができる
CategoryVector<-
function (nc = 3)
{
df <- nc - 1
d <- df + 1
diagval <- 1:d
diagval <- sqrt((df + 1)/df) * sqrt((df - diagval + 1)/(df -
diagval + 2))
others <- -diagval/(df - (0:(d - 1)))
m <- matrix(rep(others, df + 1), nrow = df + 1, byrow = TRUE)
diag(m) <- diagval
m[upper.tri(m)] <- 0
as.matrix(m[, 1:df])
}
TangentDist<-function(R,MaxX){
tmax<-atan(MaxX)
tan(atan(R)/(pi/2)*tmax)
}
minind<-function(x){
which(x==min(x))[1]
}
minindval<-function(x){
list(ind=minind(x),v=min(x))
}
Sphere2Simplex<-function(x){
if(!is.matrix(x)){
x<-matrix(x,nr=1)
}
n<-length(x[1,])
cv<-CategoryVector(n+1)
X<-x%*%t(cv)
MinIndVal<-matrix(unlist(apply(X,1,minindval)),ncol=2,byrow=TRUE)
r<-sqrt(apply(x^2,1,sum))
tmpr<-TangentDist(r,1)
tmpRatio<-tmpr/(1/(n))
tmpk<-1+tmpRatio
ratio<-(tmpr^2/apply(abs(x)^tmpk,1,sum))^(1/tmpk)
x*ratio
}
xs<-matrix(0,100,3)
xs[1,]<-c(0,0,1)
for(i in 2:100){
xs[i,]<-xs[i-1,]*1.1
}
xsc<-Sphere2Simplex(xs)
plot(xsc[,1])
- これを用いて、n次元正単体空間を動くn+1変数の軌道をn次元空間に描かせよう
CategoryVector<-
function (nc = 3)
{
df <- nc - 1
d <- df + 1
diagval <- 1:d
diagval <- sqrt((df + 1)/df) * sqrt((df - diagval + 1)/(df -
diagval + 2))
others <- -diagval/(df - (0:(d - 1)))
m <- matrix(rep(others, df + 1), nrow = df + 1, byrow = TRUE)
diag(m) <- diagval
m[upper.tri(m)] <- 0
as.matrix(m[, 1:df])
}
TangentDist<-function(R,MaxX){
tmax<-atan(MaxX)
tan(atan(R)/(pi/2)*tmax)
}
minind<-function(x){
which(x==min(x))[1]
}
minindval<-function(x){
list(ind=minind(x),v=min(x))
}
Sphere2Simplex<-function(x){
if(!is.matrix(x)){
x<-matrix(x,nr=1)
}
n<-length(x[1,])
cv<-CategoryVector(n+1)
X<-x%*%t(cv)
MinIndVal<-matrix(unlist(apply(X,1,minindval)),ncol=2,byrow=TRUE)
r<-sqrt(apply(x^2,1,sum))
tmpr<-TangentDist(r,1)
tmpRatio<-tmpr/(1/(n))
tmpk<-1+tmpRatio
ratio<-(tmpr^2/apply(abs(x)^tmpk,1,sum))^(1/tmpk)
x*ratio
}
xs<-matrix(0,100,3)
xs[1,]<-c(0,0,1)
for(i in 2:100){
xs[i,]<-xs[i-1,]*1.1
}
xsc<-Sphere2Simplex(xs)
plot(xsc[,1])
library(rgl)
NormalBase<-function(n){
I<-X<-diag(rep(1,n))
thetas<-runif(n*(n-1)/2)*2*pi
T<-matrix(0,n,n)
T[lower.tri(T)]<-thetas
for(i in 1:(n-1)){
for(j in (i+1):n){
R<-I
R[i,i]<-R[j,j]<-cos(T[j,i])
R[i,j]<-sin(T[j,i])
R[j,i]<--R[i,j]
X<-R%*%X
}
}
X
}
n<-3
np<-2
p<-matrix(rnorm(np*n),np,n)
Niter<-1000
dt<-0.01
dists<-c()
for(i in 1:(np-1)){
for(j in (i+1):np){
dists<-c(dists,sqrt((p[i,]-p[j,])^2))
}
}
Rs<-runif(np,min=0,max=max(dists)/2)
dimRots<-sample(2:n,np,replace=TRUE)
RotsSub<-NULL
RotsSubInv<-NULL
Rots<-NULL
e.outs<-NULL
Rdts<-NULL
for(i in 1:np){
RotsSub[[i]]<-NormalBase(n)
RotsSubInv[[i]]<-solve(RotsSub[[i]])
Rots[[i]]<-diag(rep(1,n))
Rots[[i]][1:dimRots[i],1:dimRots[i]]<-NormalBase(dimRots[i])
e.outs[[i]]<-eigen(Rots[[i]])
Rdts[[i]]<-(e.outs[[i]][[2]])%*%diag((e.outs[[i]][[1]])^dt)%*%solve(e.outs[[i]][[2]])
}
Nrep<-10
xssum<-NULL
col<-c()
xssum<-p
col<-rep(2,np)
k2<-3
fracattraction<-0
for(rep in 1:Nrep){
xs<-matrix(0,Niter,n)
xs[1,]<-rnorm(n)
for(i in 2:Niter){
v<-rep(0,n)
vs<-matrix(0,np,n)
vsRot<-vs
for(j in 1:np){
tmp<-xs[i-1,]-p[j,]
tmp<-RotsSub[[j]]%*%tmp
tmpvs<--tmp
tmpL<-sqrt(sum(tmpvs[1:dimRots[j]]^2))
tmpvs[1:dimRots[j]]<-(tmpL-Rs[j])/tmpL*tmpvs[1:dimRots[j]]
vs[j,]<-RotsSubInv[[j]]%*%tmpvs
vsRot[j,]<-Re((RotsSubInv[[j]])%*%(Rdts[[j]]%*%(tmp)))-(xs[i-1,]-p[j,])
}
tmpl<-sqrt(apply(vs^2,1,sum))
stvs<-sign(tmpl)*vs/tmpl^k2
tmpv<-apply(stvs,2,sum)
tmpv<-tmpv/sqrt(sum(tmpv^2))
v<-fracattraction*tmpv*(cumprod(tmpl)[length(tmpl)])*dt
vsRot<-vsRot/tmpl
tmpvRot<-apply(vsRot,2,sum)
v<-v+tmpvRot
xs[i,]<-xs[i-1,]+v
}
xssum<-rbind(xssum,xs)
col<-c(col,rep(rep,Niter))
}
cex<-rep(0.1,length(col))
cex[1:Nrep]<-3
plot3d(xssum[,1],xssum[,2],xssum[,3],col=col)
filename<-"attractor"
M <- par3d("userMatrix")
play3d( par3dinterp( userMatrix=list(M,
rotate3d(M, pi/2, 1, 0, 0),
rotate3d(M, pi/2, 0, 1, 0) ) ),
duration=4 )
SimplexXs<-Sphere2Simplex(xssum)
SimplexXs<-SimplexXs+1/(n-1)
plot3d(SimplexXs[,1],SimplexXs[,2],SimplexXs[,3],col=col)