- 一昨日の記事で、n変数をn+1次元空間の円運動で表現する、という話をした
- たとえばロトカ-ヴォルテラに、変数別の周期性が入っているようなデータがあったときに、多変量フーリエ変換をして、その結果を個々の変数ごとに評価する場合と、2変数のスペクトルの強さを合わせて評価する場合とでどんな「スペクトル採用」差が出るかをやってみる
my.mvfft <- function(X,ord.k=2){
tmp <- mvfft(X)
md <- Mod(tmp)
md.sum <- apply(md^ord.k,1,sum)
ord <- order(md.sum,decreasing=TRUE)
ret <- tmp[ord,]
ret.md <- md[ord,]
ret.md.sum <- md.sum[ord]
return(list(val=tmp,ord=ord,cmplx=ret,md=ret.md,md.sum=ret.md.sum))
}
my.mvfft.inv <- function(mvout,k=length(mvout$val[,1])){
tmp <- matrix(0,length(mvout$val[,1]),length(mvout$val[1,]))
tmp[mvout$ord[1:k],] <- mvout$val[mvout$ord[1:k],]
ret <- mvfft(tmp,inverse=TRUE)
tmp2 <- matrix(0,length(mvout$val[,1]),length(mvout$val[1,]))
for(i in 1:length(tmp2[1,])){
tmp.ord <- order(Mod(mvout$val[,i]),decreasing=TRUE)
tmp2[tmp.ord[1:k],i] <- mvout$val[tmp.ord[1:k],i]
}
ret.conv <- mvfft(tmp2,inverse=TRUE)
return(list(ret=ret,ret.conv=ret.conv))
}
a <- 0.3796097
b <- 0.8440414
c <- 0.5359939
d <- 0.4014024
k1<-2
k2<-3
x<-c(d/c*0.9)
y<-c(a/b*0.9)
v<-c(-a/y[1]-b*log(y[1])-(c*x[1]-d*log(x[1])))
Niter<-10000
dt<-100/Niter
for(i in 2:Niter){
dxdt<-a*x[i-1]^k1-b*x[i-1]^k1*y[i-1]
dydt<-c*x[i-1]*y[i-1]^k2-d*y[i-1]^k2
dxdt <- dxdt*(1+rnorm(1)*100)
dydt <- dydt*(1+rnorm(1)*100)
x<-c(x,x[i-1]+dxdt*dt)
y<-c(y,y[i-1]+dydt*dt)
v<-c(v,-a/y[i]-b*log(y[i])-(c*x[i]-d*log(x[i])))
}
par(mfcol=c(1,2))
plot(x,y,type="l")
plot(v,ylim=c(-max(abs(v)),max(abs(v))),type="l")
par(mfcol=c(1,1))
tmp.t <- seq(from=0,to=1,length=length(y))*10*pi
n.independent <- 10
for(i in 1:n.independent){
x <- x+sin(tmp.t*4*pi*runif(1))*runif(1)*0.1
y <- y+sin(tmp.t*4*pi*runif(1))*runif(1)*0.1
}
plot(x,y,type="l")
mv.out <- my.mvfft(cbind(x,y),2)
par(mfcol=c(2,3))
for(i in 1:length(x)){
mv.out.inv <- my.mvfft.inv(mv.out,i)
matplot(cbind(x,y),type="l",main="original")
plot(cbind(x,y),type="l",main="original")
par(ask=FALSE)
matplot(Re(mv.out.inv[[1]]),type="l",main="楕円合算")
plot(Re(mv.out.inv[[1]]),type="l",main="楕円合算")
matplot(Re(mv.out.inv[[2]]),type="l",main="通常逆フーリエ")
plot(Re(mv.out.inv[[2]]),type="l",main="通常逆フーリエ")
par(ask=TRUE)
}
par(ask=FALSE)
par(mfcol=c(1,1))