문제

In Python we have lru_cache as a function wrapper. Add it to your function and the function will only be evaluated once per different input argument.

Example (from Python docs):

@lru_cache(maxsize=None)
def fib(n):
    if n < 2:
        return n
    return fib(n-1) + fib(n-2)

>>> [fib(n) for n in range(16)]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]

>>> fib.cache_info()
CacheInfo(hits=28, misses=16, maxsize=None, currsize=16)

I wonder whether a similar thing exists in Matlab? At the moment I am using cache files, like so:

function result = fib(n):
% FIB example like the Python example. Don't implement it like that!
cachefile = ['fib_', n, '.mat'];
try
    load(cachefile);
catch e
    if n < 2
        result = n;
    else
        result = fib(n-1) + fib(n-2);
    end
    save(cachefile, 'result');
end
end

The problem I have with doing it this way, is that if I change my function, I need to delete the cachefile.

Is there a way to do this with Matlab realising when I changed the function and the cache has become invalidated?

도움이 되었습니까?

해결책 2

I've created something like this for my own personal use: a CACHE class. (I haven't documented the code yet though.) It appears to be more flexible than Python's lru_cache (I wasn't aware of that, thanks) in that it has several methods for adjusting exactly what gets cached (to save memory) and how the comparisons are made. It could still use some refinement (@Daniel's suggestion to use the containers.Map class is a good one – though it would limit compatibility with old Matlab versions). The code is on GitHub so you're welcome to fork and improve it.

Here is a basic example of how it can be used:

function Output1 = CacheDemo(Input1,Input2)

persistent DEMO_CACHE

if isempty(DEMO_CACHE)
    % Initialize cache object on first run
    CACHE_SIZE = 10; % Number of input/output patterns to cache
    DEMO_CACHE = CACHE(CACHE_SIZE,Input1,Input2);
    CACHE_IDX = 1;
else
    % Check if input pattern corresponds something stored in cache
    % If not, return next available CACHE_IDX
    CACHE_IDX = DEMO_CACHE.IN([],Input1,Input2);
    if ~isempty(CACHE_IDX) && DEMO_CACHE.OUT(CACHE_IDX) > 0
        [~,Output1] = DEMO_CACHE.OUT(CACHE_IDX);
        return;
    end
end

% Perform computation
Output1 = rand(Input1,Input2);

% Save output to cache CACHE_IDX
DEMO_CACHE.OUT(CACHE_IDX,Output1);

I created this class to cache the results from time-consuming stochastic simulations and have since used it to good effect in a few other places. If there is interest, I might be willing to spend some time documenting the code sooner as opposed to later. It would be nice if there was a way to limit memory use as well (a big consideration in my own applications), but getting the size of arbitrary Matlab datatypes is not trivial. I like your idea of caching to a file, which might be a good idea for larger data. Also, it might be nice to create a "lite" version that does what Python's lru_cache does.

다른 팁

Since matlab 2017 this is available: https://nl.mathworks.com/help/matlab/ref/memoizedfunction.html

a = memoized(@sin)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top