[R] aplpy recursive function on a list
Berend Hasselman
bhh at xs4all.nl
Thu Jan 26 19:33:49 CET 2012
On 26-01-2012, at 19:10, Berend Hasselman wrote:
>
> On 26-01-2012, at 17:58, Brian Diggs wrote:
>
>> On 1/25/2012 10:09 AM, patzoul wrote:
>>> I have 2 series of data a,b and I would like to calculate a new series which
>>> is z[t] = z[t-1]*a[t] + b[t] , z[1] = b[1].
>>> How can I do that without using a loop?
>>
>> ........
>
> I don't think so.
>
> a <- c(2,4,3,5)
> b <- c(1,3,5,7)
>
> z <- rep(0,length(a))
> z[1] <- b[1]
> for( t in 2:length(a) ) { z[t] <- a[t] * z[t-1] + b[t] }
> z
>
> gives
>
> [1] 1 7 26 137
>
> and this agrees with a manual calculation.
>
> You get a vector of length 5 as result. It should be of length 4 with your data.
> If you change the Reduce expression to this
>
> u <- Reduce(function(zm1, coef) {coef[1] * zm1 + coef[2]},
> Map(c, a[-1], b[-1]),
> init = b[1], accumulate = TRUE)
>
> then you get the correct result.
>
>> u
> [1] 1 7 26 137
And the loop especially if byte compiled with cmpfun appears to be quite a bit quicker.
Nrep <- 1000
tfrml.loop <- function(a,b) {
z <- rep(0,length(a))
z[1] <- b[1]
for( t in 2:length(a) ) {
z[t] <- a[t] * z[t-1] + b[t]
}
z
}
tfrml.rdce <- function(a,b) {
u <- Reduce(function(zm1, coef) {coef[1] * zm1 + coef[2]},
Map(c, a[-1], b[-1]),
init = b[1], accumulate = TRUE)
u
}
library(compiler)
tfrml.loop.c <- cmpfun(tfrml.loop)
tfrml.rdce.c <- cmpfun(tfrml.rdce)
z.loop <- tfrml.loop(a,b)
z.rdce <- tfrml.rdce(a,b)
all.equal(z.loop, z.rdce)
library(rbenchmark)
N <- 500
set.seed(1)
a <- runif(N)
b <- runif(N)
benchmark(tfrml.loop(a,b), tfrml.rdce(a,b), tfrml.loop.c(a,b), tfrml.rdce.c(a,b),
replications=Nrep, columns=c("test", "replications", "elapsed"))
test replications elapsed
1 tfrml.loop(a, b) 1000 2.665
3 tfrml.loop.c(a, b) 1000 0.554
2 tfrml.rdce(a, b) 1000 4.082
4 tfrml.rdce.c(a, b) 1000 3.143
Berend
R-2.14.1 (32-bits), Mac OS X 10.6.8.
More information about the R-help
mailing list