Eigenvector Order in R - r

I am trying to work out an issue regarding the order of eigenvectors returned by eigen in r. Consider the following:
covmatrix <- matrix(data = c(13, 5, 2, 4), nrow = 2, ncol = 2)
covmatrix
eigen <- eigen(covmatrix)
eigen
The output returns:
values
[1] 14 3
vectors
[,1] [,2]
[1,] 0.8944272 -0.1961161
[2,] 0.4472136 0.9805807
Per the documentation, the first column should represent the eigenvector associated with the largest eigenvalue. However, mathematically, when I calculate the eigenvectors I end up with column 2 associated with the eigenvalue 14 as 0.9805807 is 5 times 0.1961161. The math is detailed here. I'm sure I am missing something simple but can't quite work it out.

You are not working with the same matrix. To get consistent result with what you derive analytically, you need
covmatrix <- matrix(data = c(13, 5, 2, 4), nrow = 2, ncol = 2, byrow = TRUE)
eigen(covmatrix)
$values
[1] 14 3
$vectors
[,1] [,2]
[1,] 0.9805807 -0.4472136
[2,] 0.1961161 0.8944272

Related

Find out if input is a Toeplitz Matrix in R

Given a random matrix (any size!), write a function that determines whether or not that matrix is a Toeplitz Matrix. In linear algebra, a Toeplitz matrix is one in which the elements on any given diagonal from top left to bottom right are identical.
Here is an example:
x <- structure(c(1, 5, 4, 7, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 8,
4, 3, 2), .Dim = 4:5)
[,1] [,2] [,3] [,4] [,5]
[1,] 1 2 3 4 8
[2,] 5 1 2 3 4
[3,] 4 5 1 2 3
[4,] 7 4 5 1 2
So our function should receive such matrix and return TRUE if it meets the conditions.
To test the function, one can use stats::toeplitz() to generate a toeplitz matrix. So for example, the expected output of our function should be:
> toeplitz_detector(stats::toeplitz(sample(5, 5)))
> [1] TRUE
I've solved the problem by defining the following function:
toeplitz_solver <- function(a) {
# re-order a backwards, because we need to check diagonals from top-left
# to bottom right. if we don't reorder, we'll end up with top-right to
# bottom-left.
a <- a[, ncol(a):1]
# get all i and j (coordinates for every element)
i <- 1:nrow(a)
j <- 1:ncol(a)
# get all combinations of i and j
diags <- expand.grid(i, j)
# the coordinates for the diagonals are the ones where
# the sum is the same, e.g.: (3,2), (4,1), (2,3), (1,4)
sums <- apply(diags, 1, sum)
indexes <- lapply(unique(sums), function(x) {
diags[which(sums == x), ]
})
# indexes is now a list where every element is a list of coordinates
# the first element is a list for every coordinates for the first diag
# so on and so forth
results <- sapply(indexes, function(x) {
y <- a[as.matrix(x)]
return(all(y == y[1]))
})
# if every diagonal meets the condition, it is safe to assume that the
# input matrix is in fact toeplitz.
return(all(results))
}

What are the default values for nrow and ncol in R's matrix function?

What are the default values for the arguments nrow and ncol in the function matrix in R?
In order words: By writing
matrix(c(1,2,3,4,5,6), ncol=2)
I can make the function matrix automatically calculate how many rows the resulting matrix will have, and the output will be
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
However, if I want ncol to be a positional argument in this function call and I simply remove ncol=, that is
matrix(c(1,2,3,4,5,6), 2)
the "2" is going to end up as the value of nrow and not as the value of ncol, and I will instead get the matrix
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
I can fix this by providing the function a value for nrow so that the 2 is pushed to its correct position, like so:
matrix(c(1,2,3,4,5,6), 3, 2)
and I will get the desired matrix again. I could also use this method of providing a value for nrow if I were using a keyword argument for ncol, but at the same time wanted to be clear and provide the nrow argument as well:
matrix(c(1,2,3,4,5,6), nrow=3, ncol=2)
But now matrix doesn't calculate the number of rows for me, but I have to calculate it myself. What value should I write instead of 3 if I want tell matrix to calculate the number of rows itself? I've tried replacing the 3 with NULL, None (usually works in cases like this in Python), and -1 but these all give me errors (and 0 and 1 give me matrices with 0 rows and 1 row, respectively).
We can place a , before
matrix(c(1,2,3,4,5,6), ,2)
Here, the , is placed based on the argument order in the function. If we check ?matrix, the usage is
matrix(data = NA, nrow = 1, ncol = 1, byrow = FALSE, dimnames = NULL)
Note, that most of the argument have default values. It is always better to pass function argument with names, but if we want to skip, can use the right number of , (also depends on the function behavior). Here, we can set the dimnames as well after skipping the byrow argument with a ,
matrix(c(1,2,3,4,5,6), ,2, ,list(NULL, c('a', 'b')))
# a b
#[1,] 1 4
#[2,] 2 5
#[3,] 3 6

