How could you create a function that multiplies two matrices together? I know there is a function in R that does this already, but I want to write a function that can compute this without using the function already built in R.
It should work with sapply
res <- sapply(seq_len(ncol(matrix1)), function(i) sapply(seq_len(nrow(matrix2)),
function(j) sum(matrix1[i,] * matrix2[,j])))
Then take a transpose of the resultant
res_final <- t(res)
Not sure why you would like to do this as any "user-defined" implementation is bound to be slower than the built-in R function (and you can in fact write your own C++ implementation using Rcpp) but here is a version
matmul <- function(A, B) {
r_A <- dim(A)[1]
c_A <- dim(A)[2]
r_B <- dim(B)[1]
c_B <- dim(B)[2]
# A and B are matrices with fitting dimensions
if (c_A != r_B) {
stop("Matrix dimensions not consistent")
}
product <- matrix(nrow = r_A, ncol = c_B)
for (i in seq_len(r_A)) {
for (j in seq_len(c_B)) {
product[i,j] <- sum(A[i,] * B[,j])
}
}
return(product)
}
X <- matrix(1:12, nrow = 4, ncol = 3)
Y <- matrix(1:12, nrow = 3, ncol = 4)
print(identical(matmul(X, Y), X %*% Y))
X <- matrix(1:12, nrow = 4, ncol = 3)
Y <- matrix(1:12, nrow = 4, ncol = 3)
print(identical(matmul(X, Y), X %*% Y))
X <- matrix(1.1:12.1, nrow = 4, ncol = 3)
Y <- matrix(1:12, nrow = 3, ncol = 4)
print(identical(matmul(X, Y), X %*% Y))
Given matrices A and B, for the matrix product M = A*B, you can used the following code:
M <- t(apply(A,1,function(x) apply(B,2,function(y) sum(x*y))))
where nested apply() function is the approach here.
Example
A <- matrix(1:9,ncol = 3)
B <- matrix(1:12,nrow = 3)
M <- t(apply(A, 1, function(x) apply(B,2,function(y) sum(x*y))))
and you will get
> M
[,1] [,2] [,3] [,4]
[1,] 30 66 102 138
[2,] 36 81 126 171
[3,] 42 96 150 204
To verify the result, you can compare it with A%*%B, and it's shown the same result with the self-written code:
> A%*%B
[,1] [,2] [,3] [,4]
[1,] 30 66 102 138
[2,] 36 81 126 171
[3,] 42 96 150 204
Related
I have two matrices, one of them has a NA value and I want to use a function that only runs if there are NAs present in the data, so if I run the function it should only work on df2 and not df1. How would I do this?
df1 <- matrix(1:4, nrow = 2, ncol = 2)
df2 <- matrix(1,2,3,NA, nrow = 2, ncol = 2)
Based on the comment above, here is a complete answer (assuming I understand what you are getting at). The function is set up to do something or not to the matrix depending on whether it has NA values.
df1 <- matrix(1:4, nrow = 2, ncol = 2)
df2 <- matrix(c(1,2,3,NA), nrow = 2, ncol = 2)
myfunc <- function(m) {
ret <- m
if (all(!is.na(m))) {
print("This matrix has no NAs")
} else {
print("This matrix has NAs")
}
return(ret)
}
myfunc(df1)
# [1] "This matrix has no NAs"
# [,1] [,2]
# [1,] 1 3
# [2,] 2 4
myfunc(df2)
# [1] "This matrix has NAs"
# [,1] [,2]
# [1,] 1 3
# [2,] 2 NA
in R, I´m trying to program a Kronecker product calculator for two matrices(AxB). I´m able to obtain each A subindex product x all of the B matrix elements. This results in four matrices. I need to cbind the first and second matrix, as well as the third and fourth. Then rbind those two resulting matrices.
How could I do that?
K = function(A,B){
nfila = nrow(A)*nrow(B)
ncolum = ncol(A)*ncol(B)
m = matrix(NA, nrow = nfila, ncol = ncolum)
for(j in 1:ncol(A)){
for(i in 1:nrow(A)){
s = print(A[j,i]*B)
}
}
}
A=matrix(1:4, nrow=2, byrow=TRUE)
B=matrix(5:8, nrow=2, byrow=TRUE)
K(A,B)
Create a list to store the output.
K = function(A,B){
res <- vector('list', ncol(A))
for(j in 1:ncol(A)){
s <- vector('list', nrow(A))
for(i in 1:nrow(A)){
s[[i]] = A[j,i]*B
}
res[[j]] <- do.call(cbind, s)
}
do.call(rbind, res)
}
A=matrix(1:4, nrow=2, byrow=TRUE)
B=matrix(5:8, nrow=2, byrow=TRUE)
K(A,B)
# [,1] [,2] [,3] [,4]
#[1,] 5 6 10 12
#[2,] 7 8 14 16
#[3,] 15 18 20 24
#[4,] 21 24 28 32
We can also use lapply here.
K = function(A,B){
do.call(rbind, lapply(seq(nrow(A)), function(x)
do.call(cbind, lapply(A[x, ], `*`, B))))
}
Given an n dimensional array X, a d by d-1 dimensional matrix V and two specified dimensions (p1, p2) <= (n, n); I would like a function that preforms matrix multiplication of V along the dimensions (p1, p2) of X.
That is given X:
library(abind)
set.seed(4)
X <- matrix(runif(4), 2, 2)
X <- abind(x, x+5, along = 3)
> a
, , 1
[,1] [,2]
[1,] 1 3
[2,] 2 4
, , 2
[,1] [,2]
[1,] 6 8
[2,] 7 9
and given a matrix V
V <- matrix(c(1, 2))
[,1]
[1,] 1
[2,] 2
For example, if p1=2 and p2=1 I would like to remove the following for loop
p1 <- 1
p2 <- 2
a.out <- array(0, c(2, 1, 2))
for (i in 1:dim(a)[2]){
a.out[,,i] <- a[,,i]%*%V # note indexed along other dimension
}
> a.out
, , 1
[,1]
[1,] 7
[2,] 10
, , 2
[,1]
[1,] 22
[2,] 25
The hard part here is that I want to allow for arbitrary dimensional arrays (i.e., n could be greater than 3).
1st Edit:
This problem is not the same as Indexing slice from 3D Rcpp NumericVector as I am discussing arbitrary number of dimensions >=2 and the question is not only about indexing.
2nd Edit:
Just to be a little more clear here is another example of what I am trying to do. Here the dimension of X is 4, p1 = 2, p3=3, and the dimension of X along the p1 dimension is 12. The following code computes the desired result as X.out for random X and V.
X <- array(rnorm(672), c(4, 7, 12, 2))
V <- matrix(rnorm(132), 12, 11) # p1 = 2, p2 = 3, V is of dimension D x D-1
d <- dim(X)
X.out <- array(0, dim=c(d[1:2], d[3]-1, d[4]))
for(i in 1:d[1]){
for (j in 1:d[4]){
X.out[i,,,j] <- X[i,,,j]%*%V # p1 = 2, p2 = 3
}
}
Does anyone know a fast way to create a matrix
like the following one in R.
[,1] [,2] [,3] [,4]
[1,] 1 1 1 1
[2,] 1 2 2 2
[3,] 1 2 3 3
[4,] 1 2 3 4
The matrix above is 4x4 and I want to create something like 10000x10000.
You can do:
N <- 4
m <- matrix(nrow = N, ncol = N)
m[] <- pmin.int(col(m), row(m))
or a shorter version as suggested by #dickoa:
m <- outer(1:N, 1:N, pmin.int)
These also work and are both faster:
m <- pmin.int(matrix(1:N, nrow = N, byrow = TRUE),
matrix(1:N, nrow = N, byrow = FALSE))
m <- matrix(pmin.int(rep(1:N, each = N), 1:N), nrow = N)
Finally, here is a cute one using a matrix product but it is rather slow:
x <- matrix(1, N, N)
m <- lower.tri(x, diag = TRUE) %*% upper.tri(x, diag = TRUE)
Note that a 10k-by-10k matrix for R seems big, I hope you don't run out of memory.
I am trying to get a function that is the opposite of diff()
I want to add the values of adjacent columns in a matrix for each column in the matrix.
I do NOT need the sum of the entire column or row.
For example:
If I had:
[ 1 2 4;
3 5 8 ]
I would end up with:
[ 3 6;
8 13 ]
Of course for just one or two columns this is simple as I can just do x[,1]+x[,2], but these matrices are quite large.
I'm surprised that I cannot seem to find an efficient way to do this.
m <- matrix(c(1,3,2,5,4,8), nrow=2)
m[,-1] + m[,-ncol(m)]
[,1] [,2]
[1,] 3 6
[2,] 8 13
Or, just for the fun of it:
n <- ncol(m)
x <- suppressWarnings(matrix(c(1, 1, rep(0, n-1)),
nrow = n, ncol = n-1))
m %*% x
[,1] [,2]
[1,] 3 6
[2,] 8 13
Dummy data
mat <- matrix(sample(0:9, 100, replace = TRUE), nrow = 10)
Solution:
sum.mat <- lapply(1:(ncol(mat)-1), function(i) mat[,i] + mat[,i+1])
sum.mat <- matrix(unlist(sum.mat), byrow = FALSE, nrow = nrow(mat))
You could use:
m <- matrix(c(1,2,4,3,5,8), nrow=2, byrow=T)
sapply(2:ncol(m), function(x) m[,x] + m[,(x-1)])