Reputation: 2669
I need to assign weights to edges of a graph, from the following papers:
"Fast linear iterations for distributed averaging" by L. Xiao and S. Boyd "Convex Optimization of Graph Laplacian Eigenvalues" by S. Boyd
I have the adjacency matrix for my graph (a 50 by 50 matrix), with 512 non-zero values.
I also have a 256 by 1 vector with the optimal weights.
For the software I'm using, I need a 50 by 50 matrix with the weight of edge (i,j) in the relevant position of the adjacency matrix (and with the opposite sign for edge (j,i)).
My attempt is below, but I can't get it working.
function weights = construct_weight_mtx(weight_list, Adj)
weights = zeros(size(Adj));
positions = find(Adj);
for i=1:length(positions)/2
if Adj(i) == 1
weights(i) = weight_list(i);
end
end
weights = weights - weights';
find(Adj) == find(weights);
end
Upvotes: 0
Views: 848
Reputation: 16801
You're finding the nonzero positions in the original adjacency matrix, but you're finding all of them. To get around this, you then take only the first half of those positions.
for i=1:length(positions)/2 ...
Unfortunately, this takes the indices from complete columns rather than just the positions below the diagonal. So if your matrix was all 1's, you'd be taking:
1 1 1 0 0 ...
1 1 1 0 0 ...
1 1 1 0 0 ...
...
instead of:
1 0 0 0 0 ...
1 1 0 0 0 ...
1 1 1 0 0 ...
...
To take the correct values, we just take the lower triangular portion of Adj
and then find the nonzero positions of that:
positions = find(tril(Adj));
Now we have only the 256 positions below the diagonal and we can loop over all of the positions. Next, we need to fix the assignment in the loop:
for i=1:length(positions)
if Adj(i) == 1 %// we already know Adj(i) == 1 for all indices in positions
weights(i) = weight_list(i); %// we need to update weights(positions(i))
end
end
So this becomes:
for i=1:length(positions)
weights(positions(i)) = weight_list(i);
end
But if all we're doing is assigning 256 values to 256 positions, we can do that without a for
loop:
weights(position) = weight_list;
Note that the elements of weight_list
must be in the proper order with the nonzero elements of the lower-triangular portion ordered by columns.
Completed code:
function weights = construct_weight_mtx(weight_list, Adj)
weights = zeros(size(Adj));
positions = find(tril(Adj));
weights(positions) = weight_list;
weights = weights - weights.'; %// ' is complex conjugate; not a big deal here, but something to know
find(Adj) == find(weights); %// Not sure what this is meant to do; maybe an assert?
end
Upvotes: 1