Matlab: track all file handles that were opened/touched by script - matlab

I want to find all dependencies of my script (and/or all subfunctions/subscripts), but not only functions that are called but also external files that are loaded or touched (fopen). matlab.codetools.requiredFilesAndProducts (documentation here) doesn't capture the touched filenames, my next idea, shadow the fopen function using something like below (to copy the filename to a log file), resulted in an unexpected recursive loop.
failed because of (unexpected) recursive loop, where somehow the 'builtin' fopen is not called, rather this function itself:
function varargout=fopen(varargin)
%write opened filename to log file somewhere
varargout=builtin('fopen',varargin{:}); %attempt to call built-in fopen() as usual
end
I also checked Mathworks depencey reports etc, to no use. Any ideas? Thank you.

Related

Variable output to workspace with correct function call in command window-fixed- [duplicate]

How can I create a function with MATLAB so I can call it any where in my code?
I'm new to MATLAB so I will write a PHP example of the code I want to write in MATLAB!
Function newmatlab(n){
n=n+1;
return n;
}
array=array('1','2','3','4');
foreach($array as $x){
$result[]=newmatlab($x);
}
print_f($result);
So in nutshell, I need to loop an array and apply a function to each item in this array.
Can some one show me the above function written in MATLAB so I can understand better?
Note: I need this because I wrote a code that analyzes a video file and then plots data on a graph. I then and save this graph into Excel and jpg. My problem is that I have more than 200 video to analyze, so I need to automate this code to loop inside folders and analyze each *.avi file inside and etc.
As others have said, the documentation covers this pretty thoroughly, but perhaps we can help you understand.
There are a handful of ways that you can define functions in Matlab, but probably the most useful for you to get started is to define one in an m-file. I'll use your example code. You can do this by creating a file called newmatlab.m in your project's directory that looks something like this
% newmatlab.m
function result = newmatlab(array)
result = array + 1
Note that the function has the same name as the file and that there is no explicit return statement - it figures that out by what you've named the output parameter(s) (result in this case).
Then, in the same directory, you can create a script (or another function) that calls your newmatlab function by that name:
% main.m (or whatever)
a = [1 2 3 4];
b = newmatlab(a)
That's it! This is a simplified explanation, but hopefully enough to get you started and then the documentation can help more.
PS: There's no "include" in Matlab; any functions that are defined in m-files in the current path are visible. You can find out what's in the path by using the path command. Roughly, it's going to consist of
Matlab's own directory
The MATLAB subdirectory of your Documents directory
The current working directory

Save workspace of unknown workspace in Matlab

Is it possible to save workspace variables from a function that I am calling and cannot explicitly edit without file I/O?
I know I can use the save function to save all of the variable names in a workspace, but what if I wanted to save the workspace variables from a function that I am calling, like a built in function (mean, sum, etc).
I would like to save all of the variables from a function's workspace before it returns back to the function I am writing, and I would like to do it without opening the file each time and adding an extra line of code; is this possible?
In case anyone is interested:
I have yet to find a solution to the exact question I asked, but I found a solution that works well enough with a little extra file tracking.
Using the function onCleanup, you can specify that all the variables be saved right before the function returns to the caller. Using this and a little file parsing, you can open the code in question as a simple text file, and insert the onCleanup code anywhere in the file (easier than inserting save as the last line). Then, you can run the code and track the new .mat file using the previous file name or any naming method you choose.
That will enable you to save all the variables in a workspace just before the function exits, but it does require file parsing, see simple example below:
readFile = fopen('filename.m');
writeFile = fopen(['filename_new.m']);
%Ignore the first line (hopefully the function header, may need extra parsing if not)
functionHeader = fgets(readFile);
%Print the function header
fprintf(writeFile,functionHeader);
%Print the clean-up code
%NOTE: This can go anywhere in the file
fprintf(writeFile,sprintf('onCleanup(#()save(''%s.mat''))\n',filename)));
nextLine = fgets(readFile);
while ischar(nextLine)
fprintf(writeFile,nextLine);
nextLine = fgets(readFile);
end
With the above, a new file is created (filename_new.m) which needs to be run, and will create a mat file (filename.mat) with all of the workspace variables in it.
eval(newFileName(1:end-2));
Now, by tracking the .mat file, you can do whatever is necessary after this point. For my purposes, I was interested in the memory used by the said function, which is available by accessing the mat object of the .mat file.
matObj = matfile('filename.mat');
stats = whos(matObj);
fileSize = sum([stats.bytes]);
Try the "save" function.
Add this line in your called function:
save('filename')
Here is my sample code:
a=10; b=6;
c=addition(a,b);
And the function is defined as:
function [out]=addition(a,b)
out=a+b;
temp1=a;
temp2=b;
temp3=a-b;
save('C:\data.mat');
end

Can't close text file because MATLAB uses it after failed execution

