Funkcja do interpolacji (smoothing spline):
approxfun2 = function(x,y,...) {
m = smooth.spline(x,y,...)
function(xnew) {
ynew = predict(m, xnew)$y
ynew[xnew>max(x)] = NA
ynew[xnew<min(x)] = NA
ynew
}
}
Ładujemy dane z Fluenta i robimy z nich funkcje czasu:
tab=read.table("~/cl",skip=1,header=TRUE)
tab = tab[-(1:37),]
cl_mr = approxfun2(tab$Flow.Time,tab$cl)
Ładujemy dane z TCLB i robimy z nich funkcje czasu:
tab=read.csv("~/long_base__Log_P00_00000000.csv")
f = 1/1500
R = tab$PDX*2
tab$umax = 2*pi*f*R
tab$cl = -2*tab$ForceY/(tab$PDX * tab$umax^2)
cl_ll = approxfun2(tab$Time_si,tab$cl)
Funkcja do analizy:
decompose = function(fun, k = 1500/2, dt = 5e-2/2) {
A = sapply(0:30,function(i) {
t = seq(0,dt,len=k+1)[-1]+dt*i
fun(t)
}) # Dzieli wyniki na kawalki
sel = !apply(is.na(A),2,any) # eliminuje kawalki z poza zakresu
A = A[,sel]
L = colMeans(A) # Liczy Lrednie w kazdym kawalku
O = rowMeans(A) # Liczy Lrednie po kawalkach
O.sd = apply(A,1,sd) # Liczy odchylenie standardowe po kawalkach
A = A - O # Liczy reszta
pca = prcomp(t(A)) # liczy PCA/POD tej reszty.
var = pca$sdev^2
list(
n = ncol(A),
cuts = A,
means = L,
trend = O,
trend.sd = O.sd,
pc.var = var,
pc.shape = pca$rotation,
pc.coef = t(A) %*% pca$rotation,
pc90 = sum(cumsum(var)/sum(var) < 0.90)+1,
pc99 = sum(cumsum(var)/sum(var) < 0.99)+1
)
}
Puszczenie analizy na obu zestawach danych:
dec_mr = decompose(cl_mr)
dec_ll = decompose(cl_ll)
Plot średniego \(C_L\) w pół-okresach:
plot(dec_mr$means, type="b", ylim=c(-1,3), xlab="Half period",ylab="CL")
lines(dec_ll$means, type="b", col=2)
Plot \(C_L\) w pół-okresie (z \(99\%\) przedziałem ufności):
p = seq(0,0.5,len=1500/2+1)[-1]
s = qnorm(0.995)
plot(p,dec_mr$trend, type="l", ylim=c(-1,3))
lines(p,dec_mr$trend + dec_mr$trend.sd*s, lty=2)
lines(p,dec_mr$trend - dec_mr$trend.sd*s, lty=2)
lines(p,dec_ll$trend, col=2)
lines(p,dec_ll$trend + dec_ll$trend.sd*s, lty=2, col=2)
lines(p,dec_ll$trend - dec_ll$trend.sd*s, lty=2, col=2)
Zróbmy analize PCA/POD reszt (czyli przebiegów minus średni przebieg):
ret = prcomp(t(cbind(dec_mr$cuts/dec_mr$n,dec_ll$cuts/dec_ll$n)))
col = gray.colors(length(ret$sdev))
col[1:3]= 1:3+1
barplot(ret$sdev,ylab="Standard Deviation",names.arg = colnames(ret$rotation),col=col)
I zobaczmy jaką część zmienności realizują kolejne mody (kształty z PCA/POD):
W = cbind(apply(t(dec_mr$cuts) %*% ret$rotation,2,var),
apply(t(dec_ll$cuts) %*% ret$rotation,2,var))
barplot(W,col=col,names.arg = c("MR","LLW"), ylab="Total variance")
Widać że pierwsze 3 mody dominują. wyglądają one tak:
matplot(p,ret$rotation[,1:3],col=1:3+1,type="l",lty=1)