I am trying to multiply matrices in R. However, I am unable to do so without error. The multiplication of the dimensions seem right, but not sure what it could be. Here is some background on my data and what my loop is. Thanks for the help.
t
# [1] 6848
dim(A)
# [1] 2 2
dim(backward)
# [1] 6848 2
dim(B)
# [1] 6848 2
is.matrix(A)
# [1] TRUE
is.matrix(backward)
# [1] TRUE
is.matrix(B)
# [1] TRUE
for (i in (t-1):1){ #FIXXXXX
backward[i,] = t(A%*%(t(backward[i+1,])))*B[i+1,]
}
Error in A %*% (t(backward[i + 1, ])) : non-conformable arguments
By default, selecting a single row or column from a matrix results in a vector. Add drop=FALSE to your subsetting expression to keep this from happening.
t(A %*% t(backward[i+1, , drop=FALSE])) * B[i+1, , drop=FALSE]
And by the way, it would probably be a good idea to rename your t variable to something else, as t is also the transpose function.
Related
I'm trying to parse the coordinates of a matrix from a vector to retrieve an element.
Data:
m <- matrix(1:25, ncol = 5)
v <- c(2,3)
I'm basically trying to get the elementm[2,3], in that case the value 12, by parsing the vector as coordinates:
m[v]
but all I get is NA. I have tried m[paste(v, collapse="\",\""], which also did not work.
I know I could use
m[paste(v[1]), paste(v[2])]
but I'm trying to find a more elegant solution.
Any idea how to get this to work?
you can try
> m[matrix(v, 1)]
[1] 12
or just
> m[t(v)]
[1] 12
Few more options:
m[v[1], v[2]]
[1] 12
do.call("[", c(list(m), as.list(v)))
[1] 12
m[v[1] + (v[2]-1) * nrow(m)]
[1] 12
for a given matrix F I want to calculate the sum of the 2-norm of its rows, so I use the function sum() but it doesn't work as I expect it to do here an example
# The matrix F
> F <- matrix(c(9,1,1,1,4,1),nrow=3)
# index of the sum i
> i=1:NROW(F)
#And here is the result
> sum(norm(F[i,], type = "2")^4)
[1] 7376.60160040254
# and if i calculate each element of the sum i get
> norm(F[1,], type = "2")^4
[1] 6724
> norm(F[2,], type = "2")^4
[1] 289
> norm(F[3,], type = "2")^4
[1] 4
I think you're looking for the apply function. It applies a function along the dimensions of a matrix.
sum(apply(F,MARGIN = 1,function(x){norm(x,type = "2")^4}))
#[1] 7017
The reason yours doesn't work is because you assigned c(1,2,3) to i. Then, when you subset F, you just get the whole matrix.
i=1:NROW(F)
i
#[1] 1 2 3
norm(F,type="2")^4
#[1] 7376.602
norm(F[1:3,],type="2")^4
#[1] 7376.602
norm(F[i,],type="2")^4
#[1] 7376.602
Disclaimer: I have not assessed the mathematical validity of this approach, only programmatically recreated the OP's desired behavior.
I have an R loop that has been giving me error. Here are the dimensions of the matrices..
> dim(A)
[1] 2 2
> dim(backward)
[1] 6848 2
I am trying to run this loop and get the following error:
for (i in t:1){
backward[i,]=A%*%t(backward[i,])}
Error in A %*% t(backward[i, ]) : non-conformable arguments
Where t equals 6848. Thanks for your time.
EDIT with bgoldst code:
> A
[,1] [,2]
[1,] 0.8 0.2
[2,] 0.2 0.8
> backward <- matrix(1:(t*2),t,2);
> dim(backward)
[1] 6848 2
> for (i in t:1) backward[i,] <- A%*%t(backward[i,,drop=F]);
Error in A %*% t(backward[i, , drop = F]) : non-conformable arguments
I'm guessing that your expectation of
backward[i,]
is that it will return a 1x2 matrix, which you would be able to use as the operand of a matrix multiplication. This is incorrect. In R, when you specify a single index within a dimension of a matrix, then by default, R will "drop" that dimension. In the case of the above piece of code, the row dimension is dropped, and you end up with a vector, whose contents are taken from all columns along the indexed row. A vector is not a valid operand to a matrix multiplication.
You can solve this problem by providing the drop argument to the [ operation:
A <- matrix(1:(2*2),2,2);
backward <- matrix(1:(6848*2),6848,2);
t <- nrow(backward); for (i in t:1) backward[i,] <- A%*%t(backward[i,,drop=F]); ## no error
Here's a demo of the effect of drop=F:
backward[1,]
## [1] 20548 27398
backward[1,,drop=F]
## [,1] [,2]
## [1,] 20548 27398
See ?`[` for more info.
Here's a solution that doesn't depend on the drop=F argument:
for (i in t:1) backward[i,] <- A%*%t(matrix(backward[i,],1));
I want to get the column means for the last list element, which is a sparse matrix multiplied times a regular matrix. Whenever I use colMeans, however, I get an error. For example:
# Use the igraph package to create a sparse matrix
library(igraph)
my.lattice <- get.adjacency(graph.lattice(length = 5, dim = 2))
# Create a conformable matrix of TRUE and FALSE values
start <- matrix(sample(c(TRUE, FALSE), 50, replace = T), ncol = 2)
# Multiply the matrix times the vector, and save the results to a list
out <- list()
out[[1]] <- my.lattice %*% start
out[[2]] <- my.lattice %*% out[[1]]
# Try to get column means of the last element
colMeans(tail(out, 1)[[1]]) # Selecting first element because tail creates a list
# Error in colMeans(tail(out, 1)[[1]]) :
# 'x' must be an array of at least two dimensions
# But tail(out, 1)[[1]] seems to have two dimensions
dim(tail(out, 1)[[1]])
# [1] 25 2
Any idea what's causing this error, or what I can do about it?
It looks like explicitly calling the colMeans function from the Matrix package works:
> Matrix::colMeans(tail(out, 1)[[1]])
# [1] 4.48 5.48
Thanks to user20650 for this suggestion.
I ran into an unexpected (to me) behavior with how R (R-3.0.3) handles Inf within a matrix.
scalar <- 1
mat1 <- matrix(0)
mat2 <- matrix(1)
mat2 <- -log(mat2)
# > mat1
# [,1]
# [1,] 0
#
# > mat2
# [,1]
# [1,] 0
(mat1[1,1] - scalar[1])/mat1[1,1]
# [1] -Inf
(mat2[1,1] - scalar[1])/mat2[1,1]
# [1] Inf
Why don't both give -Inf? I do not see anything the help file for matrix. I also could not tell a difference between mat1 and mat2 using class, str or dput.
I'll just summarize the discussion on the comments to close out the question.
First, this behavior is not specific to matrices, observe
a<- 0; (a-1)/a
# [1] -Inf
a<- -log(1); (a-1)/a
# [1] Inf
but rather is it a result of the intricacies of IEEE floating point arithmetic. Despite the fact that
-log(1) == 0
# [1] TRUE
zero can actually hold a sign. There is a "+0" and a "-0" and -log(1) returns the latter. Adding +0 to a negative zero value should make it a "regular" zero.
a<- -log(1)+0; (a-1)/a
# [1] -Inf