clear persistent variables in sub-functions
Show older comments
Hi,
I have a script that calls a function, which is written in separate file and contains sub-functions that are inner to main function only. In one of my sub-functions, I have persistent variable that I would like to clear every time I run the main script. How can I do so? In addition, I have breakpoints through my code, and I would prefer to keep them while I clear the persistent variable - how that can be done?
MainScript.m script:
clear variables;
y = MyMainFunction();
MyMainFunction code:
function temp = MyMainFunction()
some code...
temp = MySubFunction(var);
some code...
end
function dataOut = MySubFunction(dataIn)
persistent idx;
some code...
end
I would like to clear "idx" persistent variable every time that I run MainScript.m, but of course to keep that variable as long as the script is running.
Thanks, John
Answers (4)
The simplest method would be to clear the subfunction:
function temp = MyMainFunction()
clear('MySubFunction')
some code...
temp = MySubFunction(var);
some code...
end
Another simple method would be to introduce an special case, such as using nargin:
clear variables;
y = MyMainFunction();
function temp = MyMainFunction()
MySubFunction;
some code...
temp = MySubFunction(var);
some code...
end
function dataOut = MySubFunction(dataIn)
persistent idx;
if nargin==0
clear whatever variables here...
return
end
some code...
end
6 Comments
J. Smith
on 9 Sep 2015
Walter Roberson
on 9 Sep 2015
function temp = MyMainFunction(clearsubs)
if nargin > 0 & clearsubs
clear MySubFunction;
temp = [];
return
end
some code...
temp = MySubFunction(var);
some code...
end
J. Smith
on 9 Sep 2015
J. Smith
on 9 Sep 2015
@J.Smith: this is easy, just move the "reset call" to the script, instead of inside the main function as I wrote in my answer:
clear variables;
MySubFunction;
y = MyMainFunction();
function temp = MyMainFunction()
some code...
temp = MySubFunction(var);
some code...
end
Or better:
clear variables;
clear('MySubFunction')
y = MyMainFunction();
J. Smith
on 10 Sep 2015
Philip Borghesani
on 9 Sep 2015
I would not use a perstent variable for this. Use a nested function and local variable
function temp = MyMainFunction()
some code...
myCommonVar=[]; %or any useful initial value
temp = MySubFunction(var);
some code...
function dataOut = MySubFunction(dataIn)
%use myCommonVar just as if it were persistent
%it will last as long as the call to MyMainFunction;
some code...
end
end
As to clearing the local function or function: in general James's analysis is correct. He missed on key point that may not be well documented. Only top level or main functions (with the same name as the file) may be cleared. To clear any local or nested function the main function must be cleared and that can't be done while the main function (or any other function in the file) is running.
2 Comments
J. Smith
on 10 Sep 2015
Philip Borghesani
on 10 Sep 2015
Only whole m files can be cleared from memory. The entire file is managed as a unit so sub functions can't be cleared without clearing the main function. It seems like clearing MyManFunction from MainScript as suggested previously is the correct solution. Why does this not work for you?
This may be overkill for some, but I found that just issuing....
clear functions
before the first run clears all persistent variables in my subfunctions. I run this before calling the top-level code each time.
This may be missing the point of the OP (?), but this does 'reset' everything each time. The penalty of course is that the JIT is starting from scratch each time (so a slower initial run), but this is ok behaviour for me.
Hope this is useful for someone.
Arwel
James Tursa
on 9 Sep 2015
Edited: James Tursa
on 9 Sep 2015
0 votes
What happens if you clear MyMainFunction? (Or clear functions)
14 Comments
J. Smith
on 9 Sep 2015
James Tursa
on 9 Sep 2015
What did you type, exactly? The doc states that clearing the function will clear the persistent variable:
As I understand the documentation clearing the main function will only clear any persistent variables in the main function, not those of functions called by the main function: "If name is: A function, then clear name reinitializes any persistent variables in the function". Clearing MySubFunction might work though.
James Tursa
on 9 Sep 2015
That's not how I would have interpreted the table under the Input Arguments / ItemType section. I would have expected "clear functions" to get rid of all functions and persistent variables. (But I don't have MATLAB on this machine to check)
J. Smith
on 9 Sep 2015
James Tursa
on 9 Sep 2015
Edited: James Tursa
on 9 Sep 2015
I have done some limited testing (R2013a Win64) and here is what I have observed:
I started with a file function_name.m and at the end of that file there is a sub function called subfunction. function_name calls subfunction. Inside subfunction is a persistent variable called p.
clear all, clear functions, and clear function_name all clear the function and the persistent variable p inside the subfunction, just as I expected from my interpretation of the doc table noted above.
However, there is a gotcha I have discovered. When any of these clear commands is issued from within the function_name function itself, the command apparently gets queued and doesn't take effect until after function_name exits. Mind you, I don't know if this is really an accurate description of what is really happening, but that is the behavior I am seeing.
To be clear, function_name.m is a function file that calls subfunction which is a function at the end of the function_name.m file. subfunction has a persistent variable p. Upon entry to subfunction, a message prints to state if p is currently empty or not. If p is empty then p is created as a large 200MB variable (so that its presence easily show up in the memory command).
When I issue clear all, clear functions, or clear function_name from either the command line or from another function file, p gets cleared from memory every time (i.e., the subsequent calling of function_name (and thus subfunction) gives a message that p is empty and needs to be created). But when I issue any of these clear commands from within function_name, and then immediately call subfunction, subfunction gives a message that p already exists and indeed the 200MB memory for it shows up when memory is examined from within subfunction. But once subfunction returns to function_name, and function_name returns to the command line, a memory command reveals that p is no longer there (the 200MB has been free'd). I.e., it is as if the clear command got queued and didn't execute until after the functions exited (which I guess makes sense ... how could the currently executing function get cleared from memory immediately while it is executing?).
Ben Barrowes
on 5 Apr 2017
This behavior still exists in 2017a. Is this a bug or a feature? If I have an m-file which calls 20 other m-files, and they in turn call 20 more each (all with persistent variables), I don't want to put 420 statements to clear the persistent variables in each subfunction. I would just like to issue one statement such as 'clear functions' from within the first m-file.
Jan
on 5 Apr 2017
@Ben: This is a problem of your code design. Distributing many persistent variables over a bunch of functions does not allow to clear them easily. Perhaps an object oriented approach will be cleaner.
Ben Barrowes
on 6 Apr 2017
I convert a lot of fortran to matlab. In doing so, I need to make matlab variables persistent because that is the default fortran behavior. But each time a fortran executable is run, all the persistent variables are cleared. But persistent variables are not cleared each time a run the main m-file corresponding to the "program" subunit in a fortran program.
When I convert 400kline code and have thousands of persistent variables, I want an easy way to clear all of them with one command at the beginning of the main m-file.
My code is designed poorly by your standards, but saying that does not help me with my problem. Furthermore, the documentation is ambiguous: it says "clear functions" clears persistent variables, but there is this undocumented limitation that "clear functions" does not work inside a function until the function completes.
Jan
on 6 Apr 2017
@Ben: Sorry, I know that it is not help to mention the poor design. Let me encourage you to redesign it. It seems to be a large code and solve the problem successfully. Then it would be a pitty, if it is hard to maintain and control. A re-design is a standard concept in code manufacturing.
Having a 400'000 line code and thousands of persistent variables is one thing. Wanting to have a method to clear all persistent variables is another. In general it is smarter to adjust a program to the possibilities of a language, and not the other way around.
Can you clear the persistent variables at the end of the code?
Ben Barrowes
on 14 Apr 2017
To get the same behavior in matlab as one does in fortran, I have to use persistent variables in matlab. I have thought about how to convert codes to matlab without using persistent variables, but I have not found a solution yet.
So, basically your answer is "matlab can't do that, so rewrite your code". Correct? I am not being sarcastic or ungrateful, I just want to summarize your answer. If matlab can't do that, then I have to find another way. But if matlab's docs say "clear functions" does what I want, but upon execution behavior is different that the docs, then either it is a bug, or the docs have to be rewritten.
I tried your suggestion of clearing variables at the end of the main m-file. Putting "clear functions" at the end of execution does not work, but "clear all" does seem to work. If I put a clear all at the end of the main m-file and before each return in the m-file, then this solution should work.
Thanks.
MATLAB is definitely Turing complete, so there is no computational problem that MATLAB cannot do. This is not a question what can or cannot be done, and to look at it from that perspective is not going to help you. Trying to write code in one language as if were another language is the problem. When converting a function from one language to another there are always going to be different ways of doing things, and in many cases efficiency (implementation time, bug-fixing time, running time) will dictate that changes need to occur.
"matlab can't do that, so rewrite your code"
MATLAB can achieve your task, but not if you try and approach writing MATLAB code as if it were FORTRAN code. Would you try to write C++ code as if it were Python? Would you expect it to be efficient? Do you write your Haskell as if it were Perl? (I shudder to think how awful that would be). Even if MATLAB has evolved from FORTRAN, there is no reason why any language idioms have to be the same.
Jan Simon is correct: to make this work in MATLAB you need to design MATLAB code from the ground up.
Or, if the exact behavior is important, why not simply call the FORTRAN from MATLAB?
Ben Barrowes
on 14 Apr 2017
I agree rewriting a code with excellent skills would be a worthwhile goal. The difficulty is that many of my clients don't have the resources to make that goal from the beginning.
Many times, companies come to me with anything from old crufty fortran IV or f77 code to modern code that they need converted source to source into matlab, but they don't have the time or money to do a complete rewrite. What they would like is a working conversion in matlab (for a tenth or hundredth of the time and money of a rewrite) of their 10kline to 1000kline+ code rapidly and cheaply. Then their plan is to switch to matlab for that code and modify and develop the matlab code gradually going forward. I can do that for them if I can get the matlab conversion to behave like the fortran version. If I have to modify 400klines of matlab code and 3000 variables to not depend on persistence, it can amount to a rewrite which my clients do not want though maybe in a perfect world they would.
This persistent variable issue is one issue that I would like a solution to in matlab. In addition, the documentation is essentially incorrect for "clear functions." I have a workaround by adding "clear all" at the end of the main program but I would like a way to clear all persistent variables at the entrance to a m-file. I am simply asking matlab to provide a feature that they currently claim they provide in their documentation.
Stephen23
on 14 Apr 2017
@Ben Barrows: it sounds like you have experience to build a robust explanation and case for either submitting a bug report (incorrect documentation), or requesting an enhancement. Make this formal and see what response you get from TMW.
Categories
Find more on MATLAB Compiler in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!