What's the purpose of 'coder' in matlab? - matlab

I was seeing the built-in function estimateFundamentalMatrix and it looks like as follows
function r = checkOutputClassStrings(list, value)
potentialMatch = validatestring(value, list, ...
'estimateFundamentalMatrix', 'OutputClass');
coder.internal.errorIf(~strcmpi(value, potentialMatch), ...
'vision:estimateFundamentalMatrix:invalidOutputClassString');
r = 1;
I was curious about the coder.internal.errorIf function. I guessed that coder is a system object that shows internal states of a function, but I don't know exactly.

coder is a package that is part of the MATLAB Coder product.
MATLAB Coder allows you to convert a subset of the MATLAB language into C code - the C code can then subsequently be incorporated into wider C applications, or brought back into MATLAB via the MEX interface, or delivered to an embedded device. When using MATLAB Coder, you will include commands from the coder package within your MATLAB code - they typically have no effect on the code when it is run within MATLAB, but when converting to C code they help you to control the way it is converted, by adding additional information necessary to help with the conversion (for example, by controlling the inlining of a function, or specifying that a for-loop should be unrolled).
Some toolboxes, including the Computer Vision Toolbox that contains the code snippet you refer to, explicitly support the use of MATLAB Coder to generate C code from them, in that they make sure to only use the subset of the MATLAB language that is convertible into C, and they include coder commands to help optimise their conversion into C.
The command you're seeing here says that, when converting the MATLAB code into C, it should include an explicit check in the C code to compare value with potentialMatch, and exit with an error if they don't match.
(I'll be honest - I'm not entirely sure why this is necessary. As far as I can see, if the code has got past the validatestrings statement, then by definition it should always pass the test in the subsequent statement. Seems a bit redundant to me, but maybe I'm overlooking some detail).

I'm just formalising the answer I gave in the comments...
The coder.internal.errorIf is exactly what the name suggests. It's an internal command to conditionally issue an error.
The strcmpi function performs a case insensitive string compare, and returns a Boolean (true/false) value.
The tilde (~) negates the result of the call to strcmpi.
So the line you're curious about is somewhat equivalent to this on the surface:
% Use strcmpi for case insensitive string comparison
if ~strcmpi(value, potentialMatch)
% When using 'error', the string must be specified along with the message identifier.
% The errorIf command was leveraging the in-built 'message' catalog.
% In this case I've lifted the error message from calling the original errorIf command.
error('vision:estimateFundamentalMatrix:invalidOutputClassString', ...
'Expected OutputClass to be ''double'' or ''single''');
end
The code.internal.errorIf command is, as pointed out in other answers and comments, a different construct than the common error command, which allows MATLAB to optimise C code generation (hence why it is in the coder package).
For more coder-specific details, see Sam's answer.

Related

Call overloaded function from specific toolbox in MATLAB

I have some Matlab-Toolboxes installed. In my Matlab version one of the Toolbox-Functions collides with another. In this case it is hessian. I want to use the hessian function of the symbolic-Toolbox.
When in C/C++ Functions are multiple defined like the function for cos and I still want to use the “standard” cos-function I can write:
std::cos(x);
Is there something similar in matlab?
If you have overloaded methods and want to call the built in one, you can use the function builtin. From the official documentation:
builtin(function,x1,...,xn) executes the built-in function with the
input arguments x1 through xn. Use builtin to execute the original
built-in from within a method that overloads the function. To work
properly, you must never overload builtin.
The syntax for using it is:
[y1,...,yn] = builtin(function,x1,...,xn)
Friendly advice: If you want to try overloading builtin ("hmm, I wonder what would happen"), remember to save stuff first.
In a very similar way that you were describing for c/c++, you can use a specific toolbox function by adding the name of the toolbox first : ToolboxName\function2call()
First use the which command to make sure of which function from which toolbox will be loaded with a specific call syntax.
Since I do not have the toolbox you are mentioning i'll use the classic fopen function as an example.
The first fopen function called without any other parameter will be the built in function which is used to return a handle to a file. Indeed, the which command confirms that:
>> which fopen
built-in (C:\TLAB13a\toolbox\matlab\iofun\fopen)
Now let's say I want to use the fopen function to open a serial port, I need to prefix the call to fopen with the name of the toolbox/object, like so: serial\fopen. Let's first make sure this way of calling point to the right function:
>> which serial\fopen
C:\TLAB13a\toolbox\matlab\iofun\#serial\fopen.m % serial method
Bingo !
And just to make sure this works when you are calling these functions, let's call them for real (with dummy parameters):
>> fopen('toto')
ans =
-1
>> serial\fopen('toto')
Error using serial (line 72)
The PORT must be specified.
It worked. The first simple call to fopen('toto') return -1 because it couldn't find a file named "toto".
The second call to serial\fopen('toto') errored because the serial port was not defined, but the right function was called.
Edit:
You can also override the order in which Matlab will fetch functions by re-ordering the Matlab path. If you put the symbolic toolbox before the other one in your path, then when called without explicit information, Matlab will execute the first function it finds in the path.
I would still recommend the first solution with explicit declaration though, because changing the path order could mess up other function call in case you have many overloaded functions.

Using abbreviations for parameter-value input pairs - why does cellfun's `'UniformOutput', false` work as `'un', 0`?

As a frequent user of cellfun(..., 'UniformOutput', false), I was surprised to discover that the latter two arguments could be input as cellfun(..., 'un', 0). This has immediately shortened my code. My question is, are there any another similar shortcuts/aliases out there?
This doesn't appear to be documented on the MathWorks website. Naughty!
Background
The property part of a Property-value pair can be often be shortened to the beginning of the property string so long as it is still uniquely identifiable (see examples below). They are also often not case sensitive.
As far as I know this is not documented for anything other than figure properties, where it is very briefly documented.
However this behaviour is also implemented in many The MathWorks functions which take property-value pair arguments, and also in some functions which take string arguments with no value pair.
The problems become what other properties are there...
For some functions is not well documented... (and many are either
built-in or obfuscated .p files, so no checking the source).
Most importantly we cannot know if future versions will introduce new
properties.
The use of shortened property names is advised against for this reason, to quote
"using the full property name can prevent problems with futures releases of MATLAB if a shortened name is no longer unique because of the addition of new properties." - Matlab documentation
"Don't shorten your code with P-V abbreviations, it's not worth it, trust me." – Sam Roberts
The brief slightly technical side - This functionality is implemented by default by Matlabs inputParser, however it can be disabled so these abbreviations are by no means guaranteed to work on every function. Only those which use the inputParser in this way or are specifically written to allow this.
Examples using figure properties
Simple Shortening
The following
hFig = figure();
get(Hfig,'Visible')
ans =
on
can be shortened to
hFig = figure();
get(Hfig,'v')
ans =
on
as it is the only property beginning with 'v' (note that 'vi','vis', etc... also work)
Uniqueness
However other properties which start similarly e.g. CurrentAxes, CurrentCharacter & CurrentObject
get(Hfig,'Current')
Error using get
Ambiguous property found.
Object Name: figure
Property Name: 'Current'.
Where as 'currenta','currentc' and 'currento' are uniquely identifiable and would work as intended
Impossible to shorten
A special mention to properties such as Color and ColorMap the name of one is the beginning of another
Color can only be used with its full name, due to any shortening being ambiguous with ColorMap
'ColorMap' can be shorted to 'colorm' however, as before.
Counter examples
This section aims to discourage use of shortened property value pairs by showing some of the seemingly unpredictable and unexpected behaviour.
The semi-undocumented hardcopy has some interesting behaviour the documentation states possible options as -dps,-deps,-dps2,-deps2,-dill,-dhpgl
However '-dh' creates an error where as '-di' works as an abbreviated '-dill' sadly there is no checking the source to see why as it is a .p file
Finally cellfun itself doesn't exactly follow there rules as 'u' should theoretically work if following the rules above, however only 'un' and onwards does.
If a routine uses MATLAB's inputParser functionality then usually any parameter name can be shortened such that it is still unambiguous and is matched case insensitively. The same is true for properties of objects such as get(gcf, 'pos') as a shorter version of get(gcf, 'Position').
However, I don't know if there is any documentation on this usage and I suggest you try it and see.
And 0 is usually equivalent to false (non-zero being true).
PS I would suggest that using these shortcuts is fine at the command line but when writing functions and scripts it is better to use the full names.

Matlab function signature changes

Let us say that I have a Matlab function and I change its signature (i.e. add parameter). As Matlab does not 'compile' is there an easy way to determine which other functions do not use the right signature (i.e. submits the additional parameter). I do not want to determine this at runtime (i.e. get an error message) or have to do text searches. Hope this makes sense. Any feedback would be very much appreciated. Many thanks.
If I understand you correctly, you want to change a function's signature and find all functions/scripts/classes that call it in the "old" way, and change it to the "new" way.
You also indicated you don't want to do it at runtime, or do text searches, but there is no way to detect "incorrect" calls at "parse-time", so I'm afraid these demands leave no option at all to detect old function calls...
What I would do in that case is temporarily add a few lines to the new function:
function myFunc(param1, param2, newParam) % <-- the NEW signature
if nargin == 2
clc, error('old call detected.'); end
and then run the main script/function/whatever in which this function resides. You'll get one error for each time something calls the function incorrectly, along with the error stack in the Matlab command window.
It is then a matter of clicking on the link in the bottom of the error stack, correct the function call, and repeat from the top until no more errors occur.
Don't forget to remove these lines when you're done, or better, replace the word error with warning just to capture anything that was missed.
Better yet: if you're on linux, a text search would be a matter of
$ grep -l 'myFunc(.*,.*); *.m'
which will list all the files having the "incorrect" call. That's not too difficult I'd say...You can probably do a similar thing with the standard windows search, but I can't test that right now.
This is more or less what the dependency report was invented for. Using that tool, you can find what functions/scripts call your altered function. Then it is just a question of manually inspecting every occurrence.
However, I'd advise to make your changes to the function signature such that backwards compatibility is maintained. You can do so by specifying default values for new parameters and/or issuing a warning in those scenarios. That way, your code will run, and you will get run-time hints of deprecated code (which is more or less a necessary evil in interpreted/dynamic languages).
For many dynamic languages (and MATLAB specifically) it is generally impossible to fully inspect the code without the interpreter executing the code. Just imagine the following piece of code:
x = magic(10);
In general, you'd say that the magic function is called. However, magic could map to a totally different function. This could be done in ways that are invisible to a static analysis tool (such as the dependency report): e.g. eval('magic = 1:100;');.
The only way is to go through your whole code base, either inspecting every occurrence manually (which can be found easily with a text search) or by running a test that fully covers your code base.
edit:
There is however a way to access intermediate outputs of the MATLAB parser. This can be accessed using the undocumented and unsupported mtree function (which can be called like this: t = mtree(file, '-file'); for every file in your code base). Using the resulting structure you might be able to find calls with a certain amount of parameters.

Accessing variable by string name

I need to load experimental data into scicoslab, a (pretty badly designed) clone fork of scilab which happens to support graphical modeling. The documentation on the web is pretty poor, but it's reasonably similar to scilab and octave.
The data I need to process is contained into a certain number of text files: Data_005, Data_010, …, Data_100. Each of them can be loaded using the -ascii flag for the loadmatfile command.
The problem comes from the fact that loadmatfile("foo", "-ascii") loads the file foo.mat into a variable named foo. In order to to cycle on the data files, I would need to do something like:
for i = [5:5:100]
name = sprintf("Data_%02d", i);
loadmatfile(name, "-ascii");
x = read_var_from_name(name);
do_something(x);
end
where what I search for is a builtin read_var_from_name which would allow me to access the internal symbol table by string.
Do you know if there exist a similar function?
Notes:
There's no way of overriding this behavior if your file is in ascii format;
In this phase I could also use octave (no graphical modelling is involved), although it behaves in the same way.
>> foo = 3.14; name = 'foo'; eval(name)
foo =
3.1400
The above works in MATLAB, and Scilab's documentation says it also has an eval function. Not sure if I understood you correctly, though.
#arne.b has a good answer.
In your case you can also do that in matlab:
a=load('filename.mat')
x=a.('variable_name')
lets go through your points one by one:
"ScicosLab, a (pretty badly designed) clone of Scilab" This in my opinion is an inaccurate way of introducing the software. ScicosLab is not a clone of Scilab but a fork of it. The team behind ScicosLab (INRIA) are the ones who made scocos (now called xcos in Scilab development line). At some point (from Scilab v4) the Scilab team decided to move away from Tcl/tk towards Java, but the SciccosLab/scicos team departed, keep using the language (Tcl) and it's graphical user interface design package (tk). Giving the ScocosLab community the credit that the whole Scilab documentation and support is not very good in general. :) (more about Scilab and the forks here)
Regarding the technical question I'm not sure what you are trying to achieve here, Scilab/ScicosLab still have the eval function which basically does what you want. However this function is to be deprecated in favor of evstr. There is also the execstr function which worth studying.
The loadmatfile, as far as I have understood, "tries" to load the variables defined in a MATLAB .mat file (MATLAB's proprietary tabular format) into the Scilab workspace. For example if there is a variable foo it will "try" to create the variable foo and loads its value from the MATLAB script. Check this example. I would create a variable x(i) = foo in the for loop. again your question is not completely clear.
As a side note maybe you could consider exporting your data as CSV instead of .mat files.

how a function change in a loop with newtonsys command matlab

i want to change function variable at each step in a for loop in matlab.
i take these steps:
i created my mfile function
function [jfun,fun]=air(x,vt,ty,tz,p2,y0)
jfun=[(cos(tz)*cos(ty)*vt/9.81)*(1-exp(-9.81*x(2)/vt)),...
x(1)*cos(tz)*cos(ty)*exp(-9.81*x(1)/vt);
(-vt*sin(tz)*cos(ty)/9.81)*exp(-9.81*x(1)/vt),...
(x(1)*sin(tz)*cos(ty)*+vt)*exp(-9.81*x(1)/vt)];
fun=[(x(1)*cos(ty)*cos(tz)*vt/9.81)*(1-exp(-9.81*x(2)/vt))-p2;...
(vt/9.81)*(x(1)*sin(tz)*cos(ty)+vt)*(1-exp(-9.81*x(2)/vt))-vt*x(2)+y0];
end
and then i used newtonSys command:
ty=rad(-23)
tz=rad(15)
p2=1.8
vt=8.4925
y0=0.2
myfun=#(x)air(x,vt,ty,tz,p2,y0)
x=newtonSys(myfun,[15 5],0.000001,0.000001,500,1)
and matlab answer:
Error in ==> Untitled18 at 7
x=newtonSys(myfun,[15 5],0.000001,0.000001,500,1)
i guess that its because of wrong use of function handle and for my function i have to use another command or i have to use another method for solving 2nonlinear equation.
First, you haven't displayed the entire error. MATLAB should tell you what the actual error is, so unless you tell us that, we won't know what's wrong.
Secondly I don't see newtonSys in my system, or in the online MATLAB documentation. So most likely it is an external program, which most people here might not be familiar with. The closest I found from a quick Google search was this, which is an implementation of Newton's method for approximating the root of a non-linear system of n-equations. Are you using the same file? If so, if you look at the comments, it says that you need to pass the function as a string. So you'd have to pass myfun as 'myfun'.
If not, could you edit your question and add the contents of the function that you're using? Without these, it's near impossible to answer your question.