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'.
Related
I have a script with lots of variables (10-30), and in a for loop I do some processing using basically every variable. I have a helper script so that the interior of the loop looks clean.
main script
a=2;b=5;c=8;d=10;%and many many more
for i=1:1000
helper;
end
I want to turn helper into a function, primarily because this would allow me to have the helper script (now a function) at the bottom of the main file. But I definitely do not want to individually pass every variable and every variable that I have yet to need in this project.
What I really need is a goto, but matlab doesnt have it.
There are many solutions to this. In rinkert's comment you've gotten the only one that is good coding practice: put the variables in a struct, then pass the struct into your function. I highly recommend that you do that. Using nested functions is not a terrible solution either, though it could be a lot more difficult to manage (variable visibility rules are funny in nested functions, I find it confusing at times).
Here I'm going to give you the worst possible solution: evalin. You should not do this, I post this here for educational purposes only.
evalin allows a function to retrieve a variable in the caller's workspace:
a=2;b=5;c=8;d=10;%and many many more
for i=1:1000
helper;
end
function helper
% NEVER DO THIS IN PRACTICE
a = evalin('caller','a');
b = evalin('caller','b');
c = evalin('caller','c');
d = evalin('caller','d');
% do computations....
assignin('caller','result',result);
end
Note that a function result = helper(a,b,c,d) is much more efficient and much easier to maintain because it's clear what is going on. evalin makes for surprising results, and assignin even more so. Do not use this.
There are a few legitimate uses of these functions. For example, I've written a GUI that allows a MATLAB user easier access to a set of functions, but is meant to work in conjunction with the interactive MATLAB command prompt. The GUI would fetch variables from the 'base' workspace, evaluate function calls in the 'base' workspace, and write new variables to the 'base' workspace. Running a function within the GUI is just like running it at the command prompt. There is no other way of accomplishing this other than using evalin and assignin.
although it's not good coding conduct, you could use global variables :
for example :
global a;
a= 5;
function out =test()
global a;
out=2*a;
end
I would like to have a list of constants readily available to use in any script or function I write. For example, I have been defining constants like hbar (Planck's constant) at the start of any script that will be using it.
Instead of that, should I:
make a list of constants in a script and load that script every time
I want to use it,
or save constants in a workspace and load that,
or is it possible for me to have global variables that will be there even when I close and reopen Octave,
or something else?
If you use GNU Octave I would suggest using the miscellaneous package and the function physical_constant which already has 335 constants. In your case:
[val, uncertainty, unit] = physical_constant ("Planck constant over 2 pi")
val = 1.0546e-34
uncertainty = 4.7000e-42
unit = J s
If you want don't want this, then use functions, not global vars.
As you indicated, there are a few ways to solve this problem. To address your third option, which seems to be closest to the spirit of what you want, you've got at least two ways of handling this.
1.) If the variables need to be mutable. Create a function or script that initializes the variables to what you want them to be. I'm going to reference the MATLAB documentation but it should basically be the same.
function initglobals()
global the_answer
the_answer = 42;
end
Then any time you want to use these globals in a script, you first indicate to Octave that you'll be using the variable as a global:
...
global the_answer
disp(the_answer) %prints 42
...
For this to be more useful, I'd recommend generating a startup script and putting in your .octaverc docs. This startup script can call this function to initialize your globals.
2.) Your other choice, if the globals ought to be immutable (for example, a physics constant) is to define a function that returns the value you want.
function [out] = the_answer()
out = 42;
end
Then you can simply just use the_answer to access your constant.
In both cases you'll want to add these functions to your path. Create your collections of functions and put them somewhere, then add that location to your path. docs
Suppose I have a smallish number of functions that I have defined in a cell in ijulia (I'm using JuliaBox).
I'd like to be able to call the main function in parallel n times. The annoyance is that the main makes calls to the dozen or so helper functions I have defined.
Do I have to put #everywhere in front of all of these helper functions, or is there some shorter syntax that would work?
e.g. is there a command that would share all functions defined at the global level to all of the processes? Or is there a way to share a list of functions (rather than putting #everywhere in the function declaration).
When I want to do this in the notebook I usually wrap the entire cell containing helper functions in #everywhere like this:
#everywhere begin
... put functions we want to share across all processes here
end
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.
What do I want?
I am looking for a way to detect all points in my code where a specific function is called.
Why do I want it?
Some examples:
Some output comes out sorted or randomized, and I want to know where this happens
I am considering to change/overload a function and want to know in which part of my code this could have impact
What have I tried?
I tried placing a breakpoint in the file that was called. This only works for non builtin functions which are called from short running code that always executes everything.
I tried 'find files', this way I can easily find direct calls to sort but it is not so easy to find a call to sort invoked by unique for example.
I have tried depfun, it tells me:
whether something will be called
from where non-builtin functions will be called
I thought of overloading the builtin function, but feels like a last resort for me as I am afraid to make a mess. | Edit: Also it probably won't help due to function precedence.
The question
What is the best way to track all potential (in)direct function calls from a specific function to a specific (built-in)function.
I don't exactly understand your use case, but I guess most of the information you want can be obtained using dbstack, which gives you the call-stack of all the parent functions calling a certain function. I think the easiest way is to overload built-in functions something like this (I tried to overload min):
function varargout = min(varargin)
% print info before function call
disp('Wrapped function called with inputs:')
disp(varargin)
[stack,I] = dbstack();
disp('Call stack:')
for i=1:length(stack)
fprintf('level %i: called from line %i in file %s\n', ...
i, stack(i).line, stack(i).file);
end
% call original function
[varargout{1:nargout}] = builtin('min', varargin{:});
% print info after function call
disp('Result of wrapped function:')
disp(varargout)
I tried to test this, but I could not make it work unfortunately, matlab keeps on using the original function, even after playing a lot with addpath. Not sure what I did wrong there, but I hope this gets you started ...
Built-in functions take precedence over functions in local folder or in path. There are two ways you can overload a built-in for direct calls from your own code. By putting your function in a private folder under the same directory where your other MATLAB functions are. This is easier if you are not already using private folder. You can rename your private folder once you are done investigating.
Another way is to use packages and importing them. You put all your override functions in a folder (e.g. +do_not_use). Then in the function where you suspect built-in calls are made add the line "import do_not_use.*;". This will make calls go to the functions in +do_not_use directory first. Once you are done checking you can use "clear import" to clear all imports. This is not easy to use if you have too many functions and do not know in which function you need to add import.
In addition to this, for each of the function you need to follow Bas Swinckels answer for the function body.
Function precedence order.
Those two methods does not work for indirect calls which are not from your own code. For indirect calls I can only think of one way where you create your own class based on built-in type. For example, if you work only on double precision types, you need to create your own class which inherits from double and override the methods you want to detect. Then pass this class as input to your code. Your code should work fine (assuming you are not using class(x) to decide code paths) since the new class should behave like a double data type. This option will not work if your output data is not created from your input data. See subclassing built-in types.
Did you try depfun?
The doc shows results similar to the ones you request.
doc depfun:
...
[list, builtins, classes, prob_files, prob_sym, eval_strings, called_from, java_classes] = depfun('fun') creates additional cell arrays or structure arrays containing information about any problems with the depfun search and about where the functions in list are invoked. The additional outputs are ...
Looks to me you could just filter the results for your function.
Though need to warn you - usually it takes forever to analyze code.