R - My conditional and nested for loop take too long. How to vectorize? -
i have following code for loop contains conditional if-statement included last 10 loop cycles search change in logical pattern, , increment counter on true:
for(ii in 100:sp) { if(start(ii) == 1 && mean(start(ii-11:ii-1)) == 0) { count = count + 1 } }
the value of sp 3,560,400; meaning loop of 3 million plus times. load time enormous, 40 minutes execute loop.
how can optimize code using perhaps vectorization?
thank help.
edit
i have included of code here can see happening:
# store current directory initial.dir<-getwd() # change new directory setwd("h:/r/range") # load necessary libraries - sound library(sound) library(ttr) ##################################################### # load .wav file / set output file ##################################################### # set output file sink("rangetmp3.out") # load dataset sndsample <- loadsample('range.wav') fs <- rate(sndsample) nbits <- bits(sndsample) # assign sound wave y <- sound(sndsample) ##################################################### # constants ##################################################### #(m/s) speed of light c <- 3e8 ############################ # |- radar parameters ############################ #(s) pulse time tp <- 20e-3 # number of samples per pulse n <- tp*fs #(hz) lfm start frequency example fstart <- 2260e6 #(hz) lfm stop frequency example fstop <- 2590e6 #(hz) lfm start frequency ism band fstart <- 2402e6 #(hz) lfm stop frequency ism band fstop <- 2495e6 #(hz) transmti bandwidth bw <- fstop-fstart #instantaneous transmit frequency f <- seq(fstart, fstop, length=n/2) #range resolution rr <- c/(2*bw) max_range <- rr*n/2 ##################################################### # range ##################################################### ############################ # |- input appears inverted ############################ trig <- -1*y[1,] s <- -1*y[2,] #reset y #y = 0 ############################ # |- parse data here triggering off rising edge of sync pulse ############################ # reset counter / threshold count <- 0 thresh <- 0 # assign logical vector meets thresh start <- (trig > thresh) sp <- nrow(start)-n for(ii in 100:sp) { if(start(ii) == 1 && mean(start(ii-11:ii-1)) == 0) { count = count + 1 } }
edit #2: matlab loop
for ii = 100:(size(start,1)-n) if start(ii) == 1 && mean(start(ii-11:ii-1)) == 0 count = count + 1; sif(count,:) = s(ii:ii+n-1); time(count) = ii*1/fs; end end
you can in single line 2 lines, follows:
library(ttr) shiftindx <- c(6:length(start), 1:5) count <- sum(start == 1 & sma(start, n=11)[shiftindx] == 0, na.rm=true)
where sma
ttr
packages
here explanation, piece piece
## give logical vector of t/f ## length equal length of start start == 1 ## part give smiple moving average of every 11 numbers sma(start, n=11) ## need shift these on centered properly. ## `shiftindx` takes first `floor(11/2)` ma's , puts them @ tail. ## (notice these na.) shiftindx <- c(6:length(start), 1:5) sma(start, n=11)[shiftindx] ## .. checking if equal 0 give t/f vector, ## of length equal length of start sma(start, n=11)[shiftindx] == 0 ## combining t/f vectors using `&` gives t/f vector ## of same length, true _both_ of original ## vectors true (start == 1) & (sma(start, n=11)[shiftindx] == 0) ## taking `sum(.)` of logical vector equivalent of counting ## how many true values in vector. ## snce incrementing `count` every time both conditional statements true, ## final value of `count` same sum below sum( (start == 1) & (sma(start, n=11)[shiftindx] == 0), na.rm=true)
and here benchmarks (before edit of adding `shiftindx`) set.seed(7) (n in 10^(6:8)) { cat("n is: ", n, "\n") start <- round(rnorm(n, 0, 10)) print(system.time( count <- sum(start == 1 & sma(start, n=11) == 0, na.rm=true) )) cat("count ", count, "\n", rep("~", 14), "\n\n", sep="") } ## output: n is: 1e+06 user system elapsed 0.059 0.021 0.081 count 485 ~~~~~~~~~~~~~~ n is: 1e+07 user system elapsed 0.578 0.195 0.768 count 4889 ~~~~~~~~~~~~~~ n is: 1e+08 user system elapsed 7.808 5.716 19.392 count 49737 ~~~~~~~~~~~~~~
Comments
Post a Comment