Make subclasses inheret a method to look for past work
3 views (last 30 days)
Show older comments
Jacob Lynch August
on 22 Jan 2018
Commented: Sean de Wolski
on 23 Jan 2018
Preface: I am a mechanical engineer with effectively zero background in software engineering. I can read most C/++/#, Java, and Python, but not make use of those languages. My work involves describing mechanical systems in mathematical models. I've been writing classdefs in MATLAB for a while now, but very recently have used subclasses of handles to better manage memory. I'm very fuzzy on events, listeners, and notifications beyond the examples provided. I have simulations that demand large amounts of data and computational time. The global parameter space being simulated often has overlaps within the process, and I don't want to repeat old calculations if it doesn't affect that local procedure.
Toward the goal of zero-recalculations, each function identifies outputs by an SHA-1 digest of its m-file and input arguments. I load the previous output arguments, or calculate the results then save it. This way, I avoid lengthy recalculations if the change in the parameter space does not affect that local procedure. Here are two m-files as examples. I arbitrarily added pauses to simulate the actual procedures, and demonstrate the speed increase when loading old results.
function demoSummonFunctionResults()
x = randi([0,255],1,randi([200,400]));
[r,p] = demoSummonFunctionResultsMethod(x, 25 );
% ignore this stage
tic
[r,p] = demoSummonFunctionResultsMethod(x, 26 );
toc
tic
[r,p] = demoSummonFunctionResultsMethod(x, 26 );
toc
end
function [OUT1,OUT2] = demoSummonFunctionResultsMethod( IN1, IN2 )
% do validations here
% do confirmity conversions here
IN1 = double( IN1(:) );
IN2 = double( IN2 );
% get results
ID = demoSummonFunctionResultsMethodGetId();
if isfile(ID)
load( ID, 'OUT1', 'OUT2' );
return;
end
% calc reults
OUT2 = zeros( size(IN1) );
OUT2(1) = 1;
for k = 2:numel(OUT2)
OUT2(k) = mod( 256*OUT2(k-1), IN2 );
pause( 0.1/OUT2(k) );
end
OUT1 = mod( sum( IN1.*OUT2 ), IN2 );
save( ID, 'OUT1', 'OUT2' );
function ID = demoSummonFunctionResultsMethodGetId()
% begin ID manager
ID_MGR = ...
javaMethod( ...
'getInstance', ...
'java.security.MessageDigest', ...
'SHA-1' );
M = dir( [mfilename('fullpath') '.m'] );
MID = fopen( fullfile( M.folder, M.name ), 'r' );
CID = onCleanup( @()fclose(MID) );
% ID output
update( ID_MGR, fread(MID,inf) );
update( ID_MGR, getByteStreamFromArray(IN1) );
update( ID_MGR, getByteStreamFromArray(IN2) );
ID_BYTES = digest( ID_MGR );
ID_ULONG = typecast( ID_BYTES, 'uint32' );
ID_HEX = dec2hex( ID_ULONG, 8 );
ID_STRING = string(ID_HEX).join('_').pad(45,'left','x')+'.mat';
ID = ID_STRING.char;
end
end
I'd like to generalize this digest-lookup-calc routine, and I suspect it is easiest with objects. Instead of copying and pasting a lookup routine at the beginning of every function, I'd like an object class that does it on all methods, and all subclasses inherit this lookup method. Is this possible in MATLAB?
0 Comments
Accepted Answer
Matt J
on 22 Jan 2018
Edited: Matt J
on 22 Jan 2018
I haven't perused your code at too much length, but I have the vague impression that you are re-inventing MEMOIZE.
If you really think you need to manage multiple memoized functions through a class, then one approach might be to create a container class which holds an array of memoizedFcn objects as a class property. Also, you can overload the SUBSREF method for this container class to invoke the memoizedFcn objects that it holds.
2 Comments
Sean de Wolski
on 23 Jan 2018
You could use a listener to clear the memoization cache on .NET file changed events. This would be better than appending numbers to a function name.
More Answers (0)
See Also
Categories
Find more on Construct and Work with Object Arrays in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!