Suppose i have a lot of source files, i want to organize them in folders-tree structure.
Is it possible for me to have several files with same name and use every of them from place i need or i must have all functions and classes with different names?
In C++ i have #include to introduce functions i need, that's here?
Just to illustrate:
.\main.m
.\Algorithms\QR\Factory.m % function Factory
.\Algorithms\QR\Algorithm.m % function Algorithm
.\Algorithms\SVD\Factory.m % function Factory
.\Algorithms\SVD\Algorithm.m % function Algorithm
MATLAB has support for namespaces. So in your example you would create the following:
C:\some\path\main.m
C:\some\path\+algorithms\+qr\factor.m
C:\some\path\+algorithms\+svd\factor.m
(Note: Only the top-level package folder's parent folder must be on the MATLAB path, i.e: addpath('C:\some\path'))
Then you could invoke each using its fully qualified name:
>> y = algorithms.qr.factor(x)
>> y = algorithms.svd.factor(x)
You could also import the package inside some scope. For example:
function y = main(x)
import algorithms.svd.*;
y = factor(x)
end
To understand the problem I need to explain some difference between the relation of c++ source and header files, and to .m files.
First: In matlab, you can only run the function which is defined highest up in the .m file. This file defines the top of the hierarchy. Then subfunctions can be implemented in the same m file, but these can only be used inside the same .m file.
Secondly: In addition to this matlab searched the include path for a specific filename and assume that the function inside the file will have the same name. You will notice this by a warning if you define the function with another name than the filename. The thing here is that you cannot have 2 matlab functions with the same name if all functions are global. This would be the same as if you would have 2 functions with the same name and in the same namespace in c++.
Note: The include path in matlab can typically be done with a hardcoded file in the to folder of your program. This function uses the matlab funcion addpath.
This is a fundamental difference to c/c++ where multiple functions are allowed to be defined in the same source file. Then the header file select what source code that you implement in the program, by providing the function definitions. The important thing here is that the header is completely disconnected from the function names, which they are not in matlab. This means that the analogy in your examples is not exactly accurate. The proposed thing by you is to "include" 2 functions with the same name. This is not possible either c/c++ (assuming the functions uses the same namespace or ar global) or in matlab.
Example: If the headers topFolder/foo/bar.h and topFolder/baz/bar.h would both contain the function void myDup(int a) and both headers uses the same namespace (or are global), then that would generate an error.
However, if the functions are only used by a limited number of other functions, then a function, eg. Factory.m, could be included as private functions in different folders. That would also mean that only this folder can access it. It is also possible to use matlab namespace as said in Amro's answer.
Related
I was trying to create a DataMatrix variable by calling the DataMatrix() function.
But that function doesn't exist. If I type this:
>> DataMatrix
I got this error message:
Undefined function or variable 'DataMatrix'.
I did install the Bioinformatics Toolbox and my version is 2016b on Mac
Any ideas?
As #Andras mentioned in the comments, the procedure to import and use this class is already mentioned in the documentation for the class (though you might be forgiven if you missed it, as it's not on the top part of the page dealing with syntax).
The tl;dr version is that you should either access the class constructor as, e.g.:
D = bioma.data.DataMatrix(...);
or, import the class from the package / namespace first, and then use it directly, i.e.:
import bioma.data.DataMatrix;
D = DataMatrix(...);
Explanation
The reason you need this step in the first place, is because this class is enclosed inside a "package" (a.k.a. a "namespace"). Read the section called "Packages Create Namespaces" in the matlab documentation to find out more what this means.
However, in principle it boils down to the fact that, if you have a folder whose name has a + prefix, then this acts as a namespace for the functions contained within.
So, if you have a folder called +MyPackage on your path, and this contains a function m-file called myfunction.m (but this is not in your path), then you can access this function in the matlab terminal by typing MyPackage.myfunction().
Or, you can import MyPackage.myfunction from that package / namespace and then use myfunction directly.
So, going back to DataMatrix, you will see that if you search where the class definition is located in your matlab folder, you'll find it here:
./toolbox/bioinfo/microarray/+bioma/+data/#DataMatrix/DataMatrix.m
and presumably ./toolbox/bioinfo/microarray is already in your path.
I.e. the bioma package/namespace is in your path, and you can access the data package/namespace below it, and then the class definition for DataMatrix by doing bioma.data.DataMatrix.
PS: Furthermore, the "#" prefix in front of a folder name denotes a class folder, containing the constructor and class methods. If this "#folder" is in your path (or imported etc), then this means you have access to the underlying constructor. This is a remnant from matlab's old object-oriented style, before the classdef keyword was introduced. You can read more about class directories here if you're interested.
As a follow up to my previous question, I run into a new obstacle: how to generate stubs for functions in a toolbox?
I found Andy Campbell's solution for the non toolbox case. This does not work in my case because Matlab complains: package directories are not allowed in MATLAB path in Pathfixtures!
I also don't see how this concept will overwrite the import statements within the toolbox, e.g. in file2.
This is my setup:
+folder1/file1.m
+folder1/runtestsuite.m
+folder1/unittest_data/file1_testdata.mat
+folder1/+folder2/file2.m
+folder1/+folder2/unittest_data/overloads/file1.m
...
Let's say I want to stub file1 in file2. And file2 has as a first statement: import folder1.file1.
With
methods(Access=private)
function inject_file1_stub(testCase, answer)
import matlab.unittest.fixtures.PathFixture;
testCase.applyFixture(PathFixture(fullfile(testCase.path,'overloads')));
file1('', answer);
end
end
So currently I believe this concept is not applicable in my case, so how is this done correctly with matlab?
I know one can shadow an implementation of a function in a toolbox, if one adds another path with the same toolboxname and function to the path. For this I would have to recreate a subset of the current folder setup:
So my current idea for a fixture is
create temporary folder with tempdir
use mfilename to check what subset of the toolbox directories I have to recreate
generate folder structure
copy from the overload folder to the new toolbox system
Add this to path
Run tests
In teardown
remove the temporary folder
remove the entry from path
I have not implemented this yet, and seems a bit redundant knowing that there is a Pathfixture in matlab already.
Pointers to other toolboxes which show how they have solved these kind of problems are also welcome.
It is true that you can't add subfolders of packages to the path, but that doesn't mean you can't shadow these path functions. To do this you need to separate the test related content out of your source location. For example, if your source looks like:
<source-home>/+folder1/file1.m
<source-home>/+folder1/+folder2/file2.m
Then you can put your tests somewhere else so your structure would look something like:
<test-home>/file1Test.m
<test-home>/file2Test.m % could also put tests into packages if you want
<test-home>/overloads/+folder1/file1.m
<test-home>/overloads/+folder1/+folder2/file2.m
Then inside of file1Test and/or file2Test you would use a PathFixture to add:
<test-home>/overloads/
to the path.
Also, another thing to consider is defining an interface in your source code for these dependencies and leveraging dependency injection (with or without a DI framework) in order to get test specific behavior into your tests.
I am having a problem with the findpeaks function, this function is in the signal processing toolbox and also the program has another version of it (user defined function). I need to call the on in the signal processing toolbox not the user defined one, also I can't rename the user defined function for many reasons. Can anyone help me in calling the toolbox function.
The precedence order used by MATLAB is described in their help pages. It states that functions in the current folder (9.) are preferred over functions elsewhere in the path (10.). Then, the first appearance of the function in the path is chosen. This allows for a number of possible solutions:
1. cd to folder
A very simple method is simply to change the current workspace directory to the folder of the function you need to call, i.e. cd either to the place where your user-defined function is, or cd to the toolbox path. Note: This is rather inelegant, but probably sometimes the simplest solution.
2. Reorder path
As mentioned, MATLAB choses the first occurence of the function in the path. You can thus re-sort the path variable, so the folder where your user-defined function is, appears last. The path variable can be viewed and manipulated using the path function. Note: Then you can only call the toolbox function. Otherwise you'd have to resort the path again.
3. Function handles
If you need to be able to call both functions, it can be useful to create a function handle for both versions. For that, you have to cd into the folders where the functions are defined and create a new handle there:
cd('path/to/userdefined/function')
userFindPeaks = #findpeaks;
cd('path/to/MATLAB/installation/toolbox/signal/signal')
toolboxFindPeaks = #findpeaks;
You can then call the functions using feval.
Of course, as Adriaan mentions in the comments, it is best not to use the names of already defined functions for your own functions or for variable names.
I just came here looking for the same thing... I ended up using builtin.
https://uk.mathworks.com/help/matlab/ref/builtin.html
[y1,...,yn] = builtin(function,x1,...,xn)
#arr_sea actually posted a link in one of the folded comments which uses this function in a different context.
Let's say I have some MATLAB code that uses some functions.
I don't want to define the functions in the same file as the code that uses
the functions.
On the other hand, the solution of making an m file for each function is also not good for me because I don't want a lot of files.
What I want is something like a utils file that holds those functions, from which I can import the functions like we do in python, for example.
What would you recommend?
What you probably want is to use a package, which is kind of like a python module in that it is a folder that can hold multiple files. You do this by putting a + at the beginning of the folder name, like +mypackage. You can then access the functions and classes in the folder using package.function notation similar to Python without it polluting the global list of functions (only the package is added to the global list, rather than every function in it). You can also import individual functions or classes. However, you always have to use the full function path, there is no such thing as relative paths like in Python.
However, if you really want multiple functions per file, probably the best you can do is create a top-level function that returns a struct of function handles for the other functions in the file, and then access the function handles from that struct. Since MATLAB doesn't require the use of () with functions that don't require any inputs, this would superficially behave similarly to a python module (although I don't know how it will affect performance).
I know this is a pain in the neck. There is no reason mathworks couldn't allow using files as packages like they currently do for folders, such as by putting + at the beginning of the file name. But they don't.
A solution close to what you are looking for could be the use of classes. A class contains methods that can be public (visible from outside) or private (only visible from inside). Implementations of the methods of a class can be either in multiple files or in the same file.
Here is a simplistic example
classdef Class1
methods (Static)
function Hello
disp('hello');
end
function x = Add(a,b)
x = Class1.AddInternal(a,b);
end
end
methods (Static, Access=private)
function x = AddInternal(a,b)
x = a+ b;
end
end
end
Example of use-:
>> Class1.Hello
hello
>> Class1.Add(1,2)
ans =
3
>> Class1.AddInternal(2,3)
Error using Class1.AddInternal
Cannot access method 'AddInternal' in class 'Class1'.
gpuArray is a function used to create array on GPU in matlab. Here I don't always want to use the gpuArray, so I write a function called gpuArray (below) to return a normal matrix when necessary, so I don't need to change the code much. I have already added this function to the path. But when I call the gpuArray function, it still return a gpuArray.....does anyone know why....thanks a lot!
function A = gpuArray(A)
This is....not the best idea. Having multiple functions with the same name will end up leading to quite a bit of ambiguity that a search + replace on your code to an alternate function with a unique name won't cause. But if you insist on doing this, then you need to be conscious of how MATLAB searches for functions. The order is (from http://au.mathworks.com/help/matlab/matlab_prog/function-precedence-order.html):
Imported package functions
Nested functions within the current function
Local functions within the current file
Private functions
Object functions
Class constructors in # folders
Functions in the current folder
Functions elsewhere on the path, in order of appearance
So to make sure your function takes precedence over the built-in function it needs to be higher on that list. You can include your function as a sub-function in the current file (#2 or #3), a private function (#4), create a class and use those functions (#5 and 6), put your function in the same folder as the code invoking it (#7) or ensure that your function is in a folder higher up in the search path than the built-in function (#8). I suspect that your \Documents\MATLAB folder or whichever your gpuArray function is in is actually lower in your folder path than the built-in function so #8 above fails. You can move the place of that folder in your search path or, a better idea, change the name of your function to something unique and change the code that calls it.
You should always be able to type "which gpuArray" to find out which "gpuArray" that Matlab will invoke. I'm assuming that it will not point to yours.
To try to get Matlab to use your gpuArray, you should try adding the path to your function to the Matlab path. Try something like:
%add the path to *my* gpuArray function
addpath('C:\MyDirectory\SomeOtherDirectory\MyMfiles\');
Good luck!