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
>
Related
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
i'm developing a function to perform operations between two vectors (dataframes, for example), using the function "for":
> A <- c(1,2,3)
> B <- c(2)
> result <- c()
> for (i in 1:length(A))
+ {
+ for (j in 1:length(B))
+ {
+ result <- (A*B)
+ }
+ }
> result
[1] 2 4 6
However, when I increase the vector "B" to 2 values:
> A <- c(1,2,3)
> B <- c(2,4)
the function generates
Warning messages lost:
"Major object length is not a multiple of the length of a lower one."
> result
[1] 2 8 6
So, how i can create a loop that performs the operation against "A" for each row "B"?
Thnaks so much!
In your loop, you don't use the variables i and j but calculate the product A * B instead.
You can produce the desired result using sapply:
A=c(1,2,3); B=c(2,4)
sapply(A, "*", B)
# [,1] [,2] [,3]
# [1,] 2 4 6
# [2,] 4 8 12
or matrix multiplication:
A %*% t(B)
# [,1] [,2]
# [1,] 2 4
# [2,] 4 8
# [3,] 6 12
As the error says, A's length has to be a multiple of B's one : if they have the same length, A*Bwill return a vector of same length whose terms will the multiplications of corresponding elements of A and B (A[1]*B[1],...A[n]*B[n]).
If length(A)=k*length(B), k>1, you will get a vector with same length as A with (A[1]*B[1]...A[l]*B[l],A[l+1]*B[1],A[l+2]*B[2]...A[kl]*B[l]), where l is B length and therefore kl is A length.
Here, 3 is a multiple of 1 but not of 2, hence the error you get.
In general, you can use outer:
outer(A, B, FUN='*')
# [,1] [,2]
# [1,] 2 4
# [2,] 4 8
# [3,] 6 12
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
In R, I want to multiply a 1x3 vector by a 3x3 matrix to produce a 1x3 vector. However R returns a matrix:
> v = c(1,1,0)
> m = matrix(c(1,2,1,3,1,1,2,2,1),nrow=3,ncol=3,byrow=T)
> v*m
[,1] [,2] [,3]
[1,] 1 2 1
[2,] 3 1 1
[3,] 0 0 0
The correct output should be a vector, not a matrix
If in doubt, try the help system, here eg help("*") or help("Arithmetic"). You simply used the wrong operator.
R> v <- c(1,1,0)
R> m <- matrix(c(1,2,1,3,1,1,2,2,1),nrow=3,ncol=3,byrow=T)
R> dim(m)
[1] 3 3
R> dim(v)
NULL
R> dim(as.vector(v))
NULL
R> dim(as.matrix(v, ncol=1))
[1] 3 1
R>
R> m %*% as.matrix(v, ncol=1)
[,1]
[1,] 3
[2,] 4
[3,] 4
R>
Note that we have to turn v into a proper vector first. You did not say whether it was 1x3 or 3x1. But luckily R is generous:
R> v %*% m
[,1] [,2] [,3]
[1,] 4 3 2
R> m %*% v
[,1]
[1,] 3
[2,] 4
[3,] 4
R>
Useful functions in this case are crossprod and tcrossprod
> tcrossprod(v, m)
[,1] [,2] [,3]
[1,] 3 4 4
See ?crossprod and ?tcrossprod for details.
Are you looking for
as.vector(v %*% m)
?
Here the documentation of matmult:
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).
R - how to vectorize computation of sum of outer products, when vectors are in two matrices - X and Y ?
Example :
X = cbind(1:3, 2:4)
Y = cbind(0:2, c(0,0,1))
> X
[,1] [,2]
[1,] 1 2
[2,] 2 3
[3,] 3 4
> Y
[,1] [,2]
[1,] 0 0
[2,] 1 0
[3,] 2 1
> outer(X[1,],Y[1,]) + outer(X[2,],Y[2,]) + outer(X[3,],Y[3,])
[,1] [,2]
[1,] 8 3
[2,] 11 4
I would like to vectorize operation :
outer(X[1,],Y[1,]) + outer(X[2,],Y[2,]) + outer(X[3,],Y[3,]) - is it possible ? Mayby something with general construction like : lapply( ,FUN=outer), and then taking sum of elements in list ? Otherwise I have to loop over outer(X[i,],Y[i,]).
This is just matrix multiplication:
t(X) %*% Y
v [,1] [,2]
# [1,] 8 3
# [2,] 11 4
You need a 2*2 matrix and both matrices X and Y are of dimensons 3*2. Transposing X gives 2*3 and when multiplied with 3*2 matrix gives the desired 2*2 matrix.