Reputation: 289
I have a model of device which have internal state between calls.
Previously I passed that state in function call and returned a new state when exited from function.
Then, I found out about persistent variables which was exactly what I need. But problem is when I need to debug model or design between multiple calls it's hard to reproduce the exact call that I need.
For example, I have function foo:
function [y] = foo(x)
persistent k;
if isempty(k)
k = 0;
end
y = k*x;
k = k+1; %% or even k = rand
end
I have multiple runs:
x = 1:5;
for i = 1:5
y = foo(x(i))
end
and have an error in 4'th call. Currently I need to run first three calls to get function state that actual for 4'th call (and if k was equal rand, I will not be able reach that state at all). I tried to save workspace between calls to have an option to load all states but that doesn't work:
for i = 1:3
y = foo(x(i))
end
save foo3.mat
for i = 4:5
y = foo(x(i))
end
clear all
load foo3.mat
foo(3)
ans =
0
So how can I save that function state? Actually, I can save that variable while function is run by putting save statement in code of function but for me that's seems not right. I think that statement should be at the top-script.
Upvotes: 2
Views: 192
Reputation: 289
I suppose the most appropriate solution to my question is replace persistent variable by global one. In that case I have minimum changes to original code:
function [y] = foo(x)
global k;
if isempty(k)
k = 0;
end
y = k*x;
k = k+1; %% or even k = rand
end
And debugging like:
x = 1:5;
for i = 1:3
y = foo(x(i))
end
global k;
save("foo3.mat","k")
clear all
load foo3.mat
foo(4)
The best solution I found is to create class-based model and move variables that stores state into class property. I can save class-object like any other variable so I can save any intermediate state of model:
classdef foo < handle
properties(Access = private)
k;
end
methods
function self = foo()
self.k = 0;
end
function [y] = bar(self, x)
y = self.k*x;
self.k = self.k+1; %% or even k = rand
end
end
end
And debug like:
f = foo();
x = 1:5;
for i = 1:3
y = f.bar(x(i))
end
save bar3.mat
for i = 4:5
y = f.bar(x(i))
end
clear f
load bar3.mat
f.bar(4)
In that case I don't need to pass and return states and I can load any inermediate state.
Upvotes: 1
Reputation: 5672
A couple of options:
clear
Dont use 'clear all'. You rarely if ever need to do clear all
, a simple clear
is usually sufficient.
mlock Put mlock in your function, note this has other implications which you should understand by looking at the documentation. Primarily you have to unlock (munlock) it to edit the function file.
Note this will keep your persistent variable for the matlab session only.
function [y] = foo(x)
persistent k;
mlock;
if isempty(k)
k = 0;
end
y = k*x;
k = k+1; %% or even k = rand
end
Upvotes: 0