1

次の関数 ( f) をベクトル化することはできますか?

を変更xして関数の出力値を最大化したいベクトルがあります。fp

しかし、とにかくベクトル化されていないため、関数は非常に遅く、そうする良い方法があるかどうか疑問に思っていました. アイデアは、将来的にこれを並列化し、潜在的data.tableにそれを高速化することです

私の実際のデータはかなり大きいので、模擬例を提供しています....

# My mock data 
x <- data.frame(x=rep(c(rep(c(0.2,-0.2),4),0.2,0.2,-0.2,0.2),20))

# The function to optimise for
f <- function(p,x){
    # Generate columns before filling
    x$multiplier <- NA
    x$cumulative <- NA

    for(i in 1:nrow(x)){
        # Going through each row systematically
        if(i==1){
            # If first row do a slightly different set of commands
            x[i,'multiplier'] <- 1 * p
            x[i,'cumulative'] <- (x[i,'multiplier'] * x[i,'x']) + 1
        } else {
            # For the rest of the rows carry out these commands
            x[i,'multiplier'] <- x[i-1,'cumulative'] * p
            x[i,'cumulative'] <- (x[i,'multiplier'] * x[i,'x']) + x[i-1,'cumulative']
        }
    }

# output the final row's output for the cumulative column
as.numeric(x[nrow(x),'cumulative'])
}

# Checking the function works by putting in a test value of p = 0.5
f(0.5,x)

# Now optimise the function between the interval of p between 0 and 1
optim.p <- optimise(f=f, interval=c(0,1),x, maximum=TRUE)

# Viewing the output of optim.p
optim.p
4

1 に答える 1

10

(編集 - 私が書いた投稿の最初の部分を忘れていたので、今入れます)。

関数fが実際に何をするかを調べることで、問題を単純化できます。私は怠け者なのでx[i, 'multiplier']、m ix[i, 'cumulative']y ix[i, 'x']x iと書きます。

の式を見てみましょうf。最初にケースを見てみましょうi > 1:

m i = y i-1 * p
y i = m i * x i + y i-1

上記の m_i を置き換えます。

y i = (y i-1 * p) * x i + y i-1 // 因数分解しましょう..
y i = y i-1 * (p * x i + 1)

これにより、列を計算する必要がなくなりmultiplerます。

あなたのi == 1ケースをもう少し詳しく見てみると、y 0を 1 にすると、すべての i = 1, ..., に対して次のようになることがわかりnrow(x)ます。

y i = y i-1 (px i + 1) ---------- (1)

関数を見ると、f計算したいのは y nです。

y n = y n-1 (px n + 1)

上記の y n-1の式を (1) を使って代入するとどうなるでしょうか?

y n = y n-2 (px n-1 + 1)(px n + 1)

ここで、上記の y n-2の式 を代入します。

y n = y n-3 (px n-2 + 1)(px n-1 + 1)(px n + 1)

パターンがわかりますよね?y 1まですべてを代入します。

y n = y 0 (px 1 + 1)(px 2 + 1)...(px n-1 + 1)(px n + 1)

しかし、覚えておいてください、y 0はちょうど 1 です。したがって、 の値を計算するにはf(x, p)、次のようにします。

f(x, p) = (px 1 + 1)(px 2 + 1)...(px n-1 + 1)(px n + 1)

はどこnですかnrow(x)。つまり、p * x[i, 'x'] + 1それぞれiを計算し、それらをすべて乗算します。


R で数値のベクトルを乗算するには、 を使用しますprod。したがって、x単なるベクトルの場合:

f_version2 <- function(p, x) {                                              
    return(prod(p * x + 1))                                                 
}                                                                           

いくつかのことでテストしてみましょう。

x <- rep(c(rep(c(0.2,-0.2),4),0.2,0.2,-0.2,0.2),20)                         

> f(0.5, x)                                                                 
[1] 16.56635                                                                
> f_version2(0.5, x)                                                        
[1] 16.56635                                                                

要約すると、問題の数学を分析するだけで、または数値的な実装に反対するだけで、スピードアップを達成できる場合があります。

于 2012-11-05T05:33:03.077 に答える