How to call an m file directly from another m file in MATLAB without add its folder path - matlab

How to call an m file from another m file in MATLAB without add its folder path?
I don't want to add its folder via
addpath(genpath(''))

Similar to the functionality of MATLAB's built-in run for scripts, you can cd into the secondary path, execute your function, and then return to the previous directory.
A small example:
% testcode.m
function [output] = testcode(fullfunctionpath, A, B)
[pathname, functionName] = fileparts(fullfunctionpath);
olddir = cd(pathname);
output = feval(functionName, A, B);
cd(olddir);
end
% .\test\testing.m
function [output] = testing(A, B)
output = A + B;
end
With the call:
C = testcode('C:\testcode-matlab\test\testing.m', 1, 2);
Will return
C =
3
Note that this approach does not have error handling nor does it check for duplicates that already exist in your path definition. If the called function is not present in the target folder but does exist in the path, the function in MATLAB's path will still be executed. See: Function Precedence Order for more information.

All visibility rules for functions are based on Folders. If you want to have different visibilities you have to place your functions in different folders.
Typically, avoiding duplicate function names and just adding all source files to your search path is what works. To avoid duplicate function names you may want to take a look at packages.

Related

How to perform processinng on .csv files used by my code for each person in one go without defining functions for each person in Matlab?

I have a main code named as process.m in which I define the path to 4 different .csv files for calculating values for each person. If I have a list of 30 persons and I don't want to define process.m as a function for each person, how can I do the processing for all the persons in one go. I want some idea by which process.m itself picks files for one person, then generate the results, then move to other person, pick his .csv files, generate the result and so on.
A breif outline of my code is attached here that would project the problem.
file1='Joseph_front.csv';
file2='Joseph_side.csv';
file3='Joseph_knee.csv';
file4='Joseph_back.csv';
A1=initiate2(file1); %initiate2 function reads the csv and perfoms some filtering operations on image in .csv format
A2=initiate2(file2);
A3=initiate2(file3);
A4=initiate2(file4);
%%omitted large part of code
cal(1) = p+q+r*s;
cal(2) = p+q+r+s;
cal(3) = p+q+r-s;
cal=cal'
%code to write the calculation in excel file
excelfile= 'test.xlsx';
xlswrite(excelfile,ValuesInInches,'Joseph_data',posColumn);
Describing more i want my code to process for 30 people all at once by selecting and picking the files itself, although i have done this operation by making the same code as a function for each person, but that is not very efficient as when I have to make a small change I have to make it in every function that means one change needs to be edited in 30 functions. Please suggest an efficient way to do it.
Note: All persons .csv files are named in the same manner and exist in the current folder.
I am assuming all of your files in one directory and there's no other files .
This portion of code will get the available filenames.
listFiles = dir('path of the directory');
filenames = strings; % an empty string array to save the filenames
j = 1;
for i = 1:1:length(listFiles)
if ~listFiles(i).isdir % to avoid the directory names
filenames(j,1) = listFiles(i).name;
j = j+1;
end
end
Now, there's 4 file for each person. So the loop should take 4 files at a time.
for ii = 1:4:length(filenames)
file1=filename(i);
file2=filename(i+1);
file3=filename(i+2);
file4=filename(i+3);
%% continue with your code
end

randomly move files from a folder to another folder?

I am trying to move my files and create a new folder to put those files there.
I have many .png files in my images folder in my MATLAB directory. I want to randomly choose 80% of them and move them to another folder called training folder in my matlab directory. Heres my code which is not working. it cant find the file to move :(
data_add = fullfile(cd,'images');
all_files = dir(data_add);
all_files = all_files(3:end);
num_files = numel(all_files);
image_order = randperm(num_files);
for k = 1:(image_order)*0.8
file_name = all_files(k).name;
file_add = all_files(k).folder;
file_to_move = fullfile('path_to_images\images',file_name);
mkdir training
movefile file_to_move training
end
A couple issues here:
Like Flynn comments, the call to mkdir training only needs to be made once, so you can place it before your loop.
You may be thinking about the variable image_order incorrectly when it comes to your for loop.
The call image_order = randperm(num_files); produces an array of randomly ordered indices from 1:num_files, which is helpful. However, the expression (image_order)*0.8 is actually multiplying each of these indices times 0.8, such that they are no longer valid, integer indices (aside from a few, like 8 which would become 1).
I think what you are attempting and wanting to do is this:
mkdir('training');
for k = 1:num_files*0.8
randK = image_order(k);
file_name = all_files(randK).name;
file_to_move = fullfile(data_add,file_name);
movefile(file_to_move, 'training'); % using function style
end
You may run into other issues next depending on where the folder training is located and where you are running your script from, but this should be closer to what you are to get, and at least locate the files for you.

stuck with my small code in matlab

I have problem with the following code:
.
.
.
a=zeros(1000,ctimes);
a1=zeros(1000,ctimes);
hold all
for i=num1:num2;
colors=Lines(i);
switch phantom
case 1
path=['E:\filename\'];
path1=['E:\filename2\'];
n=['S',num2str(emt),'_',num2str(i),'.m'];
d=load([path,name]);
a(:,i)=complex(d(:,2),d(:,3)));
n1=['S',num2str(emt),'_',num2str(i),'.m'];
d1=load([path1,name1]);
a1(:,i)=complex(d1(:,2),d1(:,3)));
the problem is that a(:,i) can not be defined. while there is no problem or with complex(d1(:,2),d1(:,3))) , can any expert body help me plz?!
thank you ...
Are you sure you are forming your file name correctly? You are doing something to create a variable n, but using a variable name when you form the path. Here are some recommended debugging steps:
1) make sure the file path is formed correctly:
filePath = fullfile(path, name);
disp(filePath);
The fullfile function concatenates elements of a file path & name, and takes care of using the right file path separator (good for portable code, stops you having to remember to add a / or \ to the end of a file path, etc).
2) check that d is loaded correctly:
clear d;
d = load(filePath);
disp(size(d));
3) check the size of the complex quantity you compute before assigning it to a(:,i):
temp = complex(d(:,2), d(:,3));
disp(size(temp));
By the time you have done these things, you should have found your problem (the dimensions of temp should be [1000 1] to match the size of a(:,i), of course).
As an aside, you should avoid using i as a variable name, especially when you are using complex numbers, since its built-in value is sqrt(-1). Thus, c = a + i * b; would create a complex number (a,b) and put it into c - until you change the meaning of i. A simple solution is to use ii. The same is true for j, by the way. It is one of the unfortunate design decisions in Matlab that you can overwrite built in values like that...

