2011-10-16 9 views
8

Quiero interpolar una función en mathematica.Evite las llamadas repetidas a la Interpolación

La función depende de un parámetro a, de hecho, es la inversa de una función F que también depende de a, así que construir mi aproximación de la siguiente manera,

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

ahora puedo llamar simplemente approx[x] a evaluar la función inversa en un punto.

lugar me gustaría hacer algo como esto: Definir una función que toma un parámetro,

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

luego escribir G [x, a] para evaluar la función. De lo contrario, tendría que repetir la interpolación de todos los parámetros que me interesan y tener muchas variables por ahí. He intentado poner la llamada Interpolación [] dentro de un módulo pero eso solo construye la interpolación cada vez que llamo G [x, a]! ¿Cómo evitaría esto?

Gracias por leer.

Respuesta

6

probar algo a lo largo de estas líneas:

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

Sólo se evaluará G la primera vez que lo llame para cada valor particular de a.

+0

Este enfoque parece ser el enfoque más simple sobre los otros proporcionados. Tal vez hay un inconveniente en este esquema sobre el almacenamiento en caché explícito como se describe en las otras respuestas. Pero no soy lo suficientemente experto como para saber la diferencia. – mark

+3

Las otras respuestas tratan sobre cómo liberar memoria almacenada en el símbolo de caché cuando crece demasiado. La idea de almacenamiento en caché de estos es la misma que en esta respuesta. Si tu código no consume mucha memoria, está bien que no te importe liberar la memoria de la sesión actual, pero puede ser útil si haces grandes cálculos. – faysou

+0

@Faysal Aberkane ... Gracias – mark

12

El primer paso consiste en parametrizar approx con a:

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

Con esta definición, G continuación, se puede definir así:

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

Pero, como se observa en la cuestión, esto termina reconstruyendo la interpolación cada vez que se llama G. Una forma de evitar esto es redefinir approx usando memoization:

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

Ahora, approx salvará la función de interpolación para cualquier dado a, evitando la reconstrucción en las llamadas posteriores con el mismo a. Por supuesto, esto consume memoria así que si hay una gran cantidad de valores distintos de a, la memoria podría escasear. Es posible localizar la caché utilizada por approx mediante la asociación de los valores guardados con otro símbolo (cache en este caso):

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

Con esta versión de approx, cache puede localizar utilizando Block, por ejemplo:

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

Las funciones de interpolación aún se almacenan temporalmente para cada valor distinto de a, pero ahora esas definiciones guardadas se liberan después de que el Block sale.

Para obtener más información acerca de las funciones de la memoria en Mathematica, vea las preguntas SO:

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

Gracias por su respuesta, que me ha motivado a ir a aprender más Mathematica! – mark

6

Podría usar la definición de CacheIndex Publicada en What is in your Mathematica tool bag?. Una cosa buena acerca del uso de esta función es que puede almacenar valores en caché o porciones de código sin tener que definir una nueva función (aunque lo hacemos aquí para estar en línea con el ejemplo).

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

que añade Pausa [3] sólo para que quede claro que la definición de interpolación se almacena en caché para cada una vez que se ha calculado una vez.

entonces se podría eliminar los valores de interpolación en caché en CacheIndex usando

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

adapté mis funciones de caché y CacheIndex para hacerlos compatibles con la idea de WReach de utilizar un símbolo definido por separado en un bloque. Una cosa que no es práctica aquí es que tiene que definir los atributos de retención para el símbolo utilizado como caché, pero la idea sigue siendo interesante.

Aquí es la definición de CacheSymbol

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

Puede probar esta aplicación utilizando las siguientes instrucciones, en un ejemplo real de caché se definiría en un bloque.

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

Aquí es la definición de CacheSymbolIndex

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

Puede probar esta aplicación utilizando las siguientes instrucciones, en un ejemplo real de caché se definiría en un bloque.

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

y de manera similar al ejemplo de WReach tendríamos

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}] 
] 
Cuestiones relacionadas