2011-10-16 27 views
8

Matematiksel bir işlevi enterpolasyon yapmak istiyorum.İnterpolasyon için tekrarlanan aramalardan kaçının

ben sadece üzere approx[x] çağırabilir şimdi

approx = Interpolation[Table[{F[0.1 n, a], 0.1 n}, {n, -100, 100}]] 

, fonksiyon aynı zamanda a bağlı olan bir fonksiyonun F tersidir aslında, bir parametre a bağlıdır, bu nedenle aşağıdaki gibi benim tahminini oluşturmak Ters fonksiyonu bir noktada değerlendirir.

Onun yerine böyle bir şey yapmak istiyorum: Bir parametre alır bir işlev tanımlayın,

G[x_,a_] = "construct the interpolating function, 
      and return the value of the function at x" 

Sonra fonksiyonunu değerlendirmek için [a, x] G yazın. Aksi takdirde, ilgilendiğim tüm parametreler için enterpolasyonu tekrarlamalıyım ve etrafta çok fazla değişken var. Interpolasyon [] çağrısını bir modülün içine koymaya çalıştım ama sadece G [x, a] dediğim her zaman interpolasyonu yapıyorum! Bundan nasıl kurtulurum?

Okumak için teşekkürler.

cevap

6

bu satırlar boyunca bir şey deneyin:

G[a_]:=G[a]=Interpolation[Table[{F[0.1 n, a], 0.1 n}, {n, -100, 100}]] 

G[0.2] (* particular value of G[a] *) 

G[0.2][0.3] (* the value you want *) 

Yalnızca değerlendirecek G, ilk kezdeğerinin her bir değeri için aradığınızda.

+0

Bu yaklaşım, sağlanan diğerlerine göre en basit yaklaşım gibi görünüyor. Belki de diğer cevaplarda açıklandığı gibi önbelleğe alma üzerinde bu şemaya bir geri çekilme vardır. Ama farkı bilecek kadar uzman değilim. – mark

+3

Diğer cevaplar, çok büyük büyüdüğünde önbellek sembolünde saklanan belleğin nasıl bırakılacağıyla ilgilidir. Bunların önbellekleme fikri, bu cevaptaki ile aynıdır. Eğer kodunuz çok hafızada değilse, o anki seansın hafızasını kaybetmemek gerçekten de önemli değildir, ancak büyük hesaplamalar yaparsanız yararlı olabilir. – faysou

+0

@Faysal Aberkane ... Teşekkürler – mark

12

ilk adım a ile approx parameterize için: Bu tanım ile

approx[a_] := Interpolation[Table[{F[0.1 n,a],0.1 n},{n,-100,100}]] 

, G daha sonra bu şekilde tanımlanabilir: söz gözlenen

G[x_, a_] := approx[a][x] 

Ancak, bu biter Her zaman G çağrılırken enterpolasyon yeniden yapılandırılır.

m: approx[a_] := m = Interpolation[Table[{F[0.1 n,a],0.1 n},{n,-100,100}]] 

Şimdi approx aynı a ile müteakip çağrılarda yeniden kaçınarak, herhangi bir a için interpolasyon fonksiyonu kazandıracak: Bunu önlemek için bir yolu Memoization kullanarak approx yeniden tanımlamaktır. Tabii ki, bu bellek kadar kullanır, böylece a'un çok sayıda farklı değeri varsa, bellek kısa sürebilir. O (bu durumda cache) Başka bir sembol ile kaydedilen değerler ilişkilendirerek approx tarafından kullanılan önbellek lokalize etmek mümkündür:

:

approx[a_] := cache[a] /. 
    _cache :> (cache[a] = Interpolation[Table[{F[0.1` n,a],0.1` n},{n,-100,100}]]) 

approx bu sürümü ile, cache, örneğin Block kullanılarak lokalize edilebilir

Block[{cache} 
, Table[G[x, a], {x, 0, 5}, {a, 0, 1, 0.1}] 
] 

Enterpolasyon işlevleri, a'un her farklı değeri için geçici olarak saklanır, ancak şimdi bu kaydedilen tanımlamalar Block çıktıktan sonra serbest bırakılır.Mathematica'da bellek ile işlevleri hakkında daha fazla bilgi için

, SO soruları görmek:

The best way to construct a function with memory

Dynamic Programming in Mathematica: how to automatically localize and/or clear memoized function's definitions

+0

Cevabınız için teşekkür ederiz olurdu, daha Mathematica öğrenmek gitmemi motive etti! – mark

6

What is in your Mathematica tool bag? numaralı belgede tanımladığım CacheIndex tanımını kullanabilirsiniz. Bu işlevi kullanmanın iyi bir yanı, yeni bir işlev tanımlamak zorunda kalmadan, değerleri veya kod bölümlerini önbelleğe alabilmenizdir (buradaki örnekle aynı hizada olmasına rağmen).

G[x_,a_] := 
    CacheIndex[a, 
     Pause[3]; 
     Interpolation[Table[{F[0.1 n,a],0.1 n},{n,-100,100}]] 
    ][x]; 

duraklatırsam [3], sadece bir kez hesaplanır sonra İnterpolasyon tanımı, her bir a için önbelleğe bir şekilde ortaya koymaktadır ilave edildi.

Ardından

DeleteCachedValues[CacheIndex] (*or*) 
DeleteCachedValues[CacheIndex,1]. 

Bir Blok tanımlanan ayrı sembol kullanma WReach fikri ile uyumlu hale getirmek için benim Önbellek ve CacheIndex işlevlerini adapte kullanarak CacheIndex önbelleğe İnterpolasyon değerlerini silebilir. Burada pratik olmayan bir şey, Hold niteliklerini önbellek olarak kullanılan sembolle tanımlamanız gerektiğidir, ancak fikir hala ilginçtir. İşte

CacheSymbol

SetAttributes[CacheSymbol,HoldAll]; 
CacheSymbol[cacheSymbol_,expr_]:=cacheSymbol[expr]/.(_cacheSymbol:>(cacheSymbol[expr]=expr)); 

Bir Blok tanımlanabilir olacak bir gerçek örnek önbelleğinde aşağıdaki yönergeleri kullanarak bu uygulama, test edebilirsiniz tanımıdır. İşte

ClearAll[cache] SetAttributes[cache,HoldFirst] CacheSymbol[cache,Pause[3];2+2] ?cache CacheSymbol[cache,Pause[3];2+2] 

Bir Blok tanımlanabilir olacak bir gerçek örnek önbelleğinde aşağıdaki yönergeleri kullanarak bu uygulamayı test edebilirsiniz

SetAttributes[CacheIndexSymbol,HoldAll]; 
CacheIndexSymbol[cacheSymbol_,index_,expr_]:=cacheSymbol[index,expr]/.(_cacheSymbol:>(cacheSymbol[index,expr]=expr)); 

CacheSymbolIndex tanımıdır.

ClearAll[cache] 
SetAttributes[cache,HoldRest] 
CacheIndexSymbol[cache,2+2,Pause[3];2+2] 
?cache 
CacheIndexSymbol[cache,2+2,Pause[3];2+2] 

ve benzer WReach örneğine biz

G[x_,a_] := 
    CacheIndexSymbol[cache,a, 
     Print["Caching"]; 
     Interpolation[Table[{F[0.1 n,a],0.1 n},{n,-100,100}]] 
    ][x] 

Block[{cache}, 
    SetAttributes[cache,HoldRest]; 
    Table[G[x, a], {x, 0, 5}, {a, 0, 1, 0.1}] 
]