2012-05-01 18 views
2

私はベクトルaを持っていて、ループを使わずに各要素に再帰的にbを掛けたいと思っています。ベクトル要素の再帰的操作

a <- rep(0, 10) 
a[1] <- 1 
b <- 2 

# with a loop 
for (i in 2:length(a)) a[i] <- a[i-1] * b 

ループを使用せずにこれに対処する方法についてのヒントに感謝します。

+1

一般に、再帰をベクトル化することは困難です。アイデアについてはこちらを参照してください:http://stackoverflow.com/questions/7153586/can-i-vectorize-a-calculation-which-depends-on-previous-elementsループを避けたい理由を説明できる場合は役立ちます(速度?)、そしてこれがあなたが解決したい実際の問題である場合(問題が再帰を完全に避けるために再考できるように) –

+0

コメントとリンクをありがとう。スピードは本当に問題ではありません。好奇心の問題です。私はしばらくそれについて考えており、それをベクトル化することができないのかどうか疑問に思っていました。 – johannes

答えて

5

一般に、明示的なループなしでこれを行うことはできません。非常に単純に

a <- rep(2, 10) 
a[1] <- 1 
cumprod(a) 
# [1] 1 2 4 8 16 32 64 128 256 512 
+0

'cumprod()'は '.Primitive()'なので、はるかに高速になることに気付くでしょう...私のテストでは、ネイティブ 'forループ'より約4倍高速ですが、コンパイルすれば1.2xどちらも、 'compiler'の' cmpfun() 'で機能します。 +1 – Chase

3

指数関数^がベクトル化されているので、::この特定のケースでは、暗黙のcumprodが提供するループを使用することができますあなたも

を書きたいかもしれません

2^(0:9) 
# [1] 1 2 4 8 16 32 64 128 256 512 

2^seq(from=0, to=9) 

長いベクトルの場合、@ JoshuaUlrichの方法ははるかに高速ですが、確かに非常にコンパクトです。あなたは、スピードについて特に心配していないとも述べました。

y[i] = x[i] + f[1]*y[i-1] + ... + f[p]*y[i-p] 

あなたがfilter機能を使用することができます。フォームの一般的な再帰的なシリーズで

4

。あなたの場合、x[i] = 0,f[1] = 2およびf[i] = 0i > 1です。あなたはそれを使用する方法を学習した後

filter(rep(0,10), 2, method="recursive", init=1/2) 
# Time Series: 
# Start = 1 
# End = 10 
# Frequency = 1 
# [1] 1 2 4 8 16 32 64 128 256 512 

、常に初めて明らかにされていない、filterは非常に強力かつ効率的である:これはに変換されます。しかし、おそらくあなたの幾何学的な事例には残念です。

+0

一般的なケースでフィルタを一般化するにはどうすればよいですか? –

関連する問題