Search code examples
rmatrixvectorsimilarityeuclidean-distance

How to go from a vector to a similarity matrix?


I would like to reconstruct a similarity matrix between two vectors from a vector containing the similarity between each pair of elements in the two vectors. Does anyone know how I could do it?

To make it more concrete, here is a toy example. I have two vectors v1 and v2. Then I construct a similarity matrix d using the Euclidean method.

    v1 <- c(1, 3, 5)
    v2 <- c(2, 4, 6)
    d <- dist(data.frame(cbind(c(1, 3, 5), c(2, 4, 6))), method = "euclidean", upper = T, diag = T)

d looks like this:

             1        2        3
    1 0.000000 2.828427 5.656854
    2 2.828427 0.000000 2.828427
    3 5.656854 2.828427 0.000000

Of course, the numbers below and above the diagonal are equal. So I can just use a vector of three numbers to get all the information I need. With the following command, I get the corresponding vector with the three similarities:

    >as.numeric(d)
    [1] 2.828427 5.656854 2.828427

Now what I would like to do is from the vector as.numeric(d) to go back to the matrix below:

             1        2        3
    1 0.000000 2.828427 5.656854
    2 2.828427 0.000000 2.828427
    3 5.656854 2.828427 0.000000

Is there a way to do that in the general case? I want to be able to go quickly from one format to the other because some calculations are more straightfroward to perform on the vector and others more straightforward to perform with the matrix.


Solution

  • You could use the following code

    vec2mat<-function(d){
        e<-uniroot(function(x)x^2-x-2*length(d),c(1,100))$root
        as.matrix(structure(d, Size=round(e), class="dist"))
    }
    
    vec2mat(1:6)
    
      1 2 3 4
    1 0 1 2 3
    2 1 0 4 5
    3 2 4 0 6
    4 3 5 6 0