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

조회 수: 1 (최근 30일)
Paul
Paul 2021년 11월 14일
편집: Walter Roberson 2021년 11월 15일
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
Paul
Paul 2021년 11월 14일
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 2021년 11월 15일
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.

댓글을 달려면 로그인하십시오.

채택된 답변

Walter Roberson
Walter Roberson 2021년 11월 15일
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
Walter Roberson
Walter Roberson 2021년 11월 15일
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 2021년 11월 15일
편집: Walter Roberson 2021년 11월 15일
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.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Sulaymon Eshkabilov
Sulaymon Eshkabilov 2021년 11월 15일
In such cases, it is best to use: clearvars instead of clear all
  댓글 수: 1
Paul
Paul 2021년 11월 15일
I was using clear all because I wanted to clear the assumptions from the symbolic engine, which clearvars does not do.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Large Files and Big Data에 대해 자세히 알아보기

제품


릴리스

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by