Can operators be stored in variables? - matlab

This is a thought example of what I am thinking of:
test = 'x > 0';
while str2func(test)
Do your thing
x=x-1;
end
Is it possible to store whole logical operations in a variable like this?
Of course the str2func will break here. If it is possible this function will likely be something else. And I have only added apostrophes to the test variable content, because I cannot think of what else would be the storing method.
I can see it usefull when sending arguments to functions and alike. But mostly I'm just wondering, because I have never seen it done in any programming language before.

You can store the textual representation of a function in a variable and evaluate it, for example
test = 'x > 0';
eval(test)
should result in 1 or 0 depending on x's value.
But you shouldn't use eval for reasons too-often covered here on SO for me to bother repeating. You should instead become familiar with functions and function handles. For example
test = #(x)x>0
makes test a handle to a function which tests whether its argument is greater than 0 or not.
Many languages which are interpreted at run-time, as opposed to compiled languages, have similar capabilities.

Related

When is the eval function necessary?

I just read the following article from MathWorks which describes why it is important to avoid the eval function and lists alternatives to many of eval's common uses.
After reading the article, I have the impression that the eval function is neither useful nor necessary. So, my question is this: When is the eval function necessary?
I have found only one useful case for eval, and then the evalc variety: when calling a function with built-in command line call back (e.g. lines without ; or with disp calls), which you cannot modify. For instance when you got some obfuscated function that dumps heaps of stuff to your command window. In that case it's best to try and obtain the source code to modify that to your needs, as using evalc will mess up your performance. Otherwise, I have not found a case where eval is the best solution.
I wrote an extensive answer detailing why you should try to avoid eval as much as possible here: How to put these images together?
I have already used eval when trying to create multiple arrays with different names. This is not really recommended, but it worked for my specific application. For example, if I wanted to have N matrices with the specific names "matrix1" "matrix2" .. "matrixN" , one solution would be to manually type these in as "matrix1 = something" ... "matrixN = somethingelse". If N is really large, this is not ideal. Using eval , you could set up a for loop that would change the name of the matrix on every loop, and calculate some value based on that same N value.
Of course, ideally saving them in to a cell would be better, but I needed the arrays in the format I described.

At which lines in my MATLAB code a variable is accessed?

I am defining a variable in the beginning of my source code in MATLAB. Now I would like to know at which lines this variable effects something. In other words, I would like to see all lines in which that variable is read out. This wish does not only include all accesses in the current function, but also possible accesses in sub-functions that use this variable as an input argument. In this way, I can see in a quick way where my change of this variable takes any influence.
Is there any possibility to do so in MATLAB? A graphical marking of the corresponding lines would be nice but a command line output might be even more practical.
You may always use "Find Files" to search for a certain keyword or expression. In my R2012a/Windows version is in Edit > Find Files..., with the keyboard shortcut [CTRL] + [SHIFT] + [F].
The result will be a list of lines where the searched string is found, in all the files found in the specified folder. Please check out the options in the search dialog for more details and flexibility.
Later edit: thanks to #zinjaai, I noticed that #tc88 required that this tool should track the effect of the name of the variable inside the functions/subfunctions. I think this is:
very difficult to achieve. The problem of running trough all the possible values and branching on every possible conditional expression is... well is hard. I think is halting-problem-hard.
in 90% of the case the assumption that the output of a function is influenced by the input is true. But the input and the output are part of the same statement (assigning the result of a function) so looking for where the variable is used as argument should suffice to identify what output variables are affected..
There are perverse cases where functions will alter arguments that are handle-type (because the argument is not copied, but referenced). This side-effect will break the assumption 2, and is one of the main reasons why 1. Outlining the cases when these side effects take place is again, hard, and is better to assume that all of them are modified.
Some other cases are inherently undecidable, because they don't depend on the computer states, but on the state of the "outside world". Example: suppose one calls uigetfile. The function returns a char type when the user selects a file, and a double type for the case when the user chooses not to select a file. Obviously the two cases will be treated differently. How could you know which variables are created/modified before the user deciding?
In conclusion: I think that human intuition, plus the MATLAB Debugger (for run time), and the Find Files (for quick search where a variable is used) and depfun (for quick identification of function dependence) is way cheaper. But I would like to be wrong. :-)

Set function workspace to base in MATLAB

I have a rather bulky program that I've been running as a script from the MATLAB command line. I decided to clean it up a bit with some nested functions (I need to keep everything in one file), but in order for that to work it required me to also make the program itself a function. As a result, the program no longer runs in the base workspace like it did when it was a script. This means I no longer have access to the dozens of useful variables that used to remain after the program runs, which are important for extra calculations and information about the run.
The suggested workarounds I can find are to use assignin, evalin, define the variables as global, or set the output in the definition of the now function-ized program. None of these solutions appeal to me, however, and I would really like to find a way to force the workspace itself to base. Does any such workaround exist? Or is there any other way to do this that doesn't require me to manually define or label each specific variable I want to get out of the function?
Functions should define clearly input and output variables. Organizing the code differently will be much more difficult to understand and to modify later on. In the end, it will most likely cost you more time to work with an unorthodox style than investing in some restructuring.
If you have a huge number of output variables, I would suggest organizing them in structure arrays, which might be easy to handle as output variables.
The only untidy workaround I can imagine would use whos, assignin and eval:
function your_function()
x = 'hello' ;
y = 'world' ;
variables = whos ;
for k=1:length(variables)
assignin('base',variables(k).name,eval(variables(k).name))
end
end
But I doubt that this will help with the aim to clean up your program. As mentioned above I suggest ordering things manually in structures:
function out = your_function()
x = 'hello' ;
y = 'world' ;
out.x = x ;
out.y = y ;
end
If the function you would like to define are simple and have a single output, one option is to use anonymous functions.
Another option is to store all the variable you would like to use afterwards in a struct and have your big function return this struct as an output.
function AllVariables = GlobalFunction(varargin);
% bunch of stuff
AllVariables= struct('Variable1', Variable1, 'Variable2', Variable2, …);
end

