2010-12-14 61 views
4

R a la fonction de pliage Reduce. Y a-t-il une fonction de dépliage correspondante? dire, donné une valeur de départ et appliquer une fonction récursivement pour obtenir un tableau? La boucle for fera l'affaire, se demandant simplement s'il y a plus de R pour ça. merci,fonction de dépliage dans R?

Un exemple, le code ci-dessous parcelle lorenz attracteur en 8 lignes (mimiques F# Lorenz Attractor in 35 lines. Mais la boucle est moche. Peut-on faire mieux?

s <- 10; b <- 8/3; p <- 28 
dt <- 0.003; n<-2000 
x <- matrix(0,n,3); x[1,] <- c(10,0,20) 
for (i in 2:n){ 
    x[i,] <- x[i-1,] + c(s * (x[i-1,2] - x[i-1,1]),x[i-1,1] * (p - x[i-1,3]) - x[i-1,2],x[i-1,1] * x[i-1,2] - b * x[i-1,3]) * dt 
} 
library(rgl) 
plot3d(x,type= 'l',col = 'red') 

Répondre

2

Que diriez-vous

n<-2000 
params <- list(s=10,b=8/3,p=28,dt=0.003) 
X0 <- X <- c(x=10,y=0,z=20) 


itfun <- function(X) { 
    with(c(as.list(X),params), 
     X + c(s*(y-x),x*(p-z)-y,x*y-b*z)*dt) 
} 
Xmat <- rbind(X0,t(replicate(n,X <<- itfun(X)))) 

library(rgl) 
plot3d(Xmat,type= 'l',col = 'red') 

ou (intégrant la réponse des commentaires)

do.call(rbind, 
Reduce(function(X, i) { 
    with(c(params, as.list(X)), 
     X + c(s*(y-x),x*(p-z)-y,x*y-b*z)*dt) 
    }, 
    seq(n), X, accumulate=TRUE)[-1]) 

PS comment comptez-vous les lignes? Si vous utilisez assez des points-virgules, vous pouvez faire tout cela sur une seule ligne :-) Je compte 11 déclarations dans votre code

modifier: il manquait quelques parenthèses dans la mise à jour x

+1

merci pour le 'replicate' et '' - 'tip. – learnbasicR

+4

Notez également l'argument 'accumulate' de' Reduce'. Par exemple, en se basant sur la réponse de Ben: 'do.call (rbind, Reduce (fonction (X, i) avec (c (params, as.list (X)), X + c (s * yx, x * (pz) -y, x * yb * z) * dt), 1: n, X, accum = T) [- 1]) ' – Charles

+0

@Ben Bolker - Je ne reçois pas la même réponse (ou intrigue) avec votre code comme l'OP ?! – Tommy