matlab: check which lines of a path are used - graphshortestpath - matlab

The related problem comes from the power Grid in Germany. I have a network of substations, which are connected according to the Lines. The shortest way from point A to B was calculated using the graphshortestpath function. The result is a path with the used substation ID's. I am interested in the Line ID's though, so I have written a sequential code to figure out the used Line_ID's for each path.
This algorithm uses two for loops. The first for-loop to access the path from a cell array, the second for-loop looks at each connection and searches the Line_ID from the array.
Question: Is there a better way of coding this? I am looking for the Line_ID's, graphshortestpath only returns the node ID's.
Here is the main code:
for i = i_entries
path_i = LKzuLK_path{i_entries};
if length(path_i) > 3 %If length <=3 no lines are used.
id_vb = 2:length(path_i) - 2;
for id = id_vb
node_start = path_i(id);
node_end = path_i(id+1);
idx_line = find_line_idx(newlinks_vertices, node_start, ...
node_end);
Zuordnung_LKzuLK_pathLines(ind2sub(size_path,i),idx_line) = true;
end
end
end
Note: The first and last enrty of path_i are area ID's, so they are not looked upon for the search for the Line_ID's
function idx_line = find_line_idx(newlinks_vertices, v_id_1, v_id_2)
% newlinks_vertices includes the Line_ID, and then the two connecting substations
% Mirror v_id's in newlinks_vertices:
check_links = [newlinks_vertices; newlinks_vertices(:,1), newlinks_vertices(:,3), newlinks_vertices(:,2)];
tmp_dist1 = find(check_links(:,2) == v_id_1);
tmp_dist2 = find(check_links(tmp_dist1,3) == v_id_2,1);
tmp_dist3 = tmp_dist1(tmp_dist2);
idx_line = check_links(tmp_dist3,1);
end
Note: I have already tried to shorten the first find-search routine, by indexing the links list. This step will return a short list with only relevant entries of the links looked upon. That way the algorithm is reduced of the first and most time consuming find function. The result wasn't much better, the calculation time was still at approximately 7 hours for 401*401 connections, so too long to implement.

I would look into Dijkstra's algorithm to get a faster implementation. This is what Matlab's graphshortestpath uses by default. The linked wiki page probably explains it better than I ever could and even lays it out in pseudocode!

Related

How to create a variable in Matlab where certain subjects are coded as 1?

I want to create a variable called 'flag_artifact' where certain subjects from my dataset (for whom I know have bad quality images) are coded as e.g., 1. My dataset is stored in a table T with a certain number of rows and 'subject' is the 1st column in the table.
I managed to do it by creating a for loop. Surely there is a more efficient way to do this by perhaps directly creating the variable and using less lines of code? Could anyone give some advice?
Thank you very much! Here is what I have:
flag_artifact = {'T_300'}; %flagging subject number 300 for example
for i = 1:size(T,1)
if isequal(table2cell(T(i, 1)), flag_artifact)
T(i, 1) = {'1'};
end
end
However, when creating the variable flag_artifact = {'T_300'}, I would like it to include more than one subject. I tried using flag_artifact = {'T_300'}; {'T_301'}, as well as flag_artifact = {'T_300', 'T_301'} but it doesn't work because these subject identifiers do not get replaced with 1s.

Matlab structure with Children that are arrays of structs, etc. - How do trace path to all children individually?

I have a Matlab structure, A, that has 3 fields. The first field is SignalName and the third field is Children. Children can either be empty or a Struct array with the same fields, and so on, to an arbitrary depth not immediately known to the user. SignalName is a character array which is the name of a signal.
I have written a recursive function (in Matlab) to retrieve all of the SignalName values for structures that have no Children, and it's pretty slick (I think), but I need to know the absolute path taken to arrive at said SignalName. I cannot figure this out in Matlab.
As an example:
A.SignalName = 'Things'
A.Children = <22x1 struct>
A.Children(1).SignalName = 'Places'
A.Children(1).Children = [8x1 struct]
This goes on for an unknown depth, and the length of the struct arrays is not immediately known. It is easy via recursion to 'dive' down and get all of the SignalNames belonging to Children with no further Children, but how do I trace the route I used to get there? My function would ideally return results as a signal name, and the path taken to said signal.
In my experience with other languages, it seems like something like A* or Breadth-First might help, but I'm not exactly searching for something. I want simply to map every node and the path to it, and I'm not sure how to do that with the strange data-structure I'm given.
Thanks for any help you all can provide!
EDIT: I wanted to provide the code to hopefully shed light on my issue. I can get the paths down to the deepest node, but any other nodes at that level leave me without a complete path to that specific location. This is what I need help with. I am using '*' as my delimiter for a regexp in my post-processing script to break up the strings in PATHS.
For two nodes at the same depth, I might get a full path like 'A.B.C.D.Signal1' for the first node, but the second would give me a path of 'D.Signal2', when what I need is 'A.B.C.D.Signal2'. If the path was the same to the 'D' level with every signal, I would just copy the path over, but I have multiple branches in this struct from each level, and I go 4 or 5 levels deep.
function [NAMES,PATHS]=FindSignals(A,TMP,TMP2)
persistent SigName;
persistent path;
SigName = TMP;
path = TMP2;
if(~isempty(A.Children)) % If this struct has Children
for i = 1:length(A.Children) % Iterate through the Children
nextStruct = A.Children(i);
path = strcat([path '*' A.SignalName]);
[NAMES,PATHS] = FindSignals(nextStruct,SigName,path); % Recurse
end
else % If this struct has no Children
path = strcat([path '*' A.SignalName '*']); % Finish the path to Child
SigName = char(SigName,A.SignalName); % Grab the signal name
NAMES = SigName;
PATHS = path;
end
end
Again, thanks for any help!
EDIT: 12/14/2015 - I'm still completely stuck on this. Could anyone please take a peek at my source code above? I am unsure how to tack on an absolute path to the recursive function call and allow it to be a full path for each node at the same depth, and then reset to the appropriate depth once I move up or down the 'tree'. Thanks.

