lib/dSP_5.1/Matlab/GraphViz2Mat1.2/make_layout.m
function [x, y] = make_layout(adj)
%  [x, y] = make_layout(adj)  Creates a layout from an adjacency matrix
%
% INPUT:   adj - adjacency matrix (source, sink)
% OUTPUT: x, y - Positions of nodes
%
% WARNING: Uses some very simple heuristics, any algorithm would do better 

N = size(adj,1);
tps = toposort(adj);
if ~isempty(tps),       % is directed ?
    level = zeros(1,N);
    for i=tps,
        idx = find(adj(:,i));
        if ~isempty(idx),
            l = max(level(idx));
            level(i)=l+1;
        end;
    end;
else
    level = poset(adj,1)'-1;  
end;
y = (level+1)./(max(level)+2);
y = 1 - y;
x = zeros(size(y));
for i = 0:max(level),
    idx = find(level==i);
    offset = (rem(i,2)-0.5)/10;
    x(idx) = (1:length(idx))./(length(idx)+1)+offset;
end;

function [depth] = poset(adj, root)
% [depth] = poset(adj, root)   Identify a partial ordering among the nodes of a graph
% INPUT:   adj  -  adjacency matrix
%          root -  node to start with
% OUTPUT:  depth - Depth of the node
% Note     : All Nodes must be connected
adj = adj + adj';
N = size(adj,1);
depth = zeros(N,1);
depth(root) = 1;
queue = root;
while 1,
    if isempty(queue),
        if all(depth), 
            break; 
        else
            root = find(depth==0); 
            root = root(1);
            depth(root) = 1;
            queue = root;
        end
    end
    r = queue(1); queue(1) = [];
    idx = find(adj(r,:));
    idx2 = find(~depth(idx));
    idx = idx(idx2);
    queue = [queue idx];
    depth(idx) = depth(r) + 1;
end;

function [seq] = toposort(adj)
% [seq] = toposort(adj)  A Topological ordering of nodes in a directed graph
% INPUT:  adj  -  adjacency matrix 
% OUTPUT: seq  -  a topological ordered sequence of nodes
%                 or an empty matrix if graph contains cycles
N = size(adj);
indeg = sum(adj,1);
outdeg = sum(adj,2);
seq = [];
for i = 1:N,
    idx = find(indeg==0);    % Find nodes with indegree 0
    if isempty(idx),   % If can't find than graph contains a cycle
        seq = [];
        break;
    end;
    [dummy idx2] = max(outdeg(idx)); % Remove the node with the max number of connections
    indx = idx(idx2);
    seq = [seq, indx];
    indeg(indx) = -1;
    idx = find(adj(indx,:));
    indeg(idx) = indeg(idx)-1;
end 