table() has been a standard function in MATLAB since R2013b. As far as I can see from the documentation, there's nothing special about table, compared to sum, cell, struct, or any other builtin function.
However, when I try to run the function using builtin('table',var1,...varN) I get an error saying:
Error using builtin
Cannot find builtin function 'table'
Investigating this further shows that it is in fact not considered a builtin function:
which('cell')
built-in (C:\Program Files\MATLAB\R2014b\toolbox\matlab\datatypes\cell)
which('table')
C:\Program Files\MATLAB\R2014b\toolbox\matlab\datatypes\#table\table.m % table constructor
|
Not builtin
Investigating further:
which cell2mat
C:\Program Files\MATLAB\R2014b\toolbox\matlab\datatypes\cell2mat.m
which mat2cell
C:\Program Files\MATLAB\R2014b\toolbox\matlab\datatypes\mat2cell.m
which table2array
C:\Program Files\MATLAB\R2014b\toolbox\matlab\datatypes\table2array.m
which struct2cell
built-in (C:\Program Files\MATLAB\R2014b\toolbox\matlab\datatypes\#struct\struct2cell) % struct method
which cell2struct
built-in (C:\Program Files\MATLAB\R2014b\toolbox\matlab\datatypes\#cell\cell2struct) % cell method
So, cell is builtin while table is not. cell2struct is builtin while cell2mat is not.
Why is this, and is there a simple way to call overloaded standard functions that aren't considered builtin by MATLAB?
If you think the why part is "too broad", please disregard it and jump to the last part of the question.
You can find the native function(s) by something like:
allTables = which ( '-all', 'table' )
allTables(cell2mat(strfind ( allTables, matlabroot )))
Its not fullproof and for some functions (e.g. sum) there are a lot in the root folders...
The documentation page for builtin gives a clear definition:
A built-in function is part of the MATLAB executable. MATLAB does not implement these functions in the MATLAB language. Although most built-in functions have a .m file associated with them, this file only supplies documentation for the function.
Related
I am writing a (rather big) pure function, which shall accept numeric and symbolic input. The problem I am facing is (mostly) with conversion symbolic expressions to logical expression. E.g., When I have a expression like syms x; assume( x, 'positive' ); and a test if( x>0 ); ..., then Matlab throws an error; Either:
Conversion to logical from sym is not possible.
or
Unable to prove 'x > 0' literally. Use 'isAlways' to test the statement mathematically.
depending on the context.
Up to now I solved this problem by rewriting all my ifs to if( isAlways(x>0) ); ... and adding a function isAlways in a folder #double, so that Matlab uses this function when it encounters a double.
The downside of this approach is, that I would have to write a isAlways function for each other type too (single, int8, ... ) (and also functions simplify,...).
Another approach of mine was, to write a function isAlways in the global namespace, and call the builtin isAlways when I encounter a sym. But, isAlways does not seem to be a built in, since Matlab reports
>> builtin('isAlways',sym(1));
Error using builtin
Cannot find builtin function 'isAlways'
Do you have any ideas how to solve this problem in a more elegant way, or at least another way?
Edit: I don't want to change the code of my function much, in particular don't want to add checks like switch class(x); case sym; ... case double;...`, but add "functionality" to Matlab such that it works out of the box for most functions.
In Matlab version approx R2018 I ended up defined a function isAlways in a folder #double etc.
Unfortunately, the behaviour changed around Matlab R2020. Now it is not possible anymore in a reliable way to add functions to classes. Thus, I now define a function isAlways in the global namespace, which gets called for each type which does not have an overload.
This is not the perfect solution, but it works at least.
Somewhere between R2010b and R2018a, Matlab seems to have removed dos as a built-in function.
In R2010b:
>> which dos
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\general\dos)
In R2018a:
>> which dos
C:\Program Files\MATLAB\R2018a\toolbox\matlab\general\dos.m
Why, and when, was this change made?
If you open the file dos.m you can notice that is a wrapper to the built-in function
system so the answar might be that MathWorks has improved the system function to run correctly both Windows command and Unix command so a built-in function for a wrapper is useless due the definition of built-in function:
A built-in function is part of the MATLAB executable. MATLAB does not implement these functions in the MATLAB language. Although most built-in functions have a .m file associated with them, this file only supplies documentation for the function.
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 would like to optimize a function written in Matlab by converting the code to C\C++. The result should be callable from within matlab, as it is a small part of a larger matlab code.
For example, converting my function to C code wrapped in a .mex file would work.
I heard matlab coder package can help with that.
As I am unfamiliar with this package, what is the quickest way to achieve this?
If you have a license for MATLAB Coder, then, yes, that is the correct package to use. The function you're looking for is codegen. There are restrictions on what can be used in code generation: to see if your function meets those restrictions, add the tag %#codegen to the beginning of your function as shown below
function foo(bar) %#codegen
<your code here>
and open the function file in the MATLAB editor. The tag tells the editor to check that the code complies with the rules for code generation. Once the editor shows that your code complies with those rules, generating the mex file may be as easy as
>> codegen foo
which would generate a mex-file, foo_mex in the current folder. For your particular function you may need to use some of the optional arguments for codegen to generate the mex-file properly.
i have a problem to using a dll fortran in matlab.
i couldn't use a dll ,that is built by fortran, in matlab. i use "loadlibrary" instruction in matlab but the error is related to header files.
what is header files??
please give me more information to load a dll fortran in matlab and call it.
Rather than try to use a dll file directly I suggest you re-build it using Matlab's MEX functionality. Yes, a mex file is a dll and you can build dlls outside Matlab and use them successfully, it's a lot easier, for a beginner such as I guess you to be, to use MEX. One way in which it is easier is that, if you build a mex file, the system won't ask you for a header file which is, as you know, a rather foreign concept to a Fortran programmer. Another way in which MEX will make your life easier is that you can then call the function exposed by the dll directly from Matlab's command line, without loadlibrary.
Study the Matlab documentation on MEX files, pay particular attention to how to integrate Fortran this way.
Without seeing your header file and the command line you're using in MATLAB, it's hard to help you too much here. You might reference the documentation in MATLAB which request that you pass two arguments to loadlibrary, the second being the header file with function signatures. I am guessing you are not providing this second argument.
You need to provide a header file that defines each of the named functions in the Fortran DLL that you'll be calling. For instance, if your DLL contains a function named sum that sums two double precision variables, like:
function sum(a,b) result(sum)
real(kind=2), intent(in) :: a, b
real(kind=2) :: sum
sum = a + b
end function
Then your header will need to contain something like:
double sum(double*a, double*b);
But don't forget to decorate this with the name mangling specific to your Fortran compiler. For instance, if sum was in a module named foo, and you compiled with gfortran, then you will need something like:
double __foo_MOD_sum(double*a, double*b);
There are a lot of other cases, but that's the gist of it.