What is this? I can't find help by using ?. (Sorry for being dumb)
> 1%*%1
[,1]
[1,] 1
> 10%*%10
[,1]
[1,] 100
> c(1:2)%*%c(1:2)
[,1]
[1,] 5
It's a matrix multiplication operator!
From the documentation:
Description:
Multiplies two matrices, if they are conformable. If one argument is a vector, it will be promoted to either a row or column matrix to make the two arguments conformable. If both are vectors of the same length, it will return the inner product (as a matrix).
Usage:
x %*% y
Arguments:
x, y numeric or complex matrices or vectors
> c(1,2,3) %*% c(4,5,6)
[,1]
[1,] 32
> c(1,2,3) * c(4,5,6)
[1] 4 10 18
Like MadSeb said, it is the matrix multiplication operator. If you give it two vectors, it will coerce them to (logical) 1-row & a 1-col matrix and multiply them.
It is also the inner (or dot) product between two vectors and finds wide usage in linear algebra, computational geometry and a host of other applications.
http://en.wikipedia.org/wiki/Dot_product
BTW, the vectors have to be in the same space (same number of dimensions)
> c(1,2,3) %*% c(4,5,6,7)
Error in c(1, 2, 3) %*% c(4, 5, 6, 7) : non-conformable arguments
I created a question 'What is the calculation behind the %*% operator in R?' which was marked as a duplicate of this question. The %*% operator is used to multiply two matrices. I didn't realise 'matrix multiplication' was an established algebraic method so it was useful to learn the underlying calculation, not yet described explicitly in other answers here. Passing on useful links from comments in the duplicate question
https://en.m.wikipedia.org/wiki/Matrix_multiplication#Definition
http://matrixmultiplication.xyz/
This operator is used to multiply a matrix with its transpose.
M = matrix( c(2,6,5,1,10,4), nrow = 2,ncol = 3,byrow = TRUE)
t = M %*% t(M)
print(t)
from tutorialspoints
Related
I have two matrices: A (k rows, m columns), B(k rows, n columns)
I want to operate on all pairs of columns (one from A and one from B), the result should be a matrix C (m rows, n columns) where C[i,j] = f(A[,i],B[,j])
now, if the function f was the sum of the dot product, then the whole thing was just a simple multiplication of matrices (C = t(A) %*% B)
but my f is different (specifically, I count the number equal entries:
f = function(x,y) sum(x==y)
my question if there is a simple (and fast, because my matrices are big) way to compute the result?
preferably in R, but possibly in python (numpy). I thought about using outer(A,B,"==") but this results in a 4 dimensional array which I havent figured out what exactly to do with it.
Any help is appreciated
In R, we can split them into list and apply the function f with a nested lapply/sapply
lapply(asplit(A, 2), function(x) sapply(asplit(B, 2), function(y) f(x, y)))
Or using outer after converting to data.frame because the unit will be column, while for matrix, it is a single element (as matrix is a vector with dim attributes)
outer(as.data.frame(A), as.data.frame(B), FUN = Vectorize(f))
data
A <- cbind(1:5, 6:10)
B <- cbind(c(1:3, 1:2), c(5:7, 6:7))
I have a 10000 x 7 data.table dat . I would like to multiply each row of dat by a 7x7 matrix c. I have tried the following
apply(dat, 1, function(x) sqrt(as.matrix(x) %*% as.matrix(c) %*% t(as.matrix(x))))
I get this error
Error in as.matrix(x) %*% as.matrix(c) : non-conformable arguments
This function works when I take a single row from dat (so 1 x 7) but not when I use apply.
How do I make this work using apply?
Thanks!
Additional info - I could achieve what I need another way. I could multiply the entire data.frame by the matrix and take sqrt(diag(x)). However, I need to do this a lot of times, so it would be more efficient to take this row by row and return a single figure.
I think you should use t(as.matrix(x))%*% as.matrix(c) %*% as.matrix(x) in your apply function, since the argument as.matrix(x) is indeed a column-vector (not a row-vector).
res <- apply(dat, 1, function(x) sqrt(t(as.matrix(x))%*% as.matrix(c) %*% as.matrix(x)))
Example
set.seed(1)
dat <- data.frame(matrix(sample(70),ncol = 7))
c <- matrix(sample(49),ncol = 7)
res <- apply(dat, 1, function(x) sqrt(t(as.matrix(x))%*% as.matrix(c) %*% as.matrix(x)))
such that
> res
[1] 1522.7206 1208.6306 1105.7509 1063.4341 1066.3423 1124.8271
[7] 1219.2280 1665.8301 1609.4704 954.3694
Note: c() is a commonly used function in R, using c as variable name is therefore not good practice, I use c_ below instead.
When multiplying matrices the number of columns in the first matrix needs to be the same as the number of rows in the second. In the as.matrix(x) %*% as.matrix(c) part in your code the first matrix has one column and the second has 7 rows. That is why you get the error.
Multiplying the transposed row of dat with c first and then the row fixes this.
apply(dat2, 1, function(x) sqrt(t(as.matrix(x)) %*% as.matrix(c_) %*% (as.matrix(x))))
Or making the function more explicit in regard to the matrix you want to create from the row also works:
apply(dat, 1, function(x) sqrt(matrix(x, 1) %*% c_ %*% t(matrix(x, 1))))
Both solutions produce the same results.
I have been wondering the most efficient way to do matrix multiplication on lists.
Let's say I have a matrix A and a list of matrices B:
A = matrix(c(1,2,3,4), ncol=2, nrow=2)
B = list(matrix(c(1,2,3,4), ncol=2, nrow=2), matrix(c(4,3,2,1), ncol=2, nrow=2))
And I want the list of crossproducts of A and each element b of B:
A %*% b
I was trying to use lapply() but couldn't figure out how to ensure the right sequence of multiplication without extra nested lapply's to transpose each b...
lapply(B, '%*%', A) # which gives a list of b%*%A rather than A%*%b
lapply(lapply(lapply(B, t), '%*%', t(A)), t) # gives the answer but geez...
Could anyone kindly give me some pointers here?
Just define your function inside lapply(), like so
lapply(B, function(x) A%*%x)
I am a newbie to R, but avid to learn.
I have been trying endlessly to create a matrix with a variable element (in this case [2,2]). The variable element should take number 4 on the first run and 5 on the second (numbers).
This matrix would be multiplied by another matrix (N0) and produce a result matrix (resul).
Up so far, I have only been able to create the initial matrix with the variable element using a for loop, but I am having problems indexing the result matrix. I have tried several versions, but this is the latest. Any suggestions would be greatly appreciated. Thank you.
numbers <- c(4,5,length.out = 2)
A <- matrix(c(1,2,3,NA),nrow=2,ncol=2)
resul <- matrix(nrow=2,ncol=1)
for (i in 1:2) {
A[2,2]<- matrix(numbers[i])
N0 <- matrix(c(1,2),nrow=2,ncol=1)
resul[i,]<- A[i,i]%*%N0
}
Your code has two distinct problems. the first is that A[i,i] is a 1 x 1
matrix, so you're getting an error because your multiplying a 1 x 1 matrix
by a 2 x 1 matrix (N0).
you could either drop the subscript [i,i] and initialize the result to be
a two by two matrix like so:
result <- matrix(nrow=2,ncol=1)
for (i in 1:2){
A[2,2]<- matrix(numbers[i])
# a colunm vector
N0 <- matrix(c(1,2),
nrow=2,
ncol=1)
# note the index is on the column b/c `A%*%N0` is a column matrix
result[,i]<- A%*%N0
}
or you could either drop the the second subscript [i,] and initialize the result to be
a two by two matrix like so:
result <- matrix(nrow=2,ncol=1)
for (i in 1:2){
A[2,2]<- matrix(numbers[i])
# a colunm vector
N0 <- matrix(c(1,2),
nrow=2,
ncol=1)
result[i,]<- A[i,]%*%N0
}
but it's not clear from you post which (if either) answer is the correct one. Indexing is tricky :)
So I took some information from a CSV, stored it as a matrix, and tried to compute the following operations on the result, but it gave me a 2x2 array of NA. Not seeing the problem here.
data <- read.csv('qog.csv', sep=';')
X <- matrix( log( data$wdi_gnipc ) )
X <- cbind(X, data$ciri_empinx_new)
t(X) %*% X
When I look at X and t(X) they look like how I expect them to, so I am matrix-multiplying a 2xn matrix with an nx2 matrix (n is some large number like 193) and so the matrix product should be well-defined and give a meaningful 2x2 answer.
Any ideas what could be going wrong?
Note: When I try
a <- rbind(c(1,2), c(3,4))
t(a) %*% a
it gives the desired result. Not sure what the important difference is between that and what I'm doing with the data.
Let's make that an answer. For the cross product to be filled with NA, you must have at least one NA per column inside X. You can find the number of NAs per column by running:
colSums(is.na(X))
and by all likelihood you will have that
all(colSums(is.na(X)) > 0)
# [1] TRUE