Debugging a for loop in matlab

I've been looking throught the documentation, but can't seem to find the bit I want.
I have a for loop and I would like to be able to view every value in the for loop.
for example here is a part of my code:
for d = 1 : nb
%for loop performs blade by blade averaging and produces a column vector
for cc = navg : length(atbmat);
atb2 = (sum(atbmat((cc-(navg-1):cc),d)))/navg;
atbvec2(:,cc) = atb2;
end
%assigns column vector 'atbvec2' to the correct column of the matrix 'atbmat2'
atbmat2(d,1:length(atbvec2)) = atbvec2;
end
I would like to view every value of atb2. I'm a python user(new to MATLAB) and would normally use a simple print statement to find this.
I'm sure there is a way to do it, but I can't quite find how.
Thankyou in advance.
you can use disp in Matlab to print to the screen but you might want to use sprintf first to format it nicely. However for debugging you're better off using a break point and then inspect the variable in the workspace browser graphically. To me, this is one of Matlab's best features.
Have a look at the "Examine Values" section of this article
The simplest way to view it everywhere is to change this line:
atb2 = (sum(atbmat((cc-(navg-1):cc),d)))/navg;
Into this, without semicolon:
atb2 = (sum(atbmat((cc-(navg-1):cc),d)))/navg
That being said, given the nature of your calculation, you could get the information you need as well by simply storing every value of abt2 and observing them afterwards. This may be done in atbmat2 already?
If you want to look at each value at the time it happens, consider setting a breakpoint or conditional breakpoint after the line where abt2 is assigned.

iterating over multiple intervals Matlab

I'd like to make a loop in Matlab that would work only over user specified intervals of time, instead of simply the whole time. How can one write this loop condition?
regards
Generally you and iterate multiple ways. There are two main ways that I can think of off the top of my head. I will also open this up for community wiki so others can just easily edit this as well.
First, using a simple For loop.
The general syntax is for index = 1:someValue
someValue can really be anything that is greater than 1 in this case. Many times it's simply the last index value of a matrix you're wanting to traverse.
You can modify this as well though! Let's say you want every 3rd index starting with the 2nd position in the matrix. All you have to do is: for index = 2:3:someValue The 3 here tells the loop that it should add 3 to the index at the end of each loop iteration until you get to (or surpass) someValue.
Yet another modfication is traversing backwards. In this case you start at the 'end' and move to the beginning. It would look like this: for index = someValue:-1:1 You can also do every 4th index while going backwards for index = someValue:-4:1.
Obviously you can replace the value between the two : to be a step size that you want. You just have to be aware of potential indexing issues that can arrise. Namely trying to index out of bounds of the matrix or potentially going negative.
Secondly here you can modify the value within the loop itself. Generally this isn't the best idea when you're using a for loop as the value of your indexing variable will be changed by the loop as well as by you within the loop. Many times you'll see this done with a while loop or a do while combo.
A few examples are as follows:
index = 0;
do
{
% some operations
index = index + aNumber;
}while(index <= someValue)
In the above example the loop will continue to loop until the index value index becomes greater than or equal to someValue at the end of the current iteration of the loop. This type of loop will ALWAYS, and I repeat ALWAYS execute at least once.
index = 0;
while(index <= someValue)
{
%some operations
index = index + aNumber;
}
In this case the loop will continue to loop while index satisfies the logical statement here. If the statement isn't true when you try to run the loop for the first time it will not execute at all.
Hope this helps and feel free to ask for any additional clarification if you want it!
Others, please feel free to edit to add additional information or clean up what I might have not explained fully =)
Do you mean something like this:
for i = [1:5 7:10 12:14 21:22]
do_func(i)
end
or even
for i = [1:5 4:7 19:-1:15]
do_func(i)
end
?
If you only want to perform an action when a certain condition is true in a loop, you just need something like:
for i=1:length(arr)
if condition(arr(i))
do_something(arr(i));
end
end

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.