Calculating exp() of each element in matrix using R

how can I take exp() of each element in a matrix? I have mymatrix = matrix(c(2, 4, 3, 1, 5, 7), 3,2) and tried using res<-expm(mymatrix) but it requires mymatrix to be square. Is there another way to calculate each element so
res is matrix(c(exp(2), exp(4), exp(3), exp(1), exp(5), exp(7), 3,2) ?
res <- mymatrix
res [] <- exp(res)
> res
[,1] [,2]
[1,] 7.389056 2.718282
[2,] 54.598150 148.413159
[3,] 20.085537 1096.633158
Here you go.

Determining Whether a Matrix Has At Least One Zero Element

I'm sure this is trivial - nonetheless, any help would be appreciated.
The problem is simple: given a matrix, I'd like to get TRUE if the matrix in question has at least one element equal to zero. So, checking
A <- matrix(c(1, 2, 3, 4, 5, 0), nrow = 2, ncol = 3, byrow = TRUE)
> A
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 0
would return TRUE, while
B <- matrix(c(1, 2, 3, 4, 5, 6), nrow = 2, ncol = 3, byrow = TRUE)
> B
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
would return FALSE.
Something like
if ( A == 0 ) { cat("\nZero detected")}
gives a warning. Is there a simple way to do this?
The warning is generated because you're presenting a vector of logical to if, which expects a single value. any is a function to tell if any of the logical values are TRUE:
any(A==0)
## [1] TRUE
any(B==0)
## [1] FALSE
There's also a function all which determines if all of the values in a logical vector are TRUE.
Try
0 %in% A
It should return TRUE or FALSE. It works for NA too:
x = matrix(1:24, ncol = 4)
x[3, 3] = NA
NA %in% x
#TRUE

R: Generating random points with different mean and sd for each attribute

Is there any way in R, other than with loops, to create a matrix using different means and standard deviations for the matrix's columns?
For example, I want to create a 3x4 matrix representing 3 points with 4 attributes each, such that every column (every attribute) has its own mean and sd.
Yes, you can do without loops. Take advantage of the fact that matrices in R are stored in column-major order, and replicate the mean and sd vectors to match.
means <- c(1, 10, 100, 1000)
sds <- c(0.1, 1, 10, 100)
rows <- 3
cols <- 4
m <- matrix(rnorm(rows*cols, m=rep(means, each=rows), s=rep(sds, each=rows)),
rows, cols)
m
[,1] [,2] [,3] [,4]
[1,] 0.9993278 11.694798 105.53191 841.2182
[2,] 0.8945916 9.556729 92.90462 1212.6817
[3,] 0.9889313 10.088022 113.67009 991.2138
I am not sure what you are looking for but this might help:
matrix(c(x = rnorm(n=3,mean=0.5,1),
y = rnorm(n=3,mean=2, 4),
z = rnorm(n=3, mean=3.5, 10),
a= rnorm(n=3,mean=5,12)),nrow=3,ncol=4)
[,1] [,2] [,3] [,4]
[1,] 0.7876793 2.9456827 8.082376 -3.065875
[2,] -0.9956971 4.2766553 14.178532 -5.003888
[3,] 2.1224071 0.7110594 6.744876 -11.006110
Note: you might bet different results as the data is randomly generated. Each column has its own mean and standard deviation.

Resources