2010-12-14 2 views
4

R есть склад функция Reduce. есть ли соответствующая функция разворота? скажем, учитывая начальное значение и рекурсивно применять функцию для получения массива? Цикл for будет выполнять эту работу, просто задаваясь вопросом, есть ли для этого больше R-подобных способов. спасибо,функция разворота в R?

Пример, приведенный ниже код участка аттрактор Лоренца в 8 линий (мнемосхема F# Lorenz Attractor in 35 lines. Но цикл выглядит некрасиво. Мы можем сделать лучше?

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') 

ответ

2

Как насчет

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') 

или (с учетом ответа от комментариев)

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 как вы рассчитываете линии? Если вы используете достаточно запятой вы можете сделать все это на одной линии :-) Я считаю 11 заявлений в код

редактировать: пропал без вести некоторые скобки в x обновления

+1

благодарит за 'replicate' и '<< -' tip. – learnbasicR

+4

Примечание. Например, на основании ответа Бена: 'do.call (rbind, Reduce (функция (X, i) с (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 - Я не получаю тот же ответ (или сюжет) с вашим кодом как ОП ?! – Tommy