Hadamard product {tensorEVD}R Documentation

Hadamard product

Description

Computes the Hadamard product between two matrices

Usage

Hadamard(A, B, IDrowA, IDrowB,
         IDcolA = NULL, IDcolB = NULL,
         make.dimnames = FALSE,
         drop = TRUE, inplace = FALSE)

Arguments

A

(numeric) Left numeric matrix

B

(numeric) Right numeric matrix

IDrowA

(integer/character) Vector of length m with either indices or row names mapping from rows of A into the resulting hadamard product. If 'missing', it is assumed to be equal to 1,...,nrow(A)

IDrowB

(integer/character) Vector of length m with either indices or row names mapping from rows of B into the resulting hadamard product. If 'missing', it is assumed to be equal to 1,...,nrow(B)

IDcolA

(integer/character) (Optional) Similar to IDrowA, vector of length n for columns. If NULL, it is assumed to be equal to IDrowA if m=n

IDcolB

(integer/character) (Optional) Similar to IDrowB, vector of length n for columns. If NULL, it is assumed to be equal to IDrowB if m=n

drop

Either TRUE or FALSE to whether return a uni-dimensional vector when output is a matrix with either 1 row or 1 column as per the rows and cols arguments

make.dimnames

TRUE or FALSE to whether add rownames and colnames attributes to the output

inplace

TRUE or FALSE to whether operate directly on one input matrix (A or B) when this is used as is (i.e., is not indexed; therefore, needs to be of appropiate dimensions) in the Hadamard. When TRUE the output will be overwritten on the same address occupied by the non-indexed matrix. Default inplace=FALSE

Details

Computes the m × n Hadamard product (aka element-wise or entry-wise product) matrix between matrices A and B,

(R1 A C'1) ⊙ (R2 B C'2)

where R1 and R2 are incidence matrices mapping from rows of the resulting Hadamard to rows of A and B, respectively; and C1 and C2 are incidence matrices mapping from columns of the resulting Hadamard to columns of A and B, respectively.

Matrix R1 A C'1 can be obtained by matrix indexing as A[IDrowA,IDcolA], where IDrowA and IDcolA are integer vectors whose entries are, respectively, the row and column number of A that are mapped at each row of R1 and C1, respectively. Likewise, matrix R2 B C'2 can be obtained as B[IDrowB,IDcolB], where IDrowB and IDcolB are integer vectors whose entries are, respectively, the row and column number of B that are mapped at each row of R2 and C2, respectively. Therefore, the Hadamard product can be obtained directly as

A[IDrowA,IDcolA]*B[IDrowB,IDcolB]

The function computes the Hadamard product directly from A and B without forming R1 A C'1 or R2 B C'2 matrices.

Value

Returns a matrix containing the Hadamard product.

Examples

  require(tensorEVD)
  
  # (a) Example 1. Indexing using row/column names
  # Generate rectangular matrices A (nrowA x ncolA) and B (nrowB x ncolB)
  nA = c(10,15)
  nB = c(12,8)
  A = matrix(rnorm(nA[1]*nA[2]), nrow=nA[1])
  B = matrix(rnorm(nB[1]*nB[2]), nrow=nB[1])
  dimnames(A) = list(paste0("row",seq(nA[1])), paste0("col",seq(nA[2])))
  dimnames(B) = list(paste0("row",seq(nB[1])), paste0("col",seq(nB[2])))
  
  # Define IDs for a Hadamard of size n1 x n2
  n = c(1000,500)
  IDrowA = sample(rownames(A), n[1], replace=TRUE)
  IDrowB = sample(rownames(B), n[1], replace=TRUE)
  IDcolA = sample(colnames(A), n[2], replace=TRUE)
  IDcolB = sample(colnames(B), n[2], replace=TRUE)
  
  K1 = Hadamard(A, B, IDrowA, IDrowB, IDcolA, IDcolB, make.dimnames=TRUE)
  
  # (it must equal to:)
  K2 = A[IDrowA,IDcolA]*B[IDrowB,IDcolB]
  dimnames(K2) = list(paste0(IDrowA,":",IDrowB), paste0(IDcolA,":",IDcolB))
  all.equal(K1,K2)
  
  # (b) Example 2. Indexing using integers
  # Generate squared symmetric matrices A and B 
  nA = 20
  nB = 15
  A = tcrossprod(matrix(rnorm(nA*nA), nrow=nA))
  B = tcrossprod(matrix(rnorm(nB*nB), nrow=nB))
  
  # Define IDs for a Hadamard of size n x n
  n = 1000
  IDA = sample(seq(nA), n, replace=TRUE)
  IDB = sample(seq(nB), n, replace=TRUE)
  
  K1 = Hadamard(A, B, IDA, IDB)
  
  # (it must equal to:)
  K2 = A[IDA,IDA]*B[IDB,IDB]
  all.equal(K1,K2)
  
  # (c) Inplace calculation
  # overwrite the output at the same address as the input:
  IDB = sample(seq(nB), nA, replace=TRUE)
  
  K1 = A[]                     # copy of A to be used as input
  add  = pryr::address(K1)     # address of K on entry
  K1 = Hadamard(K1, B, IDrowB=IDB)
  pryr::address(K1) == add     # on exit, K was moved to a different address
  
  K2 = A[]   
  add  = pryr::address(K2)
  K2 = Hadamard(K2, B, IDrowB=IDB, inplace=TRUE)
  pryr::address(K2) == add     # on exit, K remains at the same address
  all.equal(K1,K2)

[Package tensorEVD version 0.1.3 Index]