I call a function (containing fopen and fclose) from the Command Window and then after MATLAB encounters an error that I fix (the runtime of the program stops after I save my corrections), I want to delete the file it created, in order to repeat the process. However, MATLAB, somehow, still has the file open and typing in fclose(f), in the Command Window does not make MATLAB let go of the file.
function something(something)
f = fopen('something.txt', 'w');
%statments with fprintf
fclose(f);
end
You may not have access to the handle f from outside the function, in which case you can try fclose('all') from the Matlab command window.
Generally it is best practice to use a try .. catch ... statement around code that uses a file, so that you always call fclose and release the handle if an error occurs.
If you are still unable to delete the file, and assuming it is not locked by another process (for example if you are viewing it externally in Windows Notepad), it may be that you are calling library functions from Matlab and that the shared library maintains the file lock. In this case, try reloading the library using the unloadlibrary and loadlibrary commands.
Using an onCleanup object can be very useful in this case.
Here's your code rewritten to use onCleanup - the fclose will now get called when the function terminates whether normally, or because of an error.
function something(something)
f = fopen('something.txt', 'w');
closer = onCleanup( #()fclose(f) );
% statements with fprintf
end
The documentation also includes an example for exactly this case.

Executing a file or calling a function whose file is placed in another folder with MATLAB?

Tried Googling, but couldn't find anything.
I have a few files and folders in my current MATLAB folder.
One of those folders is called 'Map' and it has a 'map1.m' file which I want to call from my code in the current MATLAB folder.
In my code, I can't call it like this:
/Map/map1;
but I can do so like this:
cd Map;
map1;
cd ..;
Somehow the above method seems incorrect. Is there a more elegant way to do it?
You can run the file without adding the folder to your path manually, using the run command, which is specifically for such cases. From the documentation:
run is a convenience function that runs scripts that are not currently on the path.
You call your function/script as
run /Map/map1
If you want to run the function/script by merely entering its name and not with the full (or relative) path, then you should add the folder to your path.
As noted by #mutzmatron, you cannot use run to call functions with input/output arguments. So, unless if it's a script/function without input/output arguments, using run will not work and you'll have to add the folder to your path.
EDIT
Just as a matter of good coding practice, and to work in cases where your function has inputs/outputs, adding/removing the folder from your path is the correct way to go. So for your case,
addpath /Map
...
map1;
...
rmpath /Map
The important thing is that your function call is sandwiched between the addpath and rmpath commands. If you have functions of the same name in both folders, then you should sandwich it tighter i.e., a line before and a line after, so as to avoid conflicts.
Just add all those directories to the Matlab path with addpath like gnovice suggests. Then you'll be able to call the functions normally, and they'll be visible to which(), help(), depfun(), and the other Matlab meta-programming commands. You can put the addpath() calls in your startup.m file to have them automatically appear each time you start Matlab.
Changing the path with addpath/map1()/rmpath each time has some drawbacks.
It's a performance hit because you're adding path manipulation to each call.
Functions in different directories won't be able to see each other.
It'll be harder to write and debug functions because the path context in which they execute will change dynamically, and won't be the same as what you see when you're in the editor and the base workspace.
You need additional error handling code to make sure the path is properly restored if the called function errors out.
This won't work with the Matlab Compiler, if you want to deploy this code at some point.
And using run() or cd() yourself is ugly, because relative paths are going to have problems.
If you really want to separate the functions in the subdirectories so they can't "see" each other, you can make those directories namespaces by putting a "+" in front of their names, and then qualify the function calls with the namespace, like Map.map1().
Just to contribute to the path-altering debate...
One way to make it a bit "safer" is to write
% start of my code: create function handles
% to the functions I need:
try
cd Map
map1_func = #map1;
catch mexception
end
cd ..
This tries to preserve the current directory, and you get a handle to the function in a different directory.
Only thing is, this method won't work if map1 relies upon other functions in the Map directory.

How to make matlab see functions defined in .m files?

I'm a total newbie to MATLAB but I have to write some code in it. I've had problems with making MATLAB see functions I've defined in external .m files. This is what I've done: I've created a file named, say, foo.m in my home dir with the following contents:
function [y] = foo(x)
% description
y = x + 1
When I run matlab (my home dir is matlab's workdir) it does not see foo function - it replies with standard ??? Undefined function or variable 'foo' message. BUT help foo or which foo return correct data printing help text and pointing on foo.m file respectively.
I must be missing something but I have no idea what it is. This is getting very annoying.
Oh, after several trial and error attempts I've managed to call that function. Unfortunately I can't remember the sequence of steps I've performed. Moreover after restarting matlab it returns to its usual 'Undefined function or variable' response.
I have 7.11.0.584 matlab running on linux.
MATLAB needs to be told which directories to search over to access those m-files. Clearly it cannot be left to search over your entire disk drives. The MATLAB search path is a list of directories that will be searched in specific order to find your functions.
help addpath
help pathtool
You should never put those files anywhere in the official MATLAB toolbox directories. Choose an entirely separate directory.
Finally, be careful not to name your own functions to match the names of existing MATLAB functions. Otherwise, your very next question here will be why your code does not work properly. This is a common cause of strange and confusing bugs.
It seems you're having some trouble with addpath. Try opening the file in the matlab editor and adding a break point in the file. If the file is not on Matlab's path, matlab should ask if you want to change directory or add the file to the path, choose add to the path.
If this doesn't work, try changing the current working directory (displayed in the main window) to the same location as the m file and calling the function. If this doesn't work you're either getting the name wrong ar there's possibly something wrong with your installation.
Occasionally matlab has problems if it does not have write permission to the directory the file's in, so check that too, i.e. make sure admin rights aren't required for the directory or m file.
Oh, and try:
clear functions
to reload all functions into memory.
The function needs to be in MATLAB's path. Use pathtool to tell MATLAB where to find your function. Note that if you name a function the same name as an existing function, MATLAB will use whichever function it finds first according to the order that the paths are listed as you see them in pathtool.
Although coming late but I hope it will help someone.
If in the folder where the function you are calling is residing, there is any other function with the same name as one of the functions from MATLAB toolboxes, then Matlab will not recognize its license and therefore will disable the whole folder from execution, no matter it is properly added to the path. The help will display though.
In order to check it, type:
which name_of_func.m
and you will get the path with "%Has no license available" message.
If it is your own function, you should not get this message but only the path.
Therefore, find the function in this folder which has the same name as a MATLAB toolbox functions, and rename it. I will solve the problem :).
Best Regards
Wajahat