Call graph generation from matlab src code

I am trying to create a function call graph for around 500 matlab src files. I am unable to find any tools which could help me do the same for multiple src files.
Is anyone familiar with any tools or plugins?
In case any such tools are not available, any suggestions on reading 6000 lines of matlab code
without documentation is welcome.
Let me suggest M2HTML, a tool to automatically generate HTML documentation of your MATLAB m-files. Among its feature list:
Finds dependencies between functions and generates a dependency graph (using the dot tool of GraphViz)
Automatic cross-referencing of functions and subfunctions with their definition in the source code
Check out this demo page to see an example of the output of this tool.
I recommend looking into using the depfun function to construct a call graph. See http://www.mathworks.com/help/techdoc/ref/depfun.html for more information.
In particular, I've found that calling depfun with the '-toponly' argument, then iterating over the results, is an excellent way to construct a call graph by hand. Unfortunately, I no longer have access to any of the code that I've written using this.
I take it you mean you want to see exactly how your code is running - what functions call what subfunctions, when, and how long those run for?
Take a look at the MATLAB Code Profiler. Execute your code as follows:
>> profile on -history; MyCode; profile viewer
>> p = profile('info');
p contains the function history, From that same help page I linked above:
The history data describes the sequence of functions entered and exited during execution. The profile command returns history data in the FunctionHistory field of the structure it returns. The history data is a 2-by-n array. The first row contains Boolean values, where 0 means entrance into a function and 1 means exit from a function. The second row identifies the function being entered or exited by its index in the FunctionTable field. This example [below] reads the history data and displays it in the MATLAB Command Window.
profile on -history
plot(magic(4));
p = profile('info');
for n = 1:size(p.FunctionHistory,2)
if p.FunctionHistory(1,n)==0
str = 'entering function: ';
else
str = 'exiting function: ';
end
disp([str p.FunctionTable(p.FunctionHistory(2,n)).FunctionName])
end
You don't necessarily need to display the entrance and exit calls like the above example; just looking at p.FunctionTable and p.FunctionHistory will suffice to show when code enters and exits functions.
There are already a lot of answers to this question.
However, because I liked the question, and I love to procrastinate, here is my take at answering this (It is close to the approach presented by Dang Khoa, but different enough to be posted, in my opinion):
The idea is to run the profile function, along with a digraph to represent the data.
profile on
Main % Code to be analized
p = profile('info');
Now p is a structure. In particular, it contains the field FunctionTable, which is a structure array, where each structure contains information about one of the calls during the execution of Main.m. To keep only the functions, we will have to check, for each element in FunctionTable, if it is a function, i.e. if p.FunctionTable(ii).Type is 'M-function'
In order to represent the information, let's use a MATLAB's digraph object:
N = numel(p.FunctionTable);
G = digraph;
G = addnode(G,N);
nlabels = {};
for ii = 1:N
Children = p.FunctionTable(ii).Children;
if ~isempty(Children)
for jj = 1:numel(Children)
G = addedge(G,ii,Children(jj).Index);
end
end
end
Count = 1;
for ii=1:N
if ~strcmp(p.FunctionTable(ii).Type,'M-function') % Keep only the functions
G = rmnode(G,Count);
else
Nchars = min(length(p.FunctionTable(ii).FunctionName),10);
nlabels{Count} = p.FunctionTable(ii).FunctionName(1:Nchars);
Count = Count + 1;
end
end
plot(G,'NodeLabel',nlabels,'layout','layered')
G is a directed graph, where node #i refers to the i-th element in the structure array p.FunctionTable where an edge connects node #i to node #j if the function represented by node #i is a parent to the one represented by node #j.
The plot is pretty ugly when applied to my big program but it might be nicer for smaller functions:
Zooming in on a subpart of the graph:
I agree with the m2html answer, I just wanted to say the following the example from the m2html/mdot documentation is good:
mdot('m2html.mat','m2html.dot');
!dot -Tps m2html.dot -o m2html.ps
!neato -Tps m2html.dot -o m2html.ps
But I had better luck with exporting to pdf:
mdot('m2html.mat','m2html.dot');
!dot -Tpdf m2html.dot -o m2html.pdf
Also, before you try the above commands you must issue something like the following:
m2html('mfiles','..\some\dir\with\code\','htmldir','doc_dir','graph','on')
I found the m2html very helpful (in combination with the Graphviz software). However, in my case I wanted to create documentation of a program included in a folder but ignoring some subfolders and .m files. I found that, by adding to the m2html call the "ignoreddir" flag, one can make the program ignore some subfolders. However, I didn't find an analogue flag for ignoring .m files (neither does the "ignoreddir" flag do the job). As a workaround, adding the following line after line 1306 in the m2html.m file allows for using the "ignoreddir" flag for ignoring .m files as well:
d = {d{~ismember(d,{ignoredDir{:}})}};
So, for instance, for generating html documentation of a program included in folder "program_folder" but ignoring "subfolder_1" subfolder and "test.m" file, one should execute something like this:
m2html( 'mfiles', 'program_folder', ... % set program folder
'save', 'on', ... % provide the m2html.mat
'htmldir', './doc', ... % set doc folder
'graph', 'on', ... % produce the graph.dot file to be used for the visualization, for example, as a flux/block diagram
'recursive', 'on', ... % consider also all the subfolders inside the program folders
'global', 'on', ... % link also calls between functions in different folders, i.e., do not link only the calls for the functions which are in the same folder
'ignoreddir', { 'subfolder_1' 'test.m' } ); % ignore the following folders/files
Please note that all subfolders with name "subfolder_1" and all files with name "test.m" inside the "program_folder" will be ignored.

Reading input m-file in a main m-file

I would like MATLAB to tell me if I have an input file (.m file) that contains some variables with their numbers (i.e., a = 5, b = 6, c = 7) so that I can then use that .m file in another program (main .m file) that uses these variables to calculate S = a + b + c. How can I then read the input file from the main file? Assume the input file is called INP and the main MAIN.
This is typically not good practice in MATLAB. The file containing the input variables would, in your example, be a script. As would your main file. MATLAB does not error when running one script from another, as suggested by ScottieT812, but under certain circumstances strange errors can arise. (Run time compiling has difficulty, variable name collisions across scripts)
A better option is to turn the inputs script into a function which returns the variables of interest
function [a,b c] = inputs
a = 5;
b = 6;
c = 7;
Then this function can be called in the main.m script.
% main.m
[a,b,c] = inputs;
s = a+b+c;
If your "input" file is an m-file, just use the name of the file in your "main" m-file. For example you might have a file called input.m that looks like this:
% File: inputs.m
a = 5;
b = 6;
c = 7;
Then, you can use it in the file main.m like this:
% File: main.m
inputs;
S = a + b + c;
For this sort of stuff (parameters that are easily adjusted later) I almost always use structures:
function S = zark
S.wheels = 24;
S.mpg = 13.2;
S.name = 'magic bus';
S.transfer_fcn = #(x) x+7;
S.K = [1 2; -2 1];
Then you can return lots of data without having to do stuff like [a,b,c,d,e,f]=some_function;
One nice thing about structures is you can address them dynamically:
>> f = 'wheels';
>> S.(f)
ans =
24
It sounds like you want to have some global configuration information that's used by scripts. Often, it's much better to create functions and pass values as arguments, but sometimes it makes sense to do things the way you suggest. One way to accomplish this is to save the information in a file. See "load" and "save" in the Matlab documentation.
I ran into the exact problem KennyMorton mentioned when trying to create runtime compiled versions of MATLAB software for my work. The software uses m-files extensively for passing arguments between functions. Additionally, we create these m-files dynamically which the deployed version of MATLAB does not play nice with. Our workaround was:
save the parameters to a file without the .m extension
read and eval the contents of the file
So, to follow the OPs example, in a function we would create a text file, INP, containing our parameters. We create this file in the directory returned by the ctfroot function. Then, in MAIN, we would use the following to retrieve these parameters:
eval(char(textread(fullfile(ctfroot, INP), '%s', 'whitespace', '');
If the data script is just a script, you can call it from a function or another script directly. Not extra commands required. For example:
%mydata.m
a = 1;
b = 2;
%mymain.m
mydata
whos
mymain
>>mymain
Name Size Bytes Class Attributes
a 1x1 8 double
b 1x1 8 double
This also works for functions in addition to scripts
%foo.m
function foo
mydata
whos
>>foo
Name Size Bytes Class Attributes
a 1x1 8 double
b 1x1 8 double
Generally, it is preferable to use a MAT or other data file for this sort of thing.