iccsa-21-wind

git clone https://git.igankevich.com/iccsa-21-wind.git
Log | Files | Refs

commit b01df3952464949a914cb211effff1f21bf59758
parent 71bc63d5d5d2d701c5710ea1647d5cd420d56243
Author: Ivan Gankevich <i.gankevich@spbu.ru>
Date:   Mon, 26 Apr 2021 14:05:18 +0300

Compare VTB and anemometer.

Diffstat:
R/anal.R | 307+------------------------------------------------------------------------------
R/common.R | 19+++++++++++++++++++
R/distributions.R | 273+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
R/vtestbed.R | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 366 insertions(+), 306 deletions(-)

diff --git a/R/anal.R b/R/anal.R @@ -7,244 +7,7 @@ library(gplots) # hist2d registerDoParallel(cores=detectCores()) source("R/common.R") - -datetime_format <- "%FT%H:%M" - -# https://stackoverflow.com/questions/32370485/convert-radians-to-degree-degree-to-radians -rad2deg <- function(rad) {(rad * 180) / (pi)} -deg2rad <- function(deg) {(deg * pi) / (180)} - -# https://stackoverflow.com/questions/27455948/in-r-whats-the-simplest-way-to-scale-a-vector-to-a-unit-vector -unit <- function(x) { - length = sqrt(sum(x**2)) - ifelse(length == 0, x, x/length) -} - -# retain the original sign -power <- function(x,y) { - ifelse(abs(x) < 1, sign(x)*abs(x)**y, x**y) - #sign(x)*abs(x)**y - #abs(x)**y -} - -# normalized rmse -rmse <- function(estimated, actual) { - s_max <- max(actual) - s_min <- min(actual) - sqrt(mean((estimated - actual)**2)) / (s_max - s_min) -} - -dweibull2 <- function (x, a1=1, b1=1, c1=1, a2=1, b2=1, c2=1, g=0) { - #ifelse(x<g, - # a1* abs(c1*b1)*(abs(b1*(x-g))**(c1-1))* exp(-(abs(b1*(x-g))**c1)), - # a1* abs(c2*b2)*(abs(b2*(x-g))**(c2-1))* exp(-(abs(b2*(x-g))**c2))) - ifelse(x<g, - a1*abs(b1*c1)*exp(-(abs(b1*(abs(x-g)-abs((c1-1)/c1)**(1/c1)))**c1)), - a2*abs(b2*c2)*exp(-(abs(b2*(abs(x-g)-abs((c2-1)/c2)**(1/c2)))**c2))) -} - -dweibull4 <- function (x, a1=1, b1=1, c1=1, a2=1, b2=1, c2=1, g1=0, - a3=1, b3=1, c3=1, a4=1, b4=1, c4=1, g2=0) { - ifelse(x<0, - dweibull2(x,a1,b1,c1,a2,b2,c2,g1), - dweibull2(x,a3,b3,c3,a4,b4,c4,g2)) -} - -dvonmises <- function (x, x_mean=0, a=1, b=1, c=1) { - a * exp(b*cos(c*(x-x_mean))) / (2*pi*besselI(b,0)) -} - -dgumbel <- function (x, location=0, scale=1) { - z <- (x-location)/scale - (1/scale) * exp(-(z + exp(-z))) -} - -# https://www.tutorialspoint.com/r/r_mean_median_mode.htm -# https://stackoverflow.com/questions/2547402/how-to-find-the-statistical-mode -getmode <- function(v) { - #uniqv <- unique(v) - #uniqv[which.max(tabulate(match(v, uniqv)))] - as.numeric(names(sort(-table(v)))[1]) -} - -# https://stackoverflow.com/questions/27418461/calculate-the-modes-in-a-multimodal-distribution-in-r -find_peaks_indices <- function (x) { - modes <- c() - for (i in 2:(length(x)-1)){ - if ((x[i] > x[i-1]) & (x[i] > x[i+1])) { - modes <- c(modes,i) - } - } - modes -} - -find_real_peaks_indices <- function (x, max_modes=2) { - n <- 1024 - #x_density <- density(x,n=n,adjust=0.125) - #y <- x_density$y - y <- x - modes <- find_peaks_indices(y) - # find the first N highest peaks - modes_xy <- data.frame(x=modes,y=y[modes]) - modes_xy <- modes_xy[order(modes_xy$y, decreasing=TRUE),] - modes_xy <- modes_xy[c(1:max_modes), ] - # scale indices to [0,1] - (modes_xy$x-1)/(n-1) -} - -find_max_x <- function (x, y) { - n <- length(y)-1 - indices <- c(0:n) - index <- indices[y == max(y)]/n - x[floor(index*(length(x)-1)+1)] -} - -normalize_hist <- function(pdf_x) { - #data.frame(density=pdf_x$density/max(abs(pdf_x$density)),x=pdf_x$mids) - data.frame(density=pdf_x$density,x=pdf_x$mids) -} - -fit_velocity_pdf <- function (xx, x, density, sign=-1, plot=TRUE, axis="x", dist="weibull2") { - a0 <- 0 - b0 <- 0 - c0 <- 1 - c1 <- 3 - indices <- find_real_peaks_indices(x, max_modes=1) - if (FALSE) { - pdf <- normalize_hist(hist(x, plot=FALSE, breaks=1000)) - print(indices) - indices = floor(indices * length(pdf$x)) - x_modes <- pdf$x[indices] - print(x_modes) - model <- nls(pdf$density ~ dweibull4(pdf$x,a1,b1,c1,a2,b2,c2,x_modes[[1]],a3,b3,c3,a4,b4,c4,x_modes[[2]]), - data=pdf, - start=list(a1=1,b1=1,c1=1,a2=1,b2=1,c2=1, - a3=1,b3=1,c3=1,a4=1,b4=1,c4=1), - control=list(warnOnly=TRUE), - algorithm="port", - lower=c(a0,b0,c0,a0,b0,c0,a0,b0,c0,a0,b0,c0), - upper=c(1000,1000,3,1000,2000,3,1000,1000,3,1000,2000,3)) - c = summary(model)$coefficients - if (plot) { - pdf_x_est <- dweibull4(pdf$x,c[[1]],c[[2]],c[[3]],c[[4]],c[[5]],c[[6]],x_modes[[1]], - c[[7]],c[[8]],c[[9]],c[[10]],c[[11]],c[[12]],x_modes[[2]]) - plot(pdf$x, pdf$density, xlab=paste('Velocity', axis), ylab='PDF') - lines(pdf$x, pdf_x_est, col='red') - } - c - } else { - #x_mode <- getmode(x) - #pdf_x <- normalize_hist(hist(x, plot=FALSE, breaks=100)) - pdf_x <- data.frame(x=xx,density=x) - c <- c() - pdf_x_set <- c() - if (dist == "weibull2") { - x_mode <- find_max_x(pdf_x$x,pdf_x$density) - #indices = floor(indices * length(pdf_x$x)) + 1 - #x_mode <- pdf_x$x[indices][[1]] - c <- tryCatch( - { - model <- nls(pdf_x$density ~ dweibull2(pdf_x$x,a,b,c,d,e,f,g=x_mode), - data=pdf_x, - start=list(a=1,b=1,c=1,d=1,e=1,f=1), - control=list(warnOnly=TRUE), - algorithm="port", - lower=c(a0,b0,c0,a0,b0,c0), upper=c(1000,1000,c1,1000,2000,c1)) - summary(model)$coefficients - }, - error=function(cond) { - message(cond) - c(1,1,1,1,1,1) - }) - pdf_x_est <- dweibull2(pdf_x$x,c[[1]],c[[2]],c[[3]],c[[4]],c[[5]],c[[6]],x_mode) - } else if (dist == "vonmises") { - c <- tryCatch({ - model <- nls(density ~ dvonmises(2*pi*pdf_x$x/(max(pdf_x$x)),0,a,b,c), - data=pdf_x, - start=list(a=1,b=1,c=1), - control=list(warnOnly=TRUE), - algorithm="port", - lower=c(0,1,0), upper=c(1000,1000,pi)) - c <- summary(model)$coefficients - print(c) - },error=function(cond) { - message(cond) - c(1,1,1) - }) - pdf_x_est <- dvonmises(2*pi*pdf_x$x/max(pdf_x$x),0,c[[1]],c[[2]],c[[3]]) - } else if (dist == "gumbel") { - c <- tryCatch( - { - model <- nls(pdf_x$density ~ c*dgumbel(pdf_x$x,location=a,scale=b), - data=pdf_x, - start=list(a=1,b=1,c=1), - control=list(warnOnly=TRUE), - algorithm="port", - lower=c(-1000,0.1,c=1), upper=c(1000,1000,1000)) - c = summary(model)$coefficients - }, - error=function(cond) { - message(cond) - c <- c(1,1,1,1) - }) - pdf_x_est <- c[[3]]*dgumbel(pdf_x$x,location=c[[1]],scale=c[[2]]) - } else if (dist == "norm") { - fit <- fitdist(pdf_x$x, "norm") - c <- coef(fit) - pdf_x_est <- dnorm(pdf_x$x,mean=c[[1]],sd=c[[2]]) - } else if (dist == "rayleigh") { - c <- tryCatch( - { - model <- nls(pdf_x$density ~ b*dweibull(sign*pdf_x$x,scale=a,shape=2), - data=pdf_x, - start=list(a=1,b=1), - control=list(warnOnly=TRUE), - algorithm="port", - lower=c(0.1,0), upper=c(1000,1000)) - c = summary(model)$coefficients - }, - error=function(cond) { - message(cond) - c <- c(1,1,1,1) - }) - pdf_x_est <- c[[2]]*dweibull(sign*pdf_x$x,scale=c[[1]],shape=2) - } else { - x_mode <- find_max_x(pdf_x$x,pdf_x$density) - c <- tryCatch( - { - model <- nls(pdf_x$density ~ c*dweibull(sign*pdf_x$x,scale=a,shape=b), - data=pdf_x, - start=list(a=1,b=1,c=1), - control=list(warnOnly=TRUE), - algorithm="port", - lower=c(0.1,0.1,0), - upper=c(1000,1000,1000)) - c = summary(model)$coefficients - }, - error=function(cond) { - message(cond) - c <- c(1,1,1,1) - }) - pdf_x_est <- c[[3]]*dweibull(sign*pdf_x$x,scale=c[[1]],shape=c[[2]]) - } - #if (plot) { - # plot(sign*pdf_x$x, pdf_x$density, xlab=paste('Velocity', axis), ylab='PDF') - # lines(density(sign*x), col='blue') - # lines(sign*pdf_x$x, pdf_x_est, col='red') - #} - #if (sign < 0) { - # print(pdf_x$x) - # pdf_x$x = -rev(pdf_x$x) - # pdf_x$density = rev(pdf_x$density) - # pdf_x_est = rev(pdf_x_est) - #} - list(coefficients=c, - actual_density=pdf_x$density, - estimated_density=pdf_x_est, - x=pdf_x$x, - residual=max(abs(pdf_x$density-pdf_x_est))) - } -} +source("R/distributions.R") fit_velocity_pdf_bilateral <- function (velocity, axis="x", timestamp=0, dist="weibull") { velocity_hist <- normalize_hist(hist(velocity, plot=FALSE, breaks=100)) @@ -277,45 +40,6 @@ fit_velocity_pdf_bilateral <- function (velocity, axis="x", timestamp=0, dist="w rmse=rmse(estimated_density, actual_density)) } -fit_velocity_pdf_v2 <- function (x, sign=-1, plot=TRUE, axis="x") { - #fit <- fitdist(x, "weibull") - x_mode <- getmode(x) - fit <- fitdist(x-x_mode, "weibull2", start=list(a1=1, b1=1, c1=1, a2=1, b2=1, c2=1)) - if (plot) { - plot(fit) - } - coef(fit) -} - -fit_velocity_acf <- function (velocity, plot=TRUE, axis="x", timestamp=0, write=TRUE) { - acf_x <- acf(velocity, type="covariance", plot=FALSE) - acf_x <- data.frame(acf=acf_x$acf, lag=acf_x$lag) - model <- nls(acf ~ a*exp(-abs(b*lag)**c), - data=acf_x, - start=list(a=1,b=1,c=1), - control=list(warnOnly=TRUE), - algorithm="port", - lower=c(0,0,1e-6), upper=c(1000,1000,10)) - c <- summary(model)$coefficients - acf_est <- c[[1]]*exp(-abs(c[[2]]*acf_x$lag)**c[[3]]) - if (plot) { - plot(acf_x$lag, acf_x$acf, xlab='Lag', ylab=paste('ACF', axis)) - lines(acf_x$lag, acf_est, col='red') - } - if (write) { - path <- file.path('build', 'acf', axis) - make_directory(path) - filename <- file.path(path, sprintf("%d", timestamp)) - write.table(data.frame(lag=acf_x$lag,actual=acf_x$acf,estimated=acf_est), - filename, row.names=FALSE, quote=FALSE) - } - list(coefficients=c, - rmse=rmse(acf_est,acf_x$acf), - lag=acf_x$lag, - actual=acf_x$acf, - estimated=acf_est) -} - fit_velocity_acf_bilateral <- function (velocity, axis="x", timestamp=0, plot=TRUE) { v = velocity model_1 <- fit_velocity_acf(v[v<=0], axis=axis, timestamp=timestamp, plot=FALSE, write=FALSE); @@ -350,35 +74,6 @@ fit_velocity_acf_bilateral <- function (velocity, axis="x", timestamp=0, plot=TR estimated=estimated) } -fit_direction <- function (theta, density, plot=TRUE) { - pdf_x <- data.frame(x=theta,density=density); - #print(pdf_x) - scale <- max(abs(theta)) - c <- tryCatch({ - model <- nls(density ~ dvonmises(2*pi*x/scale-m,0,a,b,c), - data=pdf_x, - start=list(a=1,b=1,c=1,m=0), - control=list(warnOnly=TRUE), - algorithm="port", - lower=c(0,1,0,-10), - upper=c(1000,1000,1000,10)) - c <- summary(model)$coefficients - },error=function(cond) { - message(cond) - c(1,1,1) - }) - pdf_x_est <- dvonmises(2*pi*pdf_x$x/scale,c[[4]],c[[1]],c[[2]],c[[3]]) - if (plot) { - plot(pdf_x$x, pdf_x$density, xlab='Direction', ylab='PDF') - lines(pdf_x$x, pdf_x_est, col='red') - } - list(coefficients=c, - actual_density=pdf_x$density, - estimated_density=pdf_x_est, - x=pdf_x$x, - residual=max(abs(pdf_x$density-pdf_x_est))) -} - fit_direction_bilateral <- function (direction, plot=TRUE, timestamp=0, dist="vonmises") { hist <- normalize_hist(hist(direction, plot=FALSE, breaks=1000)) x = hist$x; diff --git a/R/common.R b/R/common.R @@ -96,6 +96,8 @@ select_samples <- function (timestamp, time_delta, url="samples/load-cell.sqlite velocity } +datetime_format <- "%FT%H:%M" + time_string_to_timestamp <- function(str) { as.integer(as.POSIXct(strptime(str, datetime_format))) } @@ -103,3 +105,20 @@ time_string_to_timestamp <- function(str) { make_directory <- function (path) { dir.create(path, recursive=TRUE, showWarnings=FALSE) } + +# https://stackoverflow.com/questions/32370485/convert-radians-to-degree-degree-to-radians +rad2deg <- function(rad) {(rad * 180) / (pi)} +deg2rad <- function(deg) {(deg * pi) / (180)} + +# https://stackoverflow.com/questions/27455948/in-r-whats-the-simplest-way-to-scale-a-vector-to-a-unit-vector +unit <- function(x) { + length = sqrt(sum(x**2)) + ifelse(length == 0, x, x/length) +} + +# normalized rmse +rmse <- function(estimated, actual) { + s_max <- max(actual) + s_min <- min(actual) + sqrt(mean((estimated - actual)**2)) / (s_max - s_min) +} diff --git a/R/distributions.R b/R/distributions.R @@ -0,0 +1,273 @@ +dweibull2 <- function (x, a1=1, b1=1, c1=1, a2=1, b2=1, c2=1, g=0) { + #ifelse(x<g, + # a1* abs(c1*b1)*(abs(b1*(x-g))**(c1-1))* exp(-(abs(b1*(x-g))**c1)), + # a1* abs(c2*b2)*(abs(b2*(x-g))**(c2-1))* exp(-(abs(b2*(x-g))**c2))) + ifelse(x<g, + a1*abs(b1*c1)*exp(-(abs(b1*(abs(x-g)-abs((c1-1)/c1)**(1/c1)))**c1)), + a2*abs(b2*c2)*exp(-(abs(b2*(abs(x-g)-abs((c2-1)/c2)**(1/c2)))**c2))) +} + +dweibull4 <- function (x, a1=1, b1=1, c1=1, a2=1, b2=1, c2=1, g1=0, + a3=1, b3=1, c3=1, a4=1, b4=1, c4=1, g2=0) { + ifelse(x<0, + dweibull2(x,a1,b1,c1,a2,b2,c2,g1), + dweibull2(x,a3,b3,c3,a4,b4,c4,g2)) +} + +dvonmises <- function (x, x_mean=0, a=1, b=1, c=1) { + a * exp(b*cos(c*(x-x_mean))) / (2*pi*besselI(b,0)) +} + +dgumbel <- function (x, location=0, scale=1) { + z <- (x-location)/scale + (1/scale) * exp(-(z + exp(-z))) +} + +# https://www.tutorialspoint.com/r/r_mean_median_mode.htm +# https://stackoverflow.com/questions/2547402/how-to-find-the-statistical-mode +getmode <- function(v) { + #uniqv <- unique(v) + #uniqv[which.max(tabulate(match(v, uniqv)))] + as.numeric(names(sort(-table(v)))[1]) +} + +# https://stackoverflow.com/questions/27418461/calculate-the-modes-in-a-multimodal-distribution-in-r +find_peaks_indices <- function (x) { + modes <- c() + for (i in 2:(length(x)-1)){ + if ((x[i] > x[i-1]) & (x[i] > x[i+1])) { + modes <- c(modes,i) + } + } + modes +} + +find_real_peaks_indices <- function (x, max_modes=2) { + n <- 1024 + #x_density <- density(x,n=n,adjust=0.125) + #y <- x_density$y + y <- x + modes <- find_peaks_indices(y) + # find the first N highest peaks + modes_xy <- data.frame(x=modes,y=y[modes]) + modes_xy <- modes_xy[order(modes_xy$y, decreasing=TRUE),] + modes_xy <- modes_xy[c(1:max_modes), ] + # scale indices to [0,1] + (modes_xy$x-1)/(n-1) +} + +find_max_x <- function (x, y) { + n <- length(y)-1 + indices <- c(0:n) + index <- indices[y == max(y)]/n + x[floor(index*(length(x)-1)+1)] +} + +normalize_hist <- function(pdf_x) { + #data.frame(density=pdf_x$density/max(abs(pdf_x$density)),x=pdf_x$mids) + data.frame(density=pdf_x$density,x=pdf_x$mids) +} + +fit_velocity_pdf <- function (xx, x, density, sign=-1, plot=TRUE, axis="x", dist="weibull2") { + a0 <- 0 + b0 <- 0 + c0 <- 1 + c1 <- 3 + indices <- find_real_peaks_indices(x, max_modes=1) + if (FALSE) { + pdf <- normalize_hist(hist(x, plot=FALSE, breaks=1000)) + print(indices) + indices = floor(indices * length(pdf$x)) + x_modes <- pdf$x[indices] + print(x_modes) + model <- nls(pdf$density ~ dweibull4(pdf$x,a1,b1,c1,a2,b2,c2,x_modes[[1]],a3,b3,c3,a4,b4,c4,x_modes[[2]]), + data=pdf, + start=list(a1=1,b1=1,c1=1,a2=1,b2=1,c2=1, + a3=1,b3=1,c3=1,a4=1,b4=1,c4=1), + control=list(warnOnly=TRUE), + algorithm="port", + lower=c(a0,b0,c0,a0,b0,c0,a0,b0,c0,a0,b0,c0), + upper=c(1000,1000,3,1000,2000,3,1000,1000,3,1000,2000,3)) + c = summary(model)$coefficients + if (plot) { + pdf_x_est <- dweibull4(pdf$x,c[[1]],c[[2]],c[[3]],c[[4]],c[[5]],c[[6]],x_modes[[1]], + c[[7]],c[[8]],c[[9]],c[[10]],c[[11]],c[[12]],x_modes[[2]]) + plot(pdf$x, pdf$density, xlab=paste('Velocity', axis), ylab='PDF') + lines(pdf$x, pdf_x_est, col='red') + } + c + } else { + #x_mode <- getmode(x) + #pdf_x <- normalize_hist(hist(x, plot=FALSE, breaks=100)) + pdf_x <- data.frame(x=xx,density=x) + c <- c() + pdf_x_set <- c() + if (dist == "weibull2") { + x_mode <- find_max_x(pdf_x$x,pdf_x$density) + #indices = floor(indices * length(pdf_x$x)) + 1 + #x_mode <- pdf_x$x[indices][[1]] + c <- tryCatch( + { + model <- nls(pdf_x$density ~ dweibull2(pdf_x$x,a,b,c,d,e,f,g=x_mode), + data=pdf_x, + start=list(a=1,b=1,c=1,d=1,e=1,f=1), + control=list(warnOnly=TRUE), + algorithm="port", + lower=c(a0,b0,c0,a0,b0,c0), upper=c(1000,1000,c1,1000,2000,c1)) + summary(model)$coefficients + }, + error=function(cond) { + message(cond) + c(1,1,1,1,1,1) + }) + pdf_x_est <- dweibull2(pdf_x$x,c[[1]],c[[2]],c[[3]],c[[4]],c[[5]],c[[6]],x_mode) + } else if (dist == "vonmises") { + c <- tryCatch({ + model <- nls(density ~ dvonmises(2*pi*pdf_x$x/(max(pdf_x$x)),0,a,b,c), + data=pdf_x, + start=list(a=1,b=1,c=1), + control=list(warnOnly=TRUE), + algorithm="port", + lower=c(0,1,0), upper=c(1000,1000,pi)) + c <- summary(model)$coefficients + },error=function(cond) { + message(cond) + c(1,1,1) + }) + pdf_x_est <- dvonmises(2*pi*pdf_x$x/max(pdf_x$x),0,c[[1]],c[[2]],c[[3]]) + } else if (dist == "gumbel") { + c <- tryCatch( + { + model <- nls(pdf_x$density ~ c*dgumbel(pdf_x$x,location=a,scale=b), + data=pdf_x, + start=list(a=1,b=1,c=1), + control=list(warnOnly=TRUE), + algorithm="port", + lower=c(-1000,0.1,c=1), upper=c(1000,1000,1000)) + c = summary(model)$coefficients + }, + error=function(cond) { + message(cond) + c <- c(1,1,1,1) + }) + pdf_x_est <- c[[3]]*dgumbel(pdf_x$x,location=c[[1]],scale=c[[2]]) + } else if (dist == "norm") { + fit <- fitdist(pdf_x$x, "norm") + c <- coef(fit) + pdf_x_est <- dnorm(pdf_x$x,mean=c[[1]],sd=c[[2]]) + } else if (dist == "rayleigh") { + c <- tryCatch( + { + model <- nls(pdf_x$density ~ b*dweibull(sign*pdf_x$x,scale=a,shape=2), + data=pdf_x, + start=list(a=1,b=1), + control=list(warnOnly=TRUE), + algorithm="port", + lower=c(0.1,0), upper=c(1000,1000)) + c = summary(model)$coefficients + }, + error=function(cond) { + message(cond) + c <- c(1,1,1,1) + }) + pdf_x_est <- c[[2]]*dweibull(sign*pdf_x$x,scale=c[[1]],shape=2) + } else { + x_mode <- find_max_x(pdf_x$x,pdf_x$density) + c <- tryCatch( + { + model <- nls(pdf_x$density ~ c*dweibull(sign*pdf_x$x,scale=a,shape=b), + data=pdf_x, + start=list(a=1,b=1,c=1), + control=list(warnOnly=TRUE), + algorithm="port", + lower=c(0.1,0.1,0), + upper=c(1000,1000,1000)) + c = summary(model)$coefficients + }, + error=function(cond) { + message(cond) + c <- c(1,1,1,1) + }) + pdf_x_est <- c[[3]]*dweibull(sign*pdf_x$x,scale=c[[1]],shape=c[[2]]) + } + #if (plot) { + # plot(sign*pdf_x$x, pdf_x$density, xlab=paste('Velocity', axis), ylab='PDF') + # lines(density(sign*x), col='blue') + # lines(sign*pdf_x$x, pdf_x_est, col='red') + #} + #if (sign < 0) { + # print(pdf_x$x) + # pdf_x$x = -rev(pdf_x$x) + # pdf_x$density = rev(pdf_x$density) + # pdf_x_est = rev(pdf_x_est) + #} + list(coefficients=c, + actual_density=pdf_x$density, + estimated_density=pdf_x_est, + x=pdf_x$x, + residual=max(abs(pdf_x$density-pdf_x_est))) + } +} + +fit_velocity_acf <- function (velocity, plot=TRUE, axis="x", timestamp=0, write=TRUE, + debug=FALSE) { + acf_x <- acf(velocity, type="covariance", plot=FALSE) + acf_x <- data.frame(acf=acf_x$acf, lag=acf_x$lag) + if (debug) { + plot(acf_x$lag, acf_x$acf, xlab='Lag', ylab=paste('DEBUG ACF', axis)) + } + model <- nls(acf ~ a*exp(-abs(b*lag)**c), + data=acf_x, + start=list(a=1,b=1,c=1), + control=list(warnOnly=TRUE), + algorithm="port", + lower=c(0,0,1e-6), upper=c(1000,1000,10)) + c <- summary(model)$coefficients + acf_est <- c[[1]]*exp(-abs(c[[2]]*acf_x$lag)**c[[3]]) + if (plot) { + plot(acf_x$lag, acf_x$acf, xlab='Lag', ylab=paste('ACF', axis)) + lines(acf_x$lag, acf_est, col='red') + } + if (write) { + path <- file.path('build', 'acf', axis) + make_directory(path) + filename <- file.path(path, sprintf("%d", timestamp)) + write.table(data.frame(lag=acf_x$lag,actual=acf_x$acf,estimated=acf_est), + filename, row.names=FALSE, quote=FALSE) + } + list(coefficients=c, + rmse=rmse(acf_est,acf_x$acf), + lag=acf_x$lag, + actual=acf_x$acf, + estimated=acf_est) +} + +fit_direction <- function (theta, density, plot=TRUE) { + pdf_x <- data.frame(x=theta,density=density); + #print(pdf_x) + scale <- max(abs(theta)) + c <- tryCatch({ + model <- nls(density ~ dvonmises(2*pi*x/scale-m,0,a,b,c), + data=pdf_x, + start=list(a=1,b=1,c=1,m=0), + control=list(warnOnly=TRUE), + algorithm="port", + lower=c(0,1,0,-10), + upper=c(1000,1000,1000,10)) + c <- summary(model)$coefficients + },error=function(cond) { + message(cond) + c(1,1,1) + }) + pdf_x_est <- dvonmises(2*pi*pdf_x$x/scale,c[[4]],c[[1]],c[[2]],c[[3]]) + if (plot) { + plot(pdf_x$x, pdf_x$density, xlab='Direction', ylab='PDF') + lines(pdf_x$x, pdf_x_est, col='red') + } + list(coefficients=c, + actual_density=pdf_x$density, + estimated_density=pdf_x_est, + x=pdf_x$x, + residual=max(abs(pdf_x$density-pdf_x_est))) +} + diff --git a/R/vtestbed.R b/R/vtestbed.R @@ -0,0 +1,73 @@ +source("R/common.R") +source("R/distributions.R") + +# the timestamp against which the simulation output is validated +time_start = 1616936400 +time_end = time_start +time_delta = 60*60*2 + +data <- read.table("samples/vtestbed/statistics.log", sep=",", header=TRUE) +#data <- data[c("time","wind_velocity_x","wind_velocity_y","wind_velocity_z")] +#plot(data$time, data$wind_velocity_x) +#plot(data$time, data$wind_velocity_y) +#plot(data$time, data$wind_velocity_z) +data$speed <- speed(data$wind_velocity_x,data$wind_velocity_y,data$wind_velocity_z) +data$direction <- direction(data$wind_velocity_x,data$wind_velocity_y) +#hist(data$speed) +#hist(data$direction) + + +do_fit_velocity <- function (velocity) { + velocity_hist <- normalize_hist(hist(velocity, plot=FALSE, breaks=100)) + x = velocity_hist$x; + v = velocity_hist$density; + d = density(velocity,adjust=0.5) + dist <- fit_velocity_pdf(x, v, density=d$y, sign=1, axis="v", dist="weibull") + plot(x, dist$actual_density, xlab='Wind speed', ylab='PDF') + lines(d, col='green', lwd=2) + lines(dist$x, dist$estimated_density, col='red', lwd=2) + dist +} + +do_fit_direction <- function (direction) { + hist <- normalize_hist(hist(direction, plot=FALSE, breaks=1000)) + x = hist$x; + v = hist$density; + d = density(direction,adjust=0.5) + dist <- fit_direction(x, v, plot=FALSE) + plot(x, dist$actual_density, xlab='Direction', ylab='PDF') + lines(d, col='green', lwd=2) + lines(dist$x, dist$estimated_density, col='red', lwd=2) + dist +} + +do_fit_acf <- function (velocity, axis="x") { + v = velocity + model <- fit_velocity_acf(v, axis=axis, plot=FALSE, write=FALSE); + plot(model$lag, model$actual, xlab='Lag', ylab=paste('ACF ', axis, sep="")) + lines(model$lag, model$estimated, col='red', lwd=2) + model +} + +# https://stackoverflow.com/questions/19918985/r-plot-only-text +banner <- function (str) { + plot(c(0, 1), c(0, 1), ann = F, bty = 'n', type = 'n', xaxt = 'n', yaxt = 'n') + text(x = 0.5, y = 0.5, str, cex = 1.6, col = "black") +} + +banner("Virtual testbed") +dist_speed <- do_fit_velocity(data$speed) +dist_direction <- do_fit_direction(data$direction) +#model_acf_x <- do_fit_acf(data$wind_velocity_x, axis="X") +model_acf_y <- do_fit_acf(data$wind_velocity_y, axis="Y") +#model_acf_z <- do_fit_acf(data$wind_velocity_z, axis="Z") + +banner("Anemometer") +data_real <- select_samples(time_start, time_delta) +dist_speed_real <- do_fit_velocity(data_real$speed) +dist_direction_real <- do_fit_direction(data_real$direction) +model_acf_x <- do_fit_acf(data_real$x[data_real$x<=0], axis="X") +model_acf_y <- do_fit_acf(data_real$y[data_real$y<=0], axis="Y") +model_acf_z <- do_fit_acf(data_real$z[data_real$z<=0], axis="Z") + +#print(data)