Search code examples
rmatrixcross-product

How to modify matrix multiplication to sum only positives or negatives values in R


I want to do a matrix multiplication with a twist.

I have this matrix:

A <- matrix(c(1,-1,-1,0,-1,0,1,0,0,1,0,0,0,1,-1,1,-1,0,0,-1,1,0,1,0,1,-1,-1,1,-1,1), nrow = 6, ncol = 5)

A
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    1    0    0    1
[2,]   -1    0    1   -1   -1
[3,]   -1    0   -1    1   -1
[4,]    0    1    1    0    1
[5,]   -1    0   -1    1   -1
[6,]    0    0    0    0    1

And I want to get two different matrices. The first matrix is this:

C
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    0    0    0    2    0    1
[2,]    0    0    2    1    2    0
[3,]    0    2    0    0    4    0
[4,]    2    1    0    0    0    1
[5,]    0    2    4    0    0    0
[6,]    1    0    0    1    0    0

This "convergence matrix" is something like the multiplication of A for its transpose (in R is something like this A%*%t(A)), but with a little twist, during the sum to obtain each cell I only want de sum of the positives values. For example, for the cell C23 the regular sum would be:

(-1)(-1) + (0)(0) + (1)(-1) + (-1)(1) + (-1)(-1) = 0

, but I only want the sum of the positive products, in this example the first [(-1)(-1)] and the last [(-1)(-1)] to obtain 2.

The second matrix is this:

D
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    0    2    2    0    2    0
[2,]    2    0    2    1    2    1
[3,]    2    2    0    2    0    1
[4,]    0    1    2    0    2    0
[5,]    2    2    0    2    0    1
[6,]    0    1    1    0    1    0

This "divergence matrix" is similar to the previous one, with the difference that I only want to sum de absolute values of the negative values. For example, for the cell D23 the regular sum would be:

(-1)(-1) + (0)(0) + (1)(-1) + (-1)(1) + (-1)(-1) = 0

, but I only want the sum of the absolute values of negative products, in this example the third abs [(1)(-1)] and the fourth abs[(-1)(-1)] to obtain 2.

I've been trying with apply, sweep and loops but I can't get it. Thanks for your responses.


Solution

  • Another take:

    D <- A
    D[D<0] = -1i*D[D<0]
    D <- Im(tcrossprod(D))
    
    C <- tcrossprod(A) + D
    

    A is defined in the question. Output:

    > D
         [,1] [,2] [,3] [,4] [,5] [,6]
    [1,]    0    2    2    0    2    0
    [2,]    2    0    2    1    2    1
    [3,]    2    2    0    2    0    1
    [4,]    0    1    2    0    2    0
    [5,]    2    2    0    2    0    1
    [6,]    0    1    1    0    1    0
    > C
         [,1] [,2] [,3] [,4] [,5] [,6]
    [1,]    3    0    0    2    0    1
    [2,]    0    4    2    1    2    0
    [3,]    0    2    4    0    4    0
    [4,]    2    1    0    3    0    1
    [5,]    0    2    4    0    4    0
    [6,]    1    0    0    1    0    1