Hi, I have a question about a special recursive filter problem. What I have: - given variables: x: time series with rather randomly occuring '0' and '1' wait: non negative integer - a working but ineffectiv implementation (see below) How the implementation works (what I want): The filter should drill holes of distance 'wait' between the '1' in x, e.g. x = 1 0 1 1 0 1 0 1 0 1 0 1 1 1 1 wait = 2 desired result: result = 1 0 0 1 0 0 0 1 0 0 0 1 0 0 1 working implementation: #************************************************************************* # basic informations #************************************************************************* # length of input vector lengthX <- length(x) # stop times for the recursive filter indices stopS <- 1:lengthX + wait - 1 # initialize the result and the intermediate result vector # with additional length for recursive filtering result <- y <- numeric(lengthX + wait) #************************************************************************* # filter #************************************************************************* # recursive filter function for(i in 1:lengthX){ # present ('x') and lag ('y') filtering ans <- x[i] + sum(y[i:stopS[i]]) # check for the right filter answer if( ans == 1){ y[wait + i] <- -1 result[wait + i] <- 1 } } #************************************************************************* # post calculation #************************************************************************* # remove the additional length for recursive filtering # from the returning vector result <- result[-(1:wait)] ----------------------------------------------------------------------- Is there anyone how has a better idea? Thank you for your help, Thomas. --
R. Michael Weylandt <michael.weylandt@gmail.com>
2011-Jul-29 15:42 UTC
[R] special recursive filter
I'm not sure I understand what your filter intends to do, but could this not be done more efficiently with logicals and the which? You also might need the cumsum() function and diff() with the optional lag argument if I've misunderstood your filter. Specifically try this: res = c(x,rep(NA,wait)) # make a copy to work on and include the extra NA which we might turn into zeros, but will drop later for (i in 1:wait) {res[which(x == 1) + i] <- 0} res = res[1:length(x)] # drop the extra added length. Michael Weylandt On Fri, Jul 29, 2011 at 11:16 AM, Konrad Schubert <infochat@gmx.net> wrote:> Hi, > I have a question about a special recursive filter problem. > > What I have: > > - given variables: > x: time series with rather randomly occuring '0' and '1' > wait: non negative integer > > - a working but ineffectiv implementation (see below) > > How the implementation works (what I want): > > The filter should drill holes of distance 'wait' between the '1' in x, e.g. > > x = 1 0 1 1 0 1 0 1 0 1 0 1 1 1 1 > wait = 2 > > desired result: > > result = 1 0 0 1 0 0 0 1 0 0 0 1 0 0 1 > > working implementation: > > #************************************************************************* > # basic informations > #************************************************************************* > > # length of input vector > lengthX <- length(x) > > # stop times for the recursive filter indices > stopS <- 1:lengthX + wait - 1 > > # initialize the result and the intermediate result vector > # with additional length for recursive filtering > result <- y <- numeric(lengthX + wait) > > #************************************************************************* > # filter > #************************************************************************* > > # recursive filter function > for(i in 1:lengthX){ > > # present ('x') and lag ('y') filtering > ans <- x[i] + sum(y[i:stopS[i]]) > > # check for the right filter answer > if( ans == 1){ > y[wait + i] <- -1 > result[wait + i] <- 1 > } > } > > #************************************************************************* > # post calculation > #************************************************************************* > > # remove the additional length for recursive filtering > # from the returning vector > result <- result[-(1:wait)] > > ----------------------------------------------------------------------- > > Is there anyone how has a better idea? > Thank you for your help, > Thomas. > -- > > ______________________________________________ > R-help@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide > http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >[[alternative HTML version deleted]]
More than happy to help. I think the term is "sparse" matrix. I haven't totally wrapped my mind around why your version seems to work (and testing it, it does seem to work for non-sparse matrices as well), but still, if it makes sense to you, why bother with adding one to the sum and the if statement? This should do exactly the same, only slightly quicker: positions <- which(x == 1) # so I can skip the zeros in the loop result <- numeric(length(x) + wait) for(m in positions){ result[m + wait] <- (-1)*(sum(result[m:(m+wait-1)])==0) } # This could probably be vectorized as well, but this is pretty fast already result <- -result[-(1:wait)] Michael Weylandt PS -- It's good form to cc the entire list at each step so that it all gets wisked away to the R archives for google-ability. On Mon, Aug 1, 2011 at 8:06 AM, Konrad Schubert <infochat@gmx.net> wrote:> Hi Michael, > > thank you very much for your quick responses! > > Your second answer is right - and much more faster and even simpler (Why I > didn't catch the same way?) then my own one! > > Over the weekend I thought still about improvements. A slightly better one > I would like to present. It is only better for spare vectors (Is it the > right name for vectors with much more '0' then other numeric entries?). > Have a look: > > positions <- which(x == 1) # so I can skip the zeros in the loop > > result <- numeric(length(x) + wait) > > for(m in positions){ > > ans <- sum(1, result[m:(m + wait - 1)]) > > if( ans == 1) > result[m + wait] <- -1 > } > > result <- -result[-(1:wait)] > > In the end I'm happy with your solution! > Thank you for your help! > Thomas > > -------- Original-Nachricht -------- > > Datum: Fri, 29 Jul 2011 12:25:10 -0400 > > Von: "R. Michael Weylandt <michael.weylandt@gmail.com>" < > michael.weylandt@gmail.com> > > An: Konrad Schubert <infochat@gmx.net> > > CC: R-help@r-project.org > > Betreff: Re: [R] special recursive filter > > > Oh darn, I missed the recursive-ness entirely. You condition on the > > filtered > > series, not the signal itself. > > > > In that case, I have a solution which is pretty fast, but not > particularly > > R-esque. > > > > In effect your filter just says, take x but if you see a 1, sit out for > > the > > next wait periods. This seems prone to a repeat or while loop, and I > don't > > think can be much improved since you'll have to run the signal "in real > > time" unless I'm missing a trick > > > > res = numeric(length(x)) > > i=1 > > while (i <= length(x) ) { > > if (x[i] == 1) {res[i] =1; i = i+wait} # this improves speed somewhat > > by > > jumping over those spots you are going to keep = 0 > > i = i + 1 # no need to re-assign the default value of zero > > } > > > > Again, unless there's a trick I'm missing, this seems about optimal since > > it > > runs slightly better than "real-time" through the signal. > > > > Sorry for my initial (wrong) remarks, > > > > Michael Weylandt > > > > On Fri, Jul 29, 2011 at 11:42 AM, R. Michael Weylandt < > > michael.weylandt@gmail.com> <michael.weylandt@gmail.com> wrote: > > > > > I'm not sure I understand what your filter intends to do, but could > this > > > not be done more efficiently with logicals and the which? You also > might > > > need the cumsum() function and diff() with the optional lag argument > if > > > I've misunderstood your filter. > > > > > > Specifically try this: > > > > > > res = c(x,rep(NA,wait)) # make a copy to work on and include the extra > > NA > > > which we might turn into zeros, but will drop later > > > for (i in 1:wait) {res[which(x == 1) + i] <- 0} > > > res = res[1:length(x)] # drop the extra added length. > > > > > > Michael Weylandt > > > > > > > > > > > > On Fri, Jul 29, 2011 at 11:16 AM, Konrad Schubert > > <infochat@gmx.net>wrote: > > > > > >> Hi, > > >> I have a question about a special recursive filter problem. > > >> > > >> What I have: > > >> > > >> - given variables: > > >> x: time series with rather randomly occuring '0' and '1' > > >> wait: non negative integer > > >> > > >> - a working but ineffectiv implementation (see below) > > >> > > >> How the implementation works (what I want): > > >> > > >> The filter should drill holes of distance 'wait' between the '1' in x, > > >> e.g. > > >> > > >> x = 1 0 1 1 0 1 0 1 0 1 0 1 1 1 1 > > >> wait = 2 > > >> > > >> desired result: > > >> > > >> result = 1 0 0 1 0 0 0 1 0 0 0 1 0 0 1 > > >> > > >> working implementation: > > >> > > >> > > >> > > > #************************************************************************* > > >> # basic informations > > >> > > >> > > > #************************************************************************* > > >> > > >> # length of input vector > > >> lengthX <- length(x) > > >> > > >> # stop times for the recursive filter indices > > >> stopS <- 1:lengthX + wait - 1 > > >> > > >> # initialize the result and the intermediate result vector > > >> # with additional length for recursive filtering > > >> result <- y <- numeric(lengthX + wait) > > >> > > >> > > >> > > > #************************************************************************* > > >> # filter > > >> > > >> > > > #************************************************************************* > > >> > > >> # recursive filter function > > >> for(i in 1:lengthX){ > > >> > > >> # present ('x') and lag ('y') filtering > > >> ans <- x[i] + sum(y[i:stopS[i]]) > > >> > > >> # check for the right filter answer > > >> if( ans == 1){ > > >> y[wait + i] <- -1 > > >> result[wait + i] <- 1 > > >> } > > >> } > > >> > > >> > > >> > > > #************************************************************************* > > >> # post calculation > > >> > > >> > > > #************************************************************************* > > >> > > >> # remove the additional length for recursive filtering > > >> # from the returning vector > > >> result <- result[-(1:wait)] > > >> > > >> > ----------------------------------------------------------------------- > > >> > > >> Is there anyone how has a better idea? > > >> Thank you for your help, > > >> Thomas. > > >> -- > > >> > > >> ______________________________________________ > > >> R-help@r-project.org mailing list > > >> https://stat.ethz.ch/mailman/listinfo/r-help > > >> PLEASE do read the posting guide > > >> http://www.R-project.org/posting-guide.html > > >> and provide commented, minimal, self-contained, reproducible code. > > >> > > > > > > > > -- > NEU: FreePhone - 0ct/min Handyspartarif mit Geld-zurück-Garantie! > Jetzt informieren: http://www.gmx.net/de/go/freephone >[[alternative HTML version deleted]]