目的関数に対して変数のセットを最適化する必要があります。関数の解析勾配があり、最適化ルーチンでそれを使用したいと思います。目的と勾配にはいくつかの一般的な計算があり、可能な限り最も効率的な方法で関数を定義したいと思います。以下の例は、この問題を示しています。Rでの最適化 - 目的関数と勾配の効率的計算
f_obj
,f_grad
およびf_common
をそれぞれ目的関数、勾配関数および共通計算の関数とする。最適化はベクトルx
を超えています。以下のコードは、多項式y^3 - 3*y^2 + 6*y + 1
の根を求めます。y
は、c(x[1], x[2])
の関数です。関数f_common
はf_obj
とf_grad
の両方で呼び出されます。私の実際の問題では、一般的な計算ははるかに長くなるので、f_common
への呼び出し回数を最小にするように、f_obj
とf_grad
を定義する方法を探しています。
f_common <- function(x) x[1]^3*x[2]^3 - x[2]
f_obj <- function(x) {
y <- f_common(x)
return ((y^3 - 3*y^2 + 6*y + 1)^2)
}
f_grad <- function(x) {
y <- f_common(x)
return (2 * (y^3 - 3*y^2 + 6*y + 1) * (3*y^2 - 6*y + 6)* c(3*x[1]^2*x[2]^3, 3*x[1]^3*x[2]^2 - 1))
}
optim(par = c(100,100), fn = f_obj, gr = f_grad, method = "BFGS")
UPDATE
私はパッケージnloptr
を入力し、目的関数とリストとしてその勾配を、施設を提供していますことを見つけます。同様の方法で他のオプティマイザ(optim
、optimx
、など)を定義する方法はありますか?
ありがとうございました。
あなたは何をしたいですか?コードは機能します。 f_commonの呼び出しを最小限に抑えたい場合は、関数内でyを呼び出す代わりに、ハードコードする必要があります。 –
両方の関数で共通の計算をハードコーディングするのは、f_common(実行時間の点で)を呼び出すのと同じです。私は余分な計算を排除する方法を探しています。私のコードでは、最適化ルーチンが点 'x'で' f_obj'を計算し、その点でその勾配を見つけるのであれば、 'f_common'を二度呼び出す必要がありますが、' y'を一度計算するだけです。 – user3294195
[memoise](https://cran.r-project.org/web/packages/memoise/index.html)のようなパッケージを使って、 'f_common'の結果をキャッシュすることができます。 – sgibb