What is the correct name for the situation where a Matlab-script calls a function, but provides arguments without parentheses?
Example:
clear xx
Alternatively, I could use parentheses and transfer a string with the variable name:
clear('xx')
How can I distinguish between both alternatives when googling for a solution?
Bonus Question: How can I put the content of a variable into a call that is NOT using parentheses? Specifically, a build-script using mcc with a dynamic -o filename option; calling mcc with parentheses would also be acceptable, but I don't know how to google that, hence this question.
Thank you!
When you call a function without the brackets, it is called command syntax. Here are three links to relevant documentation:
syntax
command vs function syntax
scripts and functions
Bonus answer
You cannot use a variable when using command syntax. From the docs:
When calling a function using command syntax, MATLAB passes the arguments as character vectors.
So it would work like so:
abc = zeros(10); % Some matrix called abc
mystring = 'abc' % A string containing the variable name
% Option 1:
clear('abc') % Clears the variable abc
% Option 2:
clear abc % As per above docs quote, interpreted as clear('abc')
% Option 3:
clear mystring % As per option 2, interpreted as clear('mystring') so doesn't work
% Option 4:
clear(mystring) % Interpreted as clear('abc') so works as expected
When calling mcc as you suggest in the question, the tooltip shows you can in fact use function syntax, despite the documentation being entirely shown using command syntax.
Notes
Using brackets is standard practise in MATLAB, since you also cannot get output values from a function when using command syntax.
Also from the 3rd docs link above, you can see a message discouraging the use of command syntax when using MATLAB.
Caution: While the unquoted command syntax is convenient, in some cases it can be used incorrectly without causing MATLAB to generate an error.
Related
I have searched around quite a bit and have failed to find an answer. In AutoHotKey, I am not sure the difference when a single percent is used near the beginning of a line, and when a variable is enclosed between two percent signs. I usually use trial and error to find when I use one or the other, I am hoping someone could shed some light on what the difference is or explain what it is actually doing.
Here are some examples of this in action.
Example 1: I noticed if you have multiple variables along with text, scripts tend to go with the preceding percent. Such as:
some_val := Clipboard
loop 5
msgbox % "Index:" . A_Index . ", variable:" . some_val
Example 2: I often see this as well, and sometimes it appears it must be used. Is this true?
some_variable := "test text to send"
Send, %some_variable%
Wrapping in double percent signs is legacy AHK and basically there is no need to ever use it anymore. Only reason to wrap in double % would be being stuck behind in the old times, or maybe one could argue it also being more convenient, or something, to write in some cases, but I'm not buying it.
The legacy syntax is replaced by expression syntax.
The expression syntax is closer to how many other languages behave. AHK legacy syntax really is a mess.
All legacy commands (MsgBox for example) use the old legacy syntax on each parameter (unless otherwise specified).
If you specify a % followed up by a space at the start of the parameter, you're forcing AHK to evaluate an expression on that parameter instead of reading it as a legacy text parameter.
Example:
MsgBox, 5+5
We're using a legacy command, we're not starting the parameter off with a % and a space, so we're using the legacy syntax. The MsgBox is going to print the literal text 5+5 instead of 10.
MsgBox, % 5+5
Again, legacy command, but now we're forcing AHK to evaluate an expression here, 5+5.
The result of expression's evaluation is going to be passed onto the MsgBox command and the MsgBox is going to print 10.
If we wanted to MsgBox to print the literal text 5+5, and use the expression syntax to do it, we'd do MsgBox, % "5+5".
Quotation marks in expression syntax mean we're specifying a string.
Well then there's the problem of knowing when you're in expression syntax, and when you're in the legacy syntax.
By default, you're basically always in an expression.
You leave it by for example using a command or = to assign.
If the difference between a command and a function isn't clear to you, here's an example:
Command, % 7+3, % MyCoolArray[4], % SomeOtherNiceFunction(), % false
Function(7+3, MyCoolArray[4], SomeOtherNiceFunction(), false)
In the command we specified a % followed up by a space to evaluate the expressions on each parameter, and in the function, we didn't have to do that since we're already in an expression.
And if you're not clear on the difference between = and :=,
= is legacy and deprecated, it assigns plain text to a variable
:= assigns the result of an expression to a variable.
So that's what I could write from on top of my head.
If you had some more complex examples, I could try showing on them. Maybe convert some code you may have over to expression syntax, make it 100% free of legacy syntax.
And here's a good page on the documentation you should give a read:
https://www.autohotkey.com/docs/Language.htm
In the answer to this question the MathWorks Support Team states that:
It is also possible to overload the ! (bang) operator by creating a
file called "!.m" and having this file be before the directory
$MATLABROOT\toolbox\matlab\general in the MATLAB search path.
I have tried this and it doesn't seem to work. I am running Matlab 9.1.0.441655 (R2016b) on Linux Mint. My path looks like that:
/home/raphael/Programs/Test
/usr/local/MATLAB/R2016b/toolbox/matlab/iofun
...
/usr/local/MATLAB/R2016b/toolbox/matlab/general
...
and I have created a file !.m in /home/raphael/Programs/Test. Whatever I put in this file the editor displays an error:
Line 1: Unable to run code analysis. '/home/raphael/Programs/Test/!.m' is an invalid file name.
As the ! (bang) operator is not listed in the Operators and associated function list, it is unclear what to put inside the !.m file.
I have nevertheless tried to put some code:
function bang(c)
disp(c)
but though which ! returns my custom file path, Matlab invariably calls the built-in operator:
>> which !
/home/raphael/Programs/Test/!.m
>> !pwd
/home/raphael/Programs/Test
Renaming the file to bang.m resolves the error but has no effect on the bang operator.
So:
Did Matlab's behavior changed since R2012?
How could one overload the ! (bang) operator?
And if this is actually possible, what should be the syntax of the function declaration?
It looks like this undocumented handling of !.m disappeared in R2015b (presumably with the new execution engine changes that were also introduced with that release).
For versions earlier than R2015b, you can indeed name a file !.m on the path and then the name of the function within the file doesn't matter (as it never does in MATLAB).
!.m
function bang(varargin)
disp('bang!')
end
In current versions of MATLAB, the ! operator will ignore your !.m file but will call the underlying system, unix, or dos commands. Therefore you'll need to overload those commands instead.
So on OS X, overloading just unix.m does the trick:
unix.m
function varargout = unix(varargin)
disp('My Unix Command')
[varargout{1:nargout}] = builtin('unix', varargin{:});
end
I am trying to use the function armaxfilter from the MFE toolbox, but I get an error:
>> parameters = armaxfilter(y,1,1,1);
??? Error: File: armaxfilter.m Line: 477 Column: 21
Expression or statement is incorrect--possibly unbalanced (, {, or [.
Apparently my code is correct, as can be seen from an example from help:
EXAMPLE:
To fit a standard ARMA(1,1), use
parameters = armaxfilter(y,1,1,1)
Any idea on what is wrong?
In any case, my aim is getting residuals from an ARMA model estimation on a time series, a suggestion on an alternative way would be helpful as well.
Looking at the code (from here) , the issue is probably with the tilde output. If you are using an old version of MATLAB which does not support ~, you may get the error you mention.
There is a simple way to check this. Try out at the command line:
[~,idx] = min(1:10)
If this causes an error, you are using a version of MATLAB which does not support ~. If you want to use that particular code, you will have to either upgrade your MATLAB, or edit all the files such that examples of the tilde are replaced with some sort of dummy variable, e.g.:
[garbage,idx] = min(1:10)
As the error message describes, the problem lies in the armaxfilter.m. You should open that file and see what code is written at the specified line. I am sure you will see a bug in there.
In a function, I have a few instances of disp() to help keeping track of the progress of a long computation process.
For example,
function myfun(inputs)
...
disp('Step i finished')
...
end
In some other usage of myfun, it is more convenient not having the disp() messages. Is there a way to suppress the message 'Step i finished' in command line WITHOUT either adding new code OR using the eval() function?
Note: eval() is known to be too slow for any serious computation.
There is no mechanism to redirect "stdout" in MATLAB. You can capture it with evalc and then ignore it, but that also captures (and thus suppresses) all warnings. Also, all the usual objections to using eval apply.
If you insist then you can use this bad bad BAD hack:
disp = #(~) display([]); %# at the start of the function
or, if you really don't want to change a single letter in your function, put
function disp(~)
in a separate M-file on the MATLAB path, and remove its path from the MATLAB path (or remove/rename the file) when you're done.
But really, the best way is to rewrite your function so that display is optional, and/or the level of display tunable. For example, like in virtually all of MATLAB's own functions:
options = optimset('Display', 'iter-detailed');
[~] = fminsearch(#cos, 3, options);
spparms('spumoni', 2);
sparse(rand(4)) \ rand(4,1)
A very simple way to implement the ability to turn on/off diagnostic messages like this is to use a utility function vfprintf:
function vfprintf(verbose, varargin)
if verbose
fprintf(varargin{:})
else
% Do nothing
end
Then you can set verbose to be true or false, and otherwise use the function just like you would fprintf. You could do a very similar thing to create a vdisp function as well.
I just discovered (to my surprise) that calling the following function
function foo()
if false
fprintf = 1;
else
% do nothing
end
fprintf('test')
gives and error Undefined function or variable "fprintf". My conclusion is that the scope of variables is determined before runtime (in my limited understanding how interpretation of computer languages and specifically Matlab works). Can anyone give me some background information on this?
Edit
Another interesting thing I forgot to mention above is that
function foo()
if false
fprintf = 1;
else
% do nothing
end
clear('fprintf')
fprintf('test')
produces Reference to a cleared variable fprintf.
MATLAB parses the function before it's ever run. It looks for variable names, for instance, regardless of the branching that activates (or doesn't activate) those variables. That is, scope is not determined at runtime.
ADDENDUM: I wouldn't recommend doing this, but I've seen a lot of people doing things with MATLAB that I wouldn't recommend. But... consider what would happen if someone were to define their own function called "false". The pre-runtime parser couldn't know what would happen if that function were called.
It seems that the first time the MATLAB JIT compiler parses the m-file, it identifies all variables declared in the function. It doesn't seem to care whether said variable is being declared in unreachable code. So your local fprintf variable immediately hides the builtin function fprintf. This means that, as far as this function is concerned, there is no builtin function named fprintf.
Of course, once that happens, every reference within the function to fprintf refers to the local variable, and since the variable never actually gets created, attempting to access it results in errors.
Clearing the variable simply clears the local variable, if it exists, it does not bring the builtin function back into scope.
To call a builtin function explicitly, you can use the builtin function.
builtin( 'fprintf', 'test' );
The line above will always print the text at the MATLAB command line, irrespective of local variables that may shadow the fprintf function.
Interesting situation. I doubt if there is detailed information available about how the MATLAB interpreter works in regard to this strange case, but there are a couple of things to note in the documentation...
The function precedence order used by MATLAB places variables first:
Before assuming that a name matches a function, MATLAB checks for a variable with that name in the current workspace.
Of course, in your example the variable fprintf doesn't actually exist in the workspace, since that branch of the conditional statement is never entered. However, the documentation on variable naming says this:
Avoid creating variables with the same name as a function (such as i, j, mode, char, size, and path). In general, variable names take precedence over function names. If you create a variable that uses the name of a function, you sometimes get unexpected results.
This must be one of those "unexpected results", especially when the variable isn't actually created. The conclusion is that there must be some mechanism in MATLAB that parses a file at runtime to determine what possible variables could exist within a given scope, the net result of which is functions can still get shadowed by variables that appear in the m-file even if they don't ultimately appear in the workspace.
EDIT: Even more baffling is that functions like exist and which aren't even aware of the fact that the function appears to be shadowed. Adding these lines before the call to fprintf:
exist('fprintf')
which('fprintf')
Gives this output before the error occurs:
ans =
5
built-in (C:\Program Files\MATLAB\R2012a\toolbox\matlab\iofun\fprintf)
Indicating that they still see the built-in fprintf.
These may provide insight:
https://www.mathworks.com/help/matlab/matlab_prog/base-and-function-workspaces.html
https://www.mathworks.com/help/matlab/matlab_prog/share-data-between-workspaces.html
This can give you some info about what is shadowed:
which -all
(Below was confirmed as a bug)
One gotcha is that Workspace structs, and classes on the path, have particular scoping and type precedence that (if you are me) may catch you out.
E.g. in 2017b:
% In C.m, saved in the current directory
classdef C
properties (Constant)
x = 100;
end
end
% In Command window
C.x = 1;
C.x % 100
C.x % 1 (Note the space)
C.x*C.x % 1
disp(C.x) % 1