truncamiento superior round redondear puntos programacion numero grafico graficar funciones entero elegir decimales comando matlab caching

round - redondear al entero superior matlab



La forma más limpia de cachear los resultados de las funciones en Matlab (3)

Tengo una función bastante pesada en Matlab

función [out] = f (in1, in2, in3)

Que se llama con bastante frecuencia con los mismos parámetros. La función es determinista, por lo que para los parámetros de entrada dados su salida siempre será la misma.

¿Cuál sería la forma más sencilla de almacenar los resultados de las entradas computadas en la función de modo que si la función se llamará de nuevo con el mismo resultado, podría responder rápidamente?

Es una variable persistente que mapea (usando contenedores.Mapa o alguna otra clase) entrada establecida en un resultado el camino a seguir?

(Cualquier método que requiera guardar los datos en el disco está fuera de cuestión en mi aplicación).


A continuación hay una idea para una clase CacheableFunction

  • Parece que todas las respuestas a su pregunta principal apuntan en la misma dirección: un Mapa persistente es la forma consensuada de almacenar en caché los resultados, y yo también lo hago.
  • Si las entradas son matrices, deberán pasarse a una cadena o escalar para ser utilizadas como una clave de mapa. Hay muchas formas de agrupar sus 3 matrices de entrada en una clave. Utilicé DataHash en mi solución a continuación.
  • Elegí hacer una clase en lugar de una función como memoize para que la función de hash de entrada se pueda especificar dinámicamente una vez, en lugar de codificarse.
  • Dependiendo de la forma de su salida, también utiliza dzip / dunzip para reducir la huella de las salidas guardadas.
  • Mejora potencial: una manera ingeniosa de decidir qué elementos eliminar del mapa persistente cuando su huella de memoria se acerca a algún límite.

Definición de clase

classdef CacheableFunction < handle properties exeFun hashFun cacheMap nOutputs zipOutput end methods function obj = CacheableFunction(exeFun, hashFun, nOutputs) obj.exeFun = exeFun; obj.hashFun = hashFun; obj.cacheMap = containers.Map; obj.nOutputs = nOutputs; obj.zipOutput = []; end function [result] = evaluate(obj, varargin) thisKey = obj.hashFun(varargin); if isKey(obj.cacheMap, thisKey) if obj.zipOutput result = cellfun(@(x) dunzip(x), obj.cacheMap(thisKey), ''UniformOutput'', false); else result = obj.cacheMap(thisKey); end else [result{1:obj.nOutputs}] = obj.exeFun(varargin); if isempty(obj.zipOutput) obj.zipCheck(result); end if obj.zipOutput obj.cacheMap(thisKey) = cellfun(@(x) dzip(x), result, ''UniformOutput'', false); else obj.cacheMap(thisKey) = result; end end end function [] = zipCheck(obj,C) obj.zipOutput = all(cellfun(@(x) isreal(x) & ~issparse(x) & any(strcmpi(class(x), ... {''double'',''single'',''logical'',''char'',''int8'',''uint8'',... ''int16'',''uint16'',''int32'',''uint32'',''int64'',''uint64''})), C)); end end end

Probando ...

function [] = test_caching_perf() A = CacheableFunction(@(x) long_annoying_function(x{:}), @(x) DataHash(x), 3); B = rand(50, 50); C = rand(50, 50); D = rand(50, 50); tic; myOutput = A.evaluate(B, C, D); toc tic; myOutput2 = A.evaluate(B, C, D); toc cellfun(@(x, y) all(x(:) == y(:)), myOutput, myOutput2) end function [A, B, C] = long_annoying_function(A, B, C) for ii = 1:5000000 A = A+1; B = B+2; C = C+3; end end

Y resultados

>> test_caching_perf Elapsed time is 16.781889 seconds. Elapsed time is 0.011116 seconds. ans = 1 1 1


El mapa persistente es una buena forma de implementar resultados en caché. Ventajas que puedo pensar:

  • No es necesario implementar la función hash para cada tipo de datos.
  • Las matrices de Matlab son de escritura por copia, que pueden ofrecer cierta eficiencia de memoria.
  • Si el uso de la memoria es un problema, se puede controlar cuántos resultados se almacenarán en caché.

Hay una presentación de intercambio de archivos, una clase de mapa multidimensional de David Young, viene con una función memoize () hace exactamente esto. Su implementación usa un mecanismo un poco diferente (variable local referenciada), pero la idea es casi la misma. En comparación con el mapa persistente dentro de cada función, esta función memoize () permite que la función existente sea memorada sin modificaciones. Y como señala Oleg, el uso de DataHash (o equivalente) puede reducir aún más el uso de la memoria.

PD: He usado la clase MapN extensivamente y es bastante confiable. En realidad, he enviado un informe de error y el autor lo solucionó de inmediato.