2016-03-25 19 views
4

Bir objektif fonksiyona göre bir değişkenler dizisini optimize etmem gerekiyor. Fonksiyonun analitik eğrisine sahibim ve optimizasyon rutininde kullanmak istiyorum. Amaç ve gradyan bazı ortak hesaplamalara sahiptir ve fonksiyonları mümkün olan en verimli şekilde tanımlamak isterim. Aşağıdaki örnek sorunu göstermektedir. Sırasıyla, hedef, degrade ve ortak hesaplamalar için f_obj, f_grad ve f_common fonksiyonlarını 0 olsun. Optimizasyon, x vektörünün üzerindedir. Aşağıdaki kod, y^3 - 3*y^2 + 6*y + 1 polinomunun bir kökü bulur, burada y, c(x[1], x[2])'un bir işlevidir. f_common işlevinin hem f_obj hem de f_grad'da çağrıldığını unutmayın. Benim asıl sorunumda, genel hesaplama çok daha uzun, bu yüzden f_obj ve f_grad tanımlamak için bir yol arıyorum, böylece f_common çağrılarının sayısı en aza indirilir.R - Nesnel ve Gradyan Verimlilik Hesaplamasında Optimizasyon

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

GÜNCELLEME

Ben paket nloptr girişine tesis amaç fonksiyonu ve liste halinde onun bir eğime sahip olduğunu bulmak. Diğer optimize edicileri (optim, optimx, nlminb, vb.) Benzer şekilde tanımlamanın bir yolu var mı?

Teşekkürler.

+0

Ne istiyorsunuz?>? Kod çalışır. Eğer f_common çağrısını en aza indirgemek istiyorsanız, onu çağırmamalısınız ve bunun yerine işlev içerisinde sabit kod y. –

+0

Ortak hesapların her iki işlevde kodlanması, f_common çağrısının eşdeğeri olacaktır (yürütme süresi açısından). Yedekli hesaplamaları ortadan kaldırmak için bir yol arıyorum. Benim kodumla, optimizasyon rutini 'x' bir noktasında 'f_obj' hesaplamak ve bu noktada gradyanını bulmaksa, iki kez 'f_common' çağırması gerekecek, ancak sadece bir kez hesaplamalıyız. – user3294195

+3

Belki de 'f_common' sonuçlarını önbelleğe almak için [memoise] (https://cran.r-project.org/web/packages/memoise/index.html) gibi bir paket kullanabilirsiniz. – sgibb

cevap

1

Mağaza genel değişken ortak fonksiyonunun değeri aşağıdaki gibi sonraki işlev çağrısı için kullanılabilir hale getirmek için:

f_common <- function(x) x[1]^3*x[2]^3 - x[2] 

f_obj <- function(x) { 
    y <<- f_common(x) # <<- operator stores in parent scope 
    return ((y^3 - 3*y^2 + 6*y + 1)^2) 
} 

f_grad <- function(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)) 
} 

y<<-0 

optim(par = c(100,100), fn = f_obj, gr = f_grad, method = "BFGS") 

birkaç not Bu çözüm hakkında ekleyerek değer. 1) İlk olarak, < < - işlecini kullanarak, genel bir değişkene değil, işlevin ana kapsamından (yani, çağrıldığına göre) birini atamayı kesinlikle söylemez. Genellikle bu genellikle küresel kapsamıdır. Bu iyi çalışıyor ve daha iyi bir yaklaşım. Atama() işlevini kullanarak genel kapsamı açıkça kullanmak da mümkündür, ancak burada buna gerek yoktur. 2) Aynı değişken adı başka bir yerde kullanılıyorsa, beklenmedik yan etkilere sahip olabileceğinden, genel değişkenleri kullanmanın normal olarak tavsiye edilmediğine de dikkat edilmelidir. Herhangi bir olası yan etkiyi önlemek için, global.f_common gibi başka bir yerde asla kullanılmayacak ve yan etki tehlikesi olmayan değişken bir isim kullanmanızı öneririm. Orijinal sorudaki isimlendirme ile tutarlı olmak için örnekte y adını kullandım. İstenen davranışı başka bir şekilde başarmak zordur çünkü bu, işlevinin dışında değişken bir kapsam vermenin haklı görülebileceği nadir durumlardan biridir. Dikkatli kullandığınızdan ve yukarıda önerildiği gibi benzersiz bir ad (global.f_common gibi) kullandığınızdan emin olun.

+1

x ile degrade işlevi çağrısının her zaman aynı x ile objektif işlev çağrısı tarafından izlendiğinden emin misiniz? Öyleyse, eğer grad (x2), obj (x1) hesaplandıktan hemen sonra hesaplanıyorsa, o zaman bir soruna yol açacaktır. "Optim" işlevi içindeki tüm prosedürleri anlamadıkça riskli görünüyor. –

+0

Bunun üzerine birkaç kontrol yaptım: obj (yazdırma) (y) kullanarak obj ve grad işlevlerini kullanarak ve Optim'de izleme seçeneğini kullanarak. Sonuç, bu yaklaşımın OP'de olduğu gibi iki kez hesaplanmasıyla aynı optimizasyon yolunu takip etmesidir. Ayrıca, sadece optim'in objektif işlevi zaten hesaplamış olduğu konum haricinde degradeyi hesaplamasının önemli olmadığını fark etmek önemlidir. – dww