df<-read.csv("fluxes_DE-Hai.csv")
options(repr.plot.width=8, repr.plot.height=4)
gpp<-df$GPP
N=length(gpp)
tvec<-as.POSIXct(df$time)
plot(tvec,gpp,"l")
fgpp<-fft(gpp)
print(head(fgpp))
print(" ")
print(tail(fgpp))
plot(Re(fgpp),log="y")
length(fgpp)
fgpp[1]<-0
fgpp_short<-fgpp[1:((N/2)+1)]
plot(1:((N/2)+1),abs(fgpp_short)^2,log="xy")
x<-N/(0:(N/2))
plot(x,abs(fgpp_short)^2,log="xy",xlim=c(4000,2),xlab = "Period",ylab="Power")
inds<-which(x>362 & x<368)
inds
fgpp_filtered<-fgpp
fgpp_filtered[inds]<-0
gpp_seasonal<-fft(fgpp_filtered,inverse=T)/N
plot(tvec,Re(gpp_seasonal),"l")
Ahhh - we forgot the negative frequencies
get_mirror_indices<-function(inds,N) {
N-inds+2
}
inds<-c(inds,get_mirror_indices(inds,N))
inds
fgpp_filtered[inds]<-0
gpp_anomalies<-fft(fgpp_filtered,inverse=T)/N
plot(tvec,Re(gpp_anomalies),"l")
Still a lot of seasonality left -> seasonal cycle has some harmonics
nlower<-360;nupper<-370
inds<-which((x>nlower & x<nupper) | (x>nlower/2 & x<nupper/2) | (x>nlower/3 & x<nupper/3) | (x>nlower/4 & x<nupper/4) | (x>nlower/5 & x<nupper/5) | (x>nlower/6 & x<nupper/6))
inds<-c(inds,get_mirror_indices(inds,N))
fgpp_filtered<-fgpp
fgpp_filtered[inds]<-0
gpp_anomalies<-Re(fft(fgpp_filtered,inverse=T))/N
plot(tvec,Re(gpp_anomalies),"l")
This looks good, now let's check what exactly we just filtered out
fgpp_seasonal <- fgpp-fgpp_filtered
gpp_seasonal <- Re(fft(fgpp_seasonal,inverse=T))/N
plot(tvec,Re(gpp_seasonal),"l")
plot(tvec,gpp_seasonal+gpp_anomalies,"l")
library(EMD)
emd_decomp<-emd(gpp)
par(mfrow=c(1,1))
plot(tvec,emd_decomp$imf[,1],"l",lwd=0.5,ylim=c(-5,5))
for (i in 2:ncol(emd_decomp$imf)) {
lines(tvec,emd_decomp$imf[,i],lwd=0.5)
}
fgpp_seasonal_hilbert<-fgpp_seasonal
fgpp_seasonal_hilbert[1:(N/2)]<-fgpp_seasonal_hilbert[1:(N/2)]*complex(imaginary=-1)
fgpp_seasonal_hilbert[(N/2+1):N]<-fgpp_seasonal_hilbert[(N/2+1):N]*complex(imaginary=1)
gpp_seasonal_hilbert<-Re(fft(fgpp_seasonal_hilbert,inverse=T))/N
plot(tvec,Re(gpp_seasonal),"l",ylim=c(-6,6),xlab = "",ylab = "Signal + Hilbert Transform")
lines(tvec,Re(gpp_seasonal_hilbert),col=2)
amp <- sqrt(abs(gpp_seasonal)^2+abs(gpp_seasonal_hilbert)^2)
plot(tvec,Re(gpp_seasonal),"l",ylim=c(-6,6))
lines(tvec,Re(gpp_seasonal_hilbert),col=2)
lines(tvec,amp,col=3)
plot(tvec,Re(gpp_seasonal),"l",ylim=c(-6,6))
lines(tvec,amp,col=3)
lines(tvec,atan2(Re(gpp_seasonal_hilbert),Re(gpp_seasonal)),col=4)
plot(gpp_anomalies[1:(N-1)],gpp_anomalies[2:N])
myfit <- lm(gpp_anomalies[1:(N-1)] ~ gpp_anomalies[2:N])
myfit
plot(tvec[2:N],residuals(myfit),"l")
#Create fast AR(1) function
library(rustinr)
rust('
// #[rustr_export]
pub fn generate_AR(phi: f64, noise: Vec<f64>) -> Vec<f64> {
let mut lastval = noise[0];
let mut v_out = vec!(lastval);
for i in 1..noise.len() {
let newval = lastval * phi + noise[i];
v_out.push(newval);
lastval = newval
}
return v_out
}
')
options(repr.plot.width=8, repr.plot.height=8)
y1<-generate_AR(0,rnorm(N))
y2<-generate_AR(0.5,rnorm(N))
y3<-generate_AR(0.9,rnorm(N))
y4<-generate_AR(1.0,rnorm(N))
par(mfrow=c(2,2))
plot(tvec,y1,"l",main="Phi=0",lwd=0.2)
plot(tvec,y2,"l",main="Phi=0.5",lwd=0.2)
plot(tvec,y3,"l",main="Phi=0.9",lwd=0.2)
plot(tvec,y4,"l",main="Phi=1.0",lwd=0.2)
print(cor(y3,y4))
print(cor(y1,y2))
par(mfrow=c(2,2))
plot(x,abs(fft(y1)[1:(N/2+1)])^2,xlim = c(N,2),log="x",main = "Spectrum Phi=0")
plot(x,abs(fft(y2)[1:(N/2+1)])^2,xlim = c(N,2),log="x",main = "Spectrum Phi=0.5")
plot(x,abs(fft(y3)[1:(N/2+1)])^2,xlim = c(N,2),log="x",main = "Spectrum Phi=0.9")
plot(x,abs(fft(y4)[1:(N/2+1)])^2,xlim = c(N,2),log="xy",main = "Spectrum Phi=1.0")
par(mfrow=c(2,2))
acf(y1)
acf(y2)
acf(y3)
acf(y4)
options(repr.plot.width=8, repr.plot.height=4)
ysurr<-generate_AR(myfit$coefficients[2],rnorm(N,sd = sd(residuals(myfit))))
plot(tvec,ysurr,"l",lwd=0.2)
lines(tvec,gpp_anomalies,col=4,lwd=0.2)