Elegant way to set a mode of operation across multiple function files

I've written a piece of code which calls numerous functions, which in turn also call several sub-functions.
I am calling the main file from the command line and supplementing the call with certain arguments to initiate certain modes I have accounted for.
E.g. octave classify_file.m --debug <file> would run in my custom debug mode, which sets a constant debug to 1 and subsequently outputs all plots and relevant variables. Omitting the argument outputs only 1 variable.
Similarily I have a template and a histogram mode, which essentially all do the same thing, except output some more variables, matrices and plots depending on the mode.
As it is now, I have to include the debug, template and histogram constants as arguments to each and every function if I want them to be influenced by the respective modes.
This is cumbersome and confusing, there has to be a better way. I've never worked with global variables, but would this be a good place to use one? What's an elegant solution for this problem?
This is a situation in which global variables will come in handy, although as you may be aware they are sometimes frowned upon, and can also have certain performance implications in matlab. Personally I don't think passing the mode all the way down the call stack is too bad - although are you treating all 3 as separate arguments? The least you could do is put them in a struct in your highest level function so that you only have 1 argument:
mode.debug = [whatever]
mode.histogram = [whatever]
mode.template = [whatever]
myFunction(mode);
OR, if you can only have one mode at a time what about some integer constants?
mode = MODE_DEBUG
or
mode = MODE_NONE
I would define the constants by creating short functions, this is how the pi constant works for example.
Finally, there is an alternative to global variables which I rather like, which is functions that use persistent variables. For example:
function m = debugMode(newValue)
persistant isModeOn;
if nargin > 0
isModeOn = newValue
end
m = isModeOn;
end
This way you can call debugMode(1) to set it on, and you can call m = debugMode anywhere to get the value.

Use and implications of eval('expression') in MATLAB code?

I was encountered with usage of function eval(expression) in somebody else's code in matlab:
for example:
for n = 1 : 4
sn = int2str( n) ;
eval( [ 'saveas( fig' sn ', [ sName' sn ' ], ''fig'' ) ' ] );
end
MathWorks stuff in Matlab Help pointed out that:
Many common uses of the eval function are less efficient and are more difficult to read and debug than other MATLAB functions and language constructs.
After this, I find usage of this function in many other program languages, so as Python, JavaScript, PHP.
So I have a few questions:
Will usage of this function be enfluenced on the performance of my code?
If it will slow down execution, why does it occur?
If it slow down execution every time when called, what reason for use this function in principle?
The eval function is dangerous and there are very few examples where you actually need it. For example, the code you gave can easily be rewritten if you store the figure handles in an array fig(1), fig(2) etc and write
for n = 1:4
filename = sprintf('sName%d', n);
saveas(fig(n), filename, 'fig');
end
which is clearer, uses fewer characters, can be analysed by the Matlab editor's linter, is more easily modifiable if (when) you need to extend the code, and is less prone to weird bugs.
As a rule of thumb, you should never use eval in any language unless you really know what you are doing (i.e. you are writing a complicated Lisp macro or something else equivalent to manipulating the AST of the language - if you don't know what that means, you probably don't need to use eval).
There are almost always clearer, more efficient and less dangerous ways to achieve the same result. Often, a call to eval can be replaced with some form of recursion, a higher-order function or a loop.
Using eval here will certainly be slower than a non-eval version, but most likely it won't be a bottleneck in you code. However, the performance is only one issue, maintenance (incl. debugging), as well as readability are other ones.
The slowdown occurs because Matlab uses a JIT compiler, and eval lines cannot be optimized.
Eval use is in most cases due to lack of knowledge about the Matlab functionality that would be appropriate instead. In this particular case, the issue is that the figure handles are stored in variable names called fig1 through fig4. If they had been stored in an array called fig, i.e. fig(1) etc, eval would have been unnecessary.
EDIT Here are two excellent articles by Loren Shure about why eval should be avoided in Matlab. Evading eval, and More on eval.
For the most part, the slowdown occurs because the string has to be parsed into actual code. This isn't such a major issue if used sparingly, but if you ever find yourself using it in code that loops (either an explicit loop or things like JavaScript's setInterval()) then you're in for a major performance drop.
Common uses I've seen for eval that could be done better are:
Accessing property names in the ignorance of [] notation
Calling functions based on an argument name, which could instead be done with a switch (safer, prevents risk of code injection)
Accessing variables named like var1, var2, var3 when they should be arrays instead
To be honest, I don't think I've ever encountered a single situation where eval is the only way to solve a problem. I guess you could liken it to goto in that it's a substitute for program structure, or useful as a temporary solution to test a program before spending the time making it work optimally.
Here is another implication:
When you compile a program that uses eval, you must put pragmas that tell the compiler that some functions are needed. For example:
This code will compile and run well:
foo()
But this one needs a pragma added:
%#function foo
eval('foo()')
Otherwise you will encounter a runtime problem.