Search code examples
rmatrixsapply

Generalize a function for any sized matrix


Say I have some matrix R

v1 <- c(1, .8, 0, .1, .2)
v2 <- c(.8, 1, .4, 0, .9)
v3 <- c(0, .4, 1, 0, 0)
v4 <- c(.1, 0, 0, 1, .5)
v5 <- c(.2, .9, 0, .5, 1)
R <- matrix(data=c(v1,v2,v3,v4,v5), nrow=5, byrow=TRUE)

And I want to assign values to a different matrix, R2, using min-max functions:

R2 <- matrix(NA, nrow=5, ncol=5)
for(i in 1:nrow(R))
{
  for(j in 1:ncol(R))
  {
    R2[i,j] <- max(min(R[i,1],R[1,j]), min(R[i,2],R[2,j]), min(R[i,3],R[3,j]), min(R[i,4],R[4,j]), min(R[i,5],R[5,j]))
  }
}

This works fine, but I have to modify the R2 assignment when the matrix size changes. How can I generalize the min-max function to any sized matrix? E.g., I want a function call like:

# to work, nrow(M1) == ncol(M2)
map_relation <- function(M1, M2)
{
  result <- matrix(NA, nrow=nrow(M1), ncol=ncol(M2))
  for(i in 1:nrow(M1))
  {
    max_val <- 0
    for(j in 1:ncol(M2))
    {
      # HOW CAN i MODIFY THIS TO APPLY GENERALLY TO ANY SIZED MATRIX?
      result[i,j] <- max(min(M1[i,1],M2[1,j]), min(M1[i,2],M2[2,j]), min(M1[i,3],M2[3,j]), min(M1[i,4],M2[4,j]), min(M1[i,5],M2[5,j]))
    }
  }
  return(result)
}

Solution

  • Seems you have a symmetric matrix. Anyone one way to do this is:

    R3 <-  matrix(NA, nrow=5, ncol=5)
    for(i in 1:nrow(R)) {
      for(j in 1:ncol(R)){
         R3[i,j] <- max(pmin(R[i, ],R[,j]))
       } 
    } 
    

    You could also use apply. Since the matrix is symmetric, you can use MARGIN = 2 or MARGIN = 1

    R4 <- apply(R, 2, \(x)apply(R, 1, \(y) max(pmin(x,y))))
    
    all.equal(R3, R2)
    [1] TRUE