learning R programming recently, here's a exercise I cannot figure it out.
This program that asks the user for the 8 values of a 2 2x2 mathematical matrix. Another words, there are 4 values in one 2x2 matrix and another 4 values for the
second matrix.
Then the program should has the user if they want to add, subtract, multiple or divided the 2 matrices. Print the record.
Please see attached for the sample output.
Sample output
I'm a biginner in R programming and I don't speak english very well, but I'll try to explain to you.
First, you can create matrices lik Amar did :
m1 <- matrix( rep(2,4) , ncol = 2) #rep(x,n) : repeat x n times
m2 <- matrix( c(2,3,5,6) , nrow = 2 , ncol = 2) #Personaly I prefer to precise the number of rows and columns
> m1
[,1] [,2]
[1,] 2 2
[2,] 2 2
> m2
[,1] [,2]
[1,] 2 5
[2,] 3 6
The operations
You can use "traditional" operations on matrices : + - * /
But you have to know that operations are applied on matrix's elements one by one
consider that m3 = m1*m2 ; that means that m3[i,j] = m1[i,j]*m2[i,j]
m3 <- m1*m2
[,1] [,2]
[1,] 4 10
[2,] 6 12
This is clearly not what is matrices multiplication in mathematics
N.B.: the classic addition (+) is correct
For matrices multiplication you have to use the operation %*%
> m4 <- m1%*%m2
> m4
[,1] [,2]
[1,] 10 22
[2,] 10 22
Fo division don't use the operation %/% because it's not division but modulus. and it returnus modulus applied to matrices elements one by one. m5 = m1%/%m2 means m5[i,j]=m1[i,j]%/%m2[i,j]
> m5 <- m1%/%m2
> m5
[,1] [,2]
[1,] 1 0
[2,] 0 0
Please note that in mathematics the division is not applied on matrices. If you have the equation m6*m2 = m1 then m6 = m1*inverse(m2)
to inverse a matrix you have to install the package matlib :
install.packages("matlib")
> m6 <- m1*inv(m2)
> m6
[,1] [,2]
[1,] -4 3.333333
[2,] 2 -1.333333
Important ! to inverse a matrix, the determinant should be different from 0 :
> det(m2)
[1] -3
> inv(m2)
[,1] [,2]
[1,] -2 1.6666667
[2,] 1 -0.6666667
> det(m1)
[1] 0
> inv(m1)
Error in Inverse(X, tol = sqrt(.Machine$double.eps), ...) :
X is numerically singular
In R, if you have a matrix:
m1 <- matrix(c(2,2,2,2), ncol = 2)
m2 <- matrix(c(4,4,4,4), ncol = 2)
and you want to add/subtract/divide/multiple the two you simply:
m1 + m2
[,1] [,2]
[1,] 6 6
[2,] 6 6
If you store the inputted values in a list, you can refer to it inside the matrix function as above:
matrix(user_input, ncol = 2)
#or
matrix(c(ui1, ui2, ui3, ui4), ncol = 2)
To ask for user-input, look at this SO answer: Creating a Prompt/Answer system to input data into R
Related
I want to use CVXR to find the optimal values of a vector. In the objective function i need to multiply a matrix with a vector in an elementwise way:
b: Nx1 vector
X: Nxp matrix
result: Nxp matrix
Example:
# Set the dims
N <- 50
p <- 5
X <- matrix(rnorm(N*p), N, p)
# to find the optimal values using optim() one could simply have a numeric object
# say the optimal values are 0.1, -0.2, 0.3, -0.5, 0.6
b <- c(0.1, -0.2, 0.3, -0.5, 0.6)
# Then we can have the Nxp matrix with the product
# (where column i of X is multiplied by element i of b) is given by
X*b
b is the vector of coefficient to be optimised.
Using CVXR one must declare
b <- Variable(p)
as Variable object with uses the matrix form, therefore later we can't really multiply as in the previous case.
Also, we don't want to create a matrix of b: Nxp because we need to have one optimal value for all N observations of the i-th column (therefore the mul_elemwise(X, X*b) option wouldn't work as it would give different optimal values for different observations of N - if I am not mistaken).
thanks,
To recap: this is the R behavior:
> m <- 2
> n <- 3
> A <- matrix(c(1,2,3,4,5,6),m,n)
> A
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
> x <- c(1,2)
> A*x
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 4 8 12
>
This is essentially
A[i,j]*x[i]
R behind the scenes extends (recycles) x to have it as many elements as A and then does elementwise multiplication in a columnwise fashion.
In CVXR things are a bit different. %*% is for matrix multiplication and * is for elementwise multiplication. But CVXR does not do this recycling. So for A*x it requires A and x to have the same shape (i.e. an (mxn) matrix).
This means we need to do this extending (recycling) ourselves. This can be written as follows:
> x %*% t(rep(1,n))
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 2 2 2
So we can write:
> A * (x %*% t(rep(1,n)))
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 4 8 12
This is what we can use in the CVXR model:
> library(CVXR)
> x <- Variable(m)
> Y <- Variable(m,n)
> e <- t(rep(1,n))
> e
[,1] [,2] [,3]
[1,] 1 1 1
> problem <- Problem(Minimize(0),list(x == c(1,2), Y == A * (x %*% e)) )
> sol <- solve(problem)
> sol$status
[1] "optimal"
> sol$getValue(x)
[,1]
[1,] 1
[2,] 2
> sol$getValue(Y)
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 4 8 12
>
I would like to compute the product between the each row of a matrix x with itself. And then sum the result of all these products. The result is a scalar. I make the following coda that works but is not efficient. Can someone help me to avoid the for loop?
for(i in 1:nrow(x){
resid2[i] <- t(x[i,])%*% x[i,]
}
V = sum(resid2)/
The solution is just the sum of squares of all elements of the matrix.
V = sum(x^2)
which can also be calculated via matrix multiplication as:
V = crossprod(as.vector(x))
The intermediate vector resid2 can be calculated as
resid2 = rowSums(x^2)
V = sum(resid2)
Here is an answer that swaps the for loop out for the apply family.
sum(apply(x, margin = 1, function(z) z%*%z))
The apply function takes the matrix x, margin = 1 means for each row (as opposed to margin = 2 which means each column). So, for each row in x run a function that multiplies that row by itself: function(z) z%*%z
If I understand you correctly, you don't need to loop at all. mat %*% mat should do it:
mat <- matrix(seq.int(9), nrow=3)
mat
## [,1] [,2] [,3]
## [1,] 1 4 7
## [2,] 2 5 8
## [3,] 3 6 9
mat %*% mat
## [,1] [,2] [,3]
## [1,] 30 66 102
## [2,] 36 81 126
## [3,] 42 96 150
I want to loop an equation through a matrix and store the results in a cube, so that Cube[,,1] is one result of the matrix.
I currently have written the following
PercentileReturn <- array(NA, c(RetAge,length(Percentile)+1,nrow(Demo)))
for (i in 1:nrow(Demo)) {
PercentileReturn[,,i] <-
PercentileReturn[Demo[i,3]:RetAge,
1:length(Percentile),1]<-
t(apply((apply(AnnualReturns[(Demo[i,3]):RetAge,],2,cumprod)) *
Demo[i,4],1,function(x){quantile(x, Percentile, na.rm=T)}))
}
and it results in the following error
Error in PercentileReturn[, , i] <- PercentileReturn[Demo[i, 3]:RetAge, :
number of items to replace is not a multiple of replacement length
I assume it's because the Matrix I am trying to plug in isn't in 3 dimensions.
Basically a stripped down version would be to have an
array(NA,c(2,2,3)) populated with a matrix times a vector
so that say
Matrix * vector c(1,2,3)
[,1] [,2]
[1,] 4 4
[2,] 4 4
would result in the following cube
, , 1
[,1] [,2]
[1,] 4 4
[2,] 4 4
, , 2
[,1] [,2]
[1,] 8 8
[2,] 8 8
, , 3
[,1] [,2]
[1,] 12 12
[2,] 12 12
That will do it:
M <- matrix(1:4,2) # in your example M <- matrix(4, 2,2)
x <- 1:3
array(sapply(x, function(xi) M*xi), c(dim(M), length(x)))
I found the error the first
PercentileReturn[,,i]
has to also match the dimensions of the loop data below written as
PercentileReturn[Demo[i,3]:RetAge,1:length(Percentile),i]
Thanks Jogo, I will be using something similar to what you wrote in another issue down the line.
I teach mathematics and programming (with R) at university and I am a big fan of a good and consistent notation. Please have a look at the following simple vector operations in R:
> v1 <- c(1,2,3)
> v2 <- c(4,5,6)
> v1 %*% v2
[,1]
[1,] 32
> t(v1) %*% v2
[,1]
[1,] 32
> v1 %*% t(v2)
[,1] [,2] [,3]
[1,] 4 5 6
[2,] 8 10 12
[3,] 12 15 18
> t(v1) %*% t(v2)
Error in t(v1) %*% t(v2) : non-conformable arguments
> v1 + v2
[1] 5 7 9
> v1 + t(v2)
[,1] [,2] [,3]
[1,] 5 7 9
> t(v1) + t(v2)
[,1] [,2] [,3]
[1,] 5 7 9
I think there are some inconsistencies here: Either I am missing something or R seems to be quite arbitrary with respect to what results you get when you either transpose a vector or not.
What is the underlying logic here (which seems to be completely different than Matlab by the way).
?%*% gives the logic:
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 it
will return the inner product (as a matrix).
If they're both vectors (first example), then you get the inner product. If you put a t( ) in there, the vector will get cast as a column matrix, and a vector is effectively a row matrix, so normable conformable rules apply.
Similarly, the help page for "+" says that it will cast the arguments to vectors - and gives some guidance on the 'shape' of the result.
I want to be able to add a value (in my code nug) to the i,j entry of a matrix where i = j (so like a Kronecker delta function). Its very easy to do when the matrix is square (see my code below) however I am not sure how to do it in one line when the matrix is not square
nug = 2
R = tau + diag(nug,nrow(tau))
The above code works when tau is a square matrix but now imagine that tau is not square. How would I add nug to each of the i,j elements of tau where i = j?
m <- matrix(1:6, ncol = 2)
m
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
diag(m) <- diag(m) + 1:2
m
[,1] [,2]
[1,] 2 4
[2,] 2 7
[3,] 3 6
You can do this :
m[col(m)==row(m)] <- m[col(m)==row(m)] +nug
Using a matrix of zeros to show this:
m <- matrix(rep(0,6), ncol = 2)
> m[col(m)==row(m)] <- m[col(m)==row(m)] +2
> m
[,1] [,2]
[1,] 2 0
[2,] 0 2
[3,] 0 0