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 |
IDrowB |
(integer/character) Vector of length m with either indices or row names mapping from rows of |
IDcolA |
(integer/character) (Optional) Similar to |
IDcolB |
(integer/character) (Optional) Similar to |
drop |
Either |
make.dimnames |
|
inplace |
|
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)