Why Does "clear all" Impact Prior Commands in a Script?

1 view (last 30 days)
Here is the example code. If I comment the "clear all" line in Section 2 the ouput of fplot() in Section 1 comes out fine with no warnings. It's almost like the execution does all the computations first, then goes back to the beginning to generate the plots, which for some reason it can't do correctly in Section 1. I've seen this in live scripts and and m-scripts. Is this expected behavior? If so, it's a bit disconcerting that outputs from commands in Section 1 are influenced by executon of commands in Section 2.
FWIW, I was using "clear all" in Section 2 to make sure that I cleared out all of the symbolic math assumptions from Section 1. But I think I've now found a better (correct?) way to do that, so this issue isn't holding me up at present.
% Section 1
clear all %#ok
syms t real
s(t) = piecewise(t<-1,0, t>2,0, exp(-abs(t)));
figure;
fplot(s(t),[-3 3],'MeshDensity',50)
Warning: Error updating FunctionLine.

The following error was reported evaluating the function in FunctionLine update: Unable to convert expression containing remaining symbolic function calls into double array. Argument must be expression that evaluates to number.
% Section 2
clear all %#ok
syms t real
s(t) = exp(-abs(t))*rectangularPulse(-2,2,t);
figure;
fplot(s(t),[-15 15],'MeshDensity',50)
  3 Comments
Paul
Paul on 14 Nov 2021
At the time, I didn't know how to avoid "clear all" for my use case. As suggested on this page, "clear all" is the way to clear all assumptions from the symbolic engine. As it turns out, there is another, better alternative.
The doc page for clear only says "Calling clear all decreases code performance, and is usually unnecessary," At least that's all I saw. Decreasing performance is one thing. Changing results is quite another.
Rik
Rik on 15 Nov 2021
I think I would classify this at least as unexpected behavior, if not outright as a bug. Did you contact support already?
The mere fact there are better alternatives (as I expected) doesn't change that.

Sign in to comment.

Accepted Answer

Walter Roberson
Walter Roberson on 15 Nov 2021
fplot() operates in two phases. There is some kind of internal preparation first, after which control returns to the program. The fplot continues working in the background. If I recall correctly, the axes is created in the first phase but the lines are drawn in the second phase.
The second phase can take considerable time. Several hours even. It is performing some kind of analysis to try to find accurate representation of rapidly changing lines, and find poles and discontinuities.
If you clear all while fplot is in the second phase, you destroy the data it is relying on but not the fact that it is executing.
You should expect similar difficulties if you have device callbacks going, or timers, or the new background threads.
  3 Comments
Walter Roberson
Walter Roberson on 15 Nov 2021
Some kind of device objects, such as the new serialport() object, are closed and work stopped when you clear the object in memory. For those kinds of objects, if the object is not stored against something like a graphics handle ("clear all" does not close graphics), then the callback should stop -- but there could be a race condition where data used by the callback was destroyed before the clearing of the device object triggered the stop.
For other kinds of device objects, such as the older serial(), the objects continued to exist even if the in-memory reference returned by serial() was cleared -- leading to needing ot do things like delete(instrfind('serial'))
timers are another class of object that you can lose the local reference to without the timer ceasing to exist, which is why timerfind() exists.
It has never been quite clear to me whether there are any circumstances under which handle objects are removed automatically. If you create a handle object, then if you remove all of the workspace handle references to the object, would MATLAB know to garbage-collect far enough to know the object is not longer used? Now if your class records the handle object as persistent class data, then a static class method could be used to retrieve the handle without constructing a new instance, so in that situation a regular clear() of all the returned handles would not be enough. Does "clear all" get at those? Considering that you need "clear classes" or clearing the class specifically for updates to be recognized, I suspect not.
... At the moment I am not even sure if "clear all" removes function persistent data...
Walter Roberson
Walter Roberson on 15 Nov 2021
Edited: Walter Roberson on 15 Nov 2021
memorize('paul')
memory = memorize()
memory = 'paul'
clear all
memory = memorize()
memory = []
function varargout = memorize(varargin)
persistent this_is_a_recording
if nargin > 0
this_is_a_recording = varargin{1};
if nargout > 0
varargout{1} = [];
end
elseif nargout > 0
varargout{1} = this_is_a_recording;
end
end
Okay, so clear all does find ordinary persistent data.

Sign in to comment.

More Answers (1)

Sulaymon Eshkabilov
Sulaymon Eshkabilov on 15 Nov 2021
In such cases, it is best to use: clearvars instead of clear all
  1 Comment
Paul
Paul on 15 Nov 2021
I was using clear all because I wanted to clear the assumptions from the symbolic engine, which clearvars does not do.

Sign in to comment.

Categories

Find more on Large Files and Big Data in Help Center and File Exchange

Products


Release

R2021b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!