# Computing the distance and weight matrix of a graph

I would like to create an igraph object. First, I set up the size of igraph object — n, m, then create a random matrix. As a result matrix B will be filled. Matrix B is the adjacency matrix for the igraph object. Inside for-loops I compute the distance d (scalar) and the weight matrix W. I would like to improve the perfomance of calculation. I think it is possible because I have used 4 for-loops in my code:

n <- 6
m <- 7

mat <- matrix(sample(0:255, n*m, replace=T), nrow = n, ncol = m)
R <- 2

a <- 1
b <- 1

d <- 0
e <- 0
g <- 0

W <- matrix(0, n, m)
B <- matrix(0, n*m, n*m)

for (i in 1:n){
for (j in 1:m){
for (i0 in 1:n){
for (j0 in 1:m){
d <- ((i0 - i)^2+(j0 - j)^2)^(1/2)
e <- ifelse(d <= R, 1, 0)
g <- abs(mat[i,j] - mat[i0,j0])
W[i0,j0] <- e * ((a*g)^2 + (b*d)^2)^(1/2)
} # for i0
} # for j0
B[m * (i-1)+j,] <- c(t(W))

} #for_j
} #for_i


Could anyone please give me an idea how to rewrite the above code with fewer or no for-loops?

Here is how you would do it with no for loops. The dist() function computes the distance between every pair of rows of a matrix. So you have to apply it to two matrices:

1. the matrix C where each row contains the i and j coordinates of each vertex.
2. the matrix matrix(M, ncol = 1) where each row contains the value at a vertex.

M <- t(mat)
C <- cbind(c(row(M)), c(col(M)))
D <- as.matrix(dist(C, method = "euclidean"))
E <- as.numeric(D <= R)
G <- as.matrix(dist(matrix(M, ncol = 1), method = "manhattan"))
B <- E * ((a * G) ^ 2 + (b * D) ^ 2) ^ (1 / 2)


Note that in R, matrices are stored using "Column Major", i.e. column by column. So it would be more natural to pick that the second row/col in B corresponds to the item at row 2 and col 1 in mat. You chose the opposite (row 1 col 2) which forced me to start my code with M <- t(mat). If you want to pick the more natural approach as I suggest, just replace that first line with M <- mat.

• thanks you for review of code. I tried two option M<-mat and M<-t(mat), unfortunatly, I didn't see the difference. When I plot the igraph object I use: mylayout<-as.matrix(cbind(cx, -cy)), sing '-' before cy. – Nick Feb 6 '16 at 2:55
• As the result I should obtain the symmetric matrix B. How can I do the calculation for upper right triangle (without the diagonal) only? – Nick Feb 7 '16 at 2:52
• You can remove the two as.matrix() in my code, then the result will be of class dist. The code won't be noticeably faster. Maybe the only benefit is that B will occupy less memory space. – flodel Feb 8 '16 at 0:58