summaryrefslogtreecommitdiff
path: root/R/idinput.R
diff options
context:
space:
mode:
Diffstat (limited to 'R/idinput.R')
-rw-r--r--R/idinput.R156
1 files changed, 156 insertions, 0 deletions
diff --git a/R/idinput.R b/R/idinput.R
new file mode 100644
index 0000000..46b8cad
--- /dev/null
+++ b/R/idinput.R
@@ -0,0 +1,156 @@
+#' function to generate input singals (rgs/rbs/prbs/sine)
+#'
+#' \code{idinput} is a function for generating input signals (rgs/rbs/prbs/sine) for identification purposes
+#'
+#' @param n integer length of the input singal to be generated
+#' @param type the type of input signal to be generated.
+#' 'rgs' - generates random gaussian signal
+#' 'rbs' - generates random binary signal
+#' 'prbs' - generates pseudorandom binary signal
+#' 'sine' - generates a signal that is a sum of sinusoids
+#'
+#' Default value is type='rgs'
+#' @param band determines the frequency content of the signal.
+#' For type='rbs'/'sine'/, band = [wlow,whigh]
+#' which specifies the lower and the upper bound of the passband frequencies(expressed as fractions of Nyquist frequency). Default is c(0,1)
+#' For type='prbs', band=[0,B]
+#' where B is such that the singal is constant over 1/B (clock period). Default is c(0,1)
+#' @param levels row vector defining the input level. It is of the form
+#' levels=c(minu, maxu)
+#' For 'rbs','prbs', 'sine', the generated signal always between minu and maxu.
+#' For 'rgs', minu=mean value of signal minus one standard deviation and maxu=mean value of signal plus one standard deviation
+#'
+#' Default value is levels=c(-1,1)
+#'
+#' @export
+idinput<-function(n,type='rgs',band=c(0,1),levels=c(-1,1)){
+ if(type=="rbs"){
+ rbs(n,band,levels)
+ } else if(type=="rgs"){
+ rgs(n,band,levels)
+ } else if(type=="sine"){
+ multisine(n,1,band,levels)
+ }else if(type=="prbs"){
+ idin.prbs(n,band,levels)
+ }
+}
+
+rgs <- function(n,band,levels){
+ u <- butter_filt(rnorm(n),band)
+ mu<-(levels[1]+levels[2])/2
+ sigma<-(levels[2]-levels[1])/2
+ u*sigma+mu
+}
+
+rbs <- function(n,band,levels){
+ u <- butter_filt(rnorm(n),band)
+ sapply(u,function(x) if(x>0) levels[2] else levels[1])
+}
+
+butter_filt <- function(x,band){
+ filt <- T; type <- "pass"
+ if(band[1]<=2e-3){
+ if(band[2]==1){
+ filt <- F
+ } else{
+ type <- "low"
+ }
+ } else{
+ if(band[2]==1){
+ type <- "high"
+ }
+ }
+ if(filt==T){
+ if(type=="low"){
+ bf <- signal::butter(8,band[2],type,"z")
+ } else if(type=="pass"){
+ bf <- signal::butter(8,band,type,"z")
+ }else{
+ bf <- signal::butter(8,band[1],type,"z")
+ }
+ x <- as.numeric(signal::filter(bf,x))
+ }
+ return(matrix(x,ncol=1))
+}
+
+multisine <- function(N,nin=1,band,levels){
+ sinedata <- list(nSin=10,nTrial=10,gridSkip=1)
+ freq <- 2*pi*seq(1,floor(N/2),by=sinedata$gridSkip)/N
+ band <- band*pi
+ freq <- freq[freq>=band[1] & freq<=band[2]]
+ nl <- length(freq)
+ freqInd <- seq(from=1,to=nl,length.out = nin*sinedata$nSin)
+
+ # Begin Trials
+ trials <- function(x){
+ freqs <- freq[freqInd[seq(from=x,to=nin*sinedata$nSin,by=nin)]]
+ for(k in 1:sinedata$nTrial){
+ utrial <- rowSums(cos(sapply(freqs,
+ function(x) (1:N-1)*x+2*pi*rnorm(1))))
+ if(k==1) u <- utrial; temp <- diff(range(utrial))
+ if(diff(range(utrial))< temp) {
+ u <- utrial; temp <- diff(range(utrial))
+ }
+ }
+ clevel <- max(abs(u))
+ diff(levels)/2/clevel*(u+clevel)+levels[1]
+ }
+ u <- sapply(1:nin,trials)
+ return(u)
+}
+
+#' @import bitops signal
+idin.prbs<-function(n,band=c(0,1),levels=c(0,1)){
+ u <- numeric(0)
+ for(i in 1:18){
+ if(n / (2^i) < 1){
+ u <- idin.prbs12(i,band,levels)
+ break
+ }
+ }
+ return(u[1:n])
+}
+
+idin.prbs12 <- function(N,band=c(0,1),levels=c(0,1)){
+ first=ceiling(abs(rnorm(1)*10)) #some non-zero initial state
+ x= first
+ v = vector()
+ n=2^N-1
+ i=1
+ clock=floor(1/band[2])
+ k=1
+ M=rbind(c(0,0,0,0),c(1,2,0,0),c(1,3,0,0),c(1,4,0,0),c(2,5,0,0),c(1,6,0,0),
+ c(1,7,0,0),c(1,2,7,8),c(4,9,0,0),c(3,10,0,0),c(9,11,0,0),
+ c(6,8,11,12),c(9,10,12,13),c(4,8,13,14),c(14,15,0,0),c(4,13,15,16),
+ c(14,17,0,0),c(11,18,0,0))
+ repeat{
+ a=M[N,1]
+ b=M[N,2]
+ c=M[N,3]
+ d=M[N,4]
+ four=c(8,12,13,14,16)
+ if(N %in% four){
+ e=bitwXor(bitwShiftR(x,N-a),bitwShiftR(x,N-b))
+ f=bitwXor(bitwShiftR(x,N-c),bitwShiftR(x,N-d))
+ newbit=bitwAnd(bitwXor(e,f),1)
+ }else{
+ newbit=bitwAnd(bitwXor(bitwShiftR(x,N-a),bitwShiftR(x,N-b)),1)
+ }
+ if(k>=clock || i==1){
+ v[i]=newbit
+ i=i+1
+ k=1
+ }else{
+ v[i]=v[i-1]
+ i=i+1
+ k=k+1
+ }
+ x=bitwOr(bitwShiftR(x,1),bitwShiftL(newbit,N-1))
+ if(x==first){
+ break
+ }
+ }
+
+ v=sapply(v, function(x){if (x==0) levels[1] else levels[2]})
+ return(v)
+} \ No newline at end of file