summaryrefslogtreecommitdiff
path: root/R/sim.R
diff options
context:
space:
mode:
Diffstat (limited to 'R/sim.R')
-rw-r--r--R/sim.R87
1 files changed, 87 insertions, 0 deletions
diff --git a/R/sim.R b/R/sim.R
new file mode 100644
index 0000000..2efa74e
--- /dev/null
+++ b/R/sim.R
@@ -0,0 +1,87 @@
+#' Simulate response of dynamic system
+#'
+#' Simulate the response of a system to a given input
+#'
+#' @param model the linear system to simulate
+#' @param input a vector/matrix containing the input
+#' @param addNoise logical variable indicating whether to add noise to the
+#' response model. (Default: \code{FALSE})
+#' @param innov an optional times series of innovations. If not supplied (specified
+#' as \code{NULL}), gaussian white noise is generated, with the variance specified in
+#' the model (Property: \code{noiseVar})
+#' @param seed integer indicating the seed value of the random number generator.
+#' Useful for reproducibility purposes.
+#'
+#' @return
+#' a vector containing the simulated output
+#'
+#' @details
+#' The routine is currently built only for SISO systems. Future versions will
+#' include support for MIMO systems.
+#'
+#' @examples
+#' # ARX Model
+#' u <- idinput(300,"rgs")
+#' model <- idpoly(A=c(1,-1.5,0.7),B=c(0.8,-0.25),ioDelay=1,
+#' noiseVar=0.1)
+#' y <- sim(model,u,addNoise=TRUE)
+#'
+#' @export
+sim <- function(model,input,addNoise = F,innov=NULL,seed=NULL) UseMethod("sim")
+
+#' @export
+sim.default <- function(model,input,addNoise = F,innov=NULL,seed=NULL){
+ print("The sim method is not developed for the current class of the object")
+}
+
+#' @import signal polynom
+#' @export
+sim.idpoly <- function(model,input,addNoise = F,innov=NULL,seed=NULL){
+ B <- c(rep(0,model$ioDelay),model$B)
+ Gden <- as.numeric(polynomial(model$A)*polynomial(model$F1))
+ G <- signal::Arma(b=B,a=Gden)
+ ufk <- signal::filter(G,input)
+ yk <- as.numeric(ufk)
+
+ if(addNoise){
+ n <- ifelse(is.numeric(input),length(input),dim(input)[1])
+ if(!is.null(innov)){
+ ek <- innov
+ } else{
+ if(!is.null(seed)) set.seed(seed)
+ ek <- rnorm(n,sd=sqrt(model$noiseVar))
+ }
+ den1 <- as.numeric(polynomial(model$A)*polynomial(model$D))
+ filt1 <- Arma(b=model$C,a=den1)
+ vk <- signal::filter(filt1,ek)
+
+ yk <- yk + as.numeric(vk)
+ }
+
+ return(yk)
+}
+
+# sim_arx <- function(model,input,ek){
+# na <- length(model$A) - 1; nk <- model$ioDelay;
+# nb <- length(model$B) - 1; nb1 <- nb+nk
+# n <- max(na,nb1)
+# coef <- matrix(c(model$A[-1],model$B),nrow=na+(nb+1))
+#
+# if(class(input)=="idframe"){
+# uk <- input$input[,1,drop=T]
+# } else if(class(input) %in% c("matrix","data.frame")){
+# uk <- input[,1,drop=T]
+# } else if(is.numeric(input)){
+# uk <- input
+# }
+#
+# y <- rep(0,length(input)+n)
+# u <- c(rep(0,n),uk)
+#
+# for(i in n+1:length(uk)){
+# if(nk==0) v <- u[i-0:nb] else v <- u[i-nk:nb1]
+# reg <- matrix(c(-(y[i-1:na]),v),ncol=na+(nb+1))
+# y[i] <- reg%*%coef + ek[i]
+# }
+# return(y[n+1:length(uk)])
+# } \ No newline at end of file