2

I have a network with edges and points. The FID shows the ID number of each edge that is created by Start_Point and End_Point. For example edge 3 is between the two points of 2 and 3 in the network.

FID     Start_Point End_Point
1       1           2
2       1           4
3       2           3
4       2           4

I want to create a 4-by-4 matrix of these points. if there is an edge between 2 points the value is 1 else is inf:

[inf, 1,   inf, 1;
 1,   inf, 1,   1;
 inf, 1,   inf, inf;
 1,   1,   inf, inf]

How can I create such a matrix in MATLAB?

6
  • 1
    Please clarify your question. Make your output have the correct dimensions for you 5-by-3 input. Explain why a point in your matrix would be inf and why it would be 1. What format (data type) is your input in? Please EDIT your question to add these details
    – Dan
    Commented Sep 22, 2015 at 8:59
  • It is still not clear. Explain the dimensions of your output matrix, how did you get to the (inf 1 inf inf inf ... 1)? What are the round brackets supposed to mean??
    – Dan
    Commented Sep 22, 2015 at 9:17
  • there are 127 edges (FID) between the network of points. If there is a edge between two points, it means there is a rout ! so, the value of that edge will be 1 and if there is not a rout between two points, then there is not an edge between them. so, the value of edge will be inf. Commented Sep 22, 2015 at 9:23
  • there is 101 points in the network.. so the dimension of matrix will be 101X101. the arrays of matrix would be 1 or inf. Is it more clear? Commented Sep 22, 2015 at 9:24
  • Not much more clear I'm afraid, make an example much smaller network with an output of say 4-by-4 and show the full input data and output matrix. Also format your output matrix as a proper matlab matrix (i.e. drop the ())
    – Dan
    Commented Sep 22, 2015 at 9:30

3 Answers 3

3

You can convert it to a sparse matrix and then use full command to obtain adjacency matrix.

edges= [1 2;
    3 4;
    3 1
    2 3];
n=size(edges,1);
% create sparse matrix with given edges and their reverse direction
A = sparse([edges(:,1); edges(:,2)],[edges(:,2); edges(:,1)],[ones(n,1); ones(n,1)]);
% create adjacency matrix
B=full(A);
% set zeros to inf
B(B==0)=inf;

and this is the result :

A =

   (2,1)        1
   (3,1)        1
   (1,2)        1
   (3,2)        1
   (1,3)        1
   (2,3)        1
   (4,3)        1
   (3,4)        1

>> B

B =

   Inf     1     1   Inf
     1   Inf     1   Inf
     1     1   Inf     1
   Inf   Inf     1   Inf

Edit : the sparse command create a sparse matrix with addressing values of its elements. One prototype for this command is as follow :

A=sparse(rows,cols,values);

for example A=sparse([1;2],[1,3],[10,5]) is a matrix which A(1,1)=10 and A(2,3)=5 and other elements are zero:

A=sparse([1;2],[1,3],[10,5]);
>> full(A)

ans =

    10     0     0
     0     0     5

In your case you have to add two directions to sparse matrix (symmetric) and all values are one. So you need to construct sparse matrix as :

 A = sparse([edges(:,1); edges(:,2)],[edges(:,2); edges(:,1)],[ones(n,1); ones(n,1)]);

full command convert a sparse matrix to a dense one.

3
  • Thanks for your reply.. please explain about line A = sparse([edges(:,1); edges(:,2)],[edges(:,2); edges(:,1)],[ones(n,1); ones(n,1)]); what is [ones(n,1); ones(n,1)]) ? Commented Sep 22, 2015 at 11:41
  • @Shokouh Dareshiri, I edited the answer and I explained that. Commented Sep 22, 2015 at 12:17
  • Merc.. Thank you so much.. It was so helpful :-) Commented Sep 22, 2015 at 12:55
2

So you basically want to create an adjacency matrix from an adjacency list of edges? The number of your edges (i.e. your FID column) is irrelevant so I'm assuming your input data is of the form

edges = [1   2
         1   4
         2   3
         2   4]

Now the first column of edges is the rows of your adjacency matrix and the second is the columns (or vice versa, it doesn't matter since your matrix is symmetrical)

The simplest solution is to use linear index which you would get via the sub2ind function:

adj = inf(size(edges,2));
idx = sub2ind(size(adj),edges(:,1), edges(:,2))
adj(idx) = 1;

I suspect your edges matrix will already be symmetrical but if it's not then just use

edges_sym = [edges; fliplr(edges)]

instead of edges

1
1

You can use accumarray:

edges1 = accumarray([startpoint endpoint]),1);
edges2 = edges1.'; % transpose your matrix, to obtain both edges
edges = edges1+edges2;
edges(edges==0)=inf;

accumarray gathers all points with common indices, pastes the value 1 on those indices. edges1 is the transpose of edges2, thus transpose, then add the two together. Find all indices on which the matrix is 0, then fill those values with inf.

Alternative:

edges= [1 2;
    3 4;
    3 1
    2 3];
matrix = accumarray([edges;fliplr(edges)],1,[],[],inf);

fliplr flips your matrix left to right, to get all the desired combinations of indices. Then use accumarray to set a 1 on all locations specified by edges and put inf at the other locations.

If you are sure your matrix is symmetric, don't use fliplr, if you sure your matrix is non-symmetric, use fliplr and if you are not sure use this:

matrix = accumarray([edges;fliplr(edges)],1,[],@mean,inf);

where the @mean makes sure to set double entries to 1 anyway. For weighted edges do the following, where weights is an Nx1 array containing the weights and N is the number of edges.

matrix = accumarray([edges;fliplr(edges)],weights,[],@mean,inf);
5
  • Thanks for your reply :-) Commented Sep 22, 2015 at 12:54
  • 1
    No problem. The answer by Ali Mirzaei is probably the fastest of these three solutions for your problem, though I'd like to mention the versatility of accumarray for utilisation of other functions than sparse's built-in sum functionality, if you ever need it ;). This is not an intent to steal the accept, that belongs on Ali's fast solution!
    – Adriaan
    Commented Sep 22, 2015 at 13:21
  • if i want to weigh edges instead of 1 then what should i do? Commented Oct 5, 2015 at 6:15
  • when i use accumarray , it give me error : Undefined function 'accumarray' for input arguments of type 'dataset'. Commented Oct 5, 2015 at 6:59
  • 1
    then you are missing the toolbox it's part of. You can use sparse with the same weight array
    – Adriaan
    Commented Oct 5, 2015 at 7:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.