How can I state, in R code, a list of certain possible values for a given equation? For example (this is just a random equation feel free to use any formula suitable):
For positive integers a, b, and c with the formula x^3 + y^2 = z.
How can I test for all possible combinations of x and y less than or equal to 1000 and c to satisfy the formula and check if the variables are also valid inputs?
You can generate all possible values with expand.grid and then subset to the ones meeting your criteria:
vals <- expand.grid(x=seq(1000), y=seq(1000))
subset(vals, x^3 + y^2 == 108)
# x y
# 8003 3 9
# 9002 2 10
Related
I have an expression that contains several parts. However, for simplicity, consider only the following part as MWE:
Let's assume we have the inverse of a matrix Y that I want to differentiate w.r.t. x.
Y is given as I - (x * b * t(b)), where I is the identity matrix, x is a scalar, and b is a vector.
According to The Matrix Cookbook Equ. 59, the partial derivative of an inverse is:
Normally I would use the function D from the package stats to calculate the derivatives. But that is not possible in this case, because e.g. solve to specify Y as inverse and t() is not in the table of derivatives.
What is the best workaround to circumvent this problem? Are there any other recommended packages that can handle such input?
Example that doesn't work:
f0 <- expression(solve(I - (x * b %*% t(b))))
D(f0, "x")
Example that works:
f0 <- expression(x^3)
D(f0, "x")
3 * x^2
I assume that the question is how to get an explicit expression for the derivative of the inverse of Y with respect to x. In the first section we compute it and in the second section we double check it by computing it numerically and show that the two approaches give the same result.
b and the null space of b are both eigenspaces of Y which we can readily verify by noting that Yb = (1-(b'b)x)b and if z belongs to the nullspace of b then Yz = z. This also shows that the corresponding eigenvalues are 1 - x(b'b) with multiplicity 1 and 1 with multiplicity n-1 (since the nullspace of b has that dimension).
As a result of the fact that we can expand such a matrix into the sum of each eigenvalue times the projection onto its eigenspace we can express Y as the following where bb'/b'b is the projection onto the eigenspace spanned by b and the part pre-multiplying it is the eigenvalue. The remaining terms do not involve x because they involve an eigenvalue of 1 independently of x and the nullspace of b is independent of x as well.
Y = (1-x(b'b))(bb')/(b'b) + terms not involving x
The inverse of Y is formed by taking the reciprocals of the eigenvalues so:
Yinv = 1/(1-x(b'b)) * (bb')/(b'b) + terms not involving x
and the derivative of that wrt x is:
(b'b) / (1 - x(b'b))^2 * (bb')/(b'b)
Cancelling the b'b and writing the derivative in terms of R code:
1/(1 - x*sum(b*b))^2*outer(b, b)
Double check
Using specific values for b and x we can verify it against the numeric derivative as follows:
library(numDeriv)
x <- 1
b <- 1:3
# Y inverse as a function of x
Yinv <- function(x) solve(diag(3) - x * outer(b, b))
all.equal(matrix(jacobian(Yinv, x = 1), 3),
1/(1 - x*sum(b*b))^2*outer(b, b))
## [1] TRUE
So I'm having hard time coding the above equation, mainly the part which contains that double sum over i's and over j.
I'n my case, my n = 200 and p = 15. My yi:s are in a vector Y = (y1,y2,...yn) that is vector of length 200 and Xij:s are in a matrix which has 15 columns and 200 rows. Bj:s are in a vector of length 15.
My own solution, which I'm fairly certain is wrong, is this:
b0 <- 1/200 * sum(Y - sum(matr*b))
And here is code which you can use to reproduce my vectors and matrix:
matr <- t(mvrnorm(15,mu= rep(0,200),diag(1,nrow = 200)))
Y <- rnorm(n = 200)
b <- rnorm(n = 15)
Use matrix multiplication:
mean(y - x %*% b)
Note that if y and x are known and b is the least squares regression estimate of the coefficients then we can write it as:
fm <- lm(y ~ x + 0)
mean(resid(fm))
and that necessarily equals 0 if there is an intercept, i.e. a constant column in x, since the residual vector must be orthogonal to the range of x and taking the mean is the same as taking the inner product of the residuals and a vector whose elements are all the same (and equal to 1/n).
Does anyone know how to generate matrix with certain rank in R?
I ultimately want to create data matrix Y = X + E
where rank(X)=k and E~i.i.d.N(0,sigma^2).
The easiest is the identity matrix, which has always full rank. So e.g. use:
k <- 10
mymatrix <- diag(k)
Here, rows and columns are equal to the rank you specify
I suppose you want to mimic a regression model, so you might want to have more rows (meaning 'observations') than columns, (e.g. 'variables'). The following code allows you to specify both:
k <- 5 # rank of your matrix
nobs <- 10 # number of lines within X
X <- rbind(diag(k), matrix(rep(0,k*(nobs-k)), ncol=k))
y <- X + rnorm(nobs)
Note, that X - and therefore also y - now have full column rank. there is no multicollinearity in this 'model'.
I wonder if there is a function that can do addition or subtraction operator randomly:
x +- y
The question boils down to getting -1 or 1 in random fashion. You can get it using sample:
x + sample(c(-1,1),size=1)*y
or runif:
x + sign(runif(n=1,min=-1,max=1))*y
If x and y are vectors, you can generate sequence of numbers -1 and 1 of the same length as the length of x, as #BondedDust suggested:
x + sample(c(-1,1),size=length(x),replace=T)*y
I'm new to R and I need to plot the quadratic matrix equation:
x^T A x + b^T x + c = 0
in R^2, with A being a 2x2, b a 2x1, and c a constant. The equation is for a boundary that defines classes of points. I need to plot that boundary for x0 = -6...6, x1 = -4...6. My first thought was generate a bunch of points and see where they are zero, but it depends on the increment between the numbers (most likely I'm not going guess what points are zero).
Is there a better way than just generating a bunch of points and seeing where it is zero or multiplying it out? Any help would be much appreciated,
Thank you.
Assuming you have a symmetric matrix A,
eg
# A = | a b/2 |
# | b/2 c |
and your equation represents a conic section, you can use the conics package
What you need is a vector of coefficients c(a,b,c,d,e,f) representing
a.x^2 + b*x*y + c*y^2 + d*x + e*y + f
In your case, say you have
A <- matrix(c(2,1,1,2))
B <- c(-20,-28)
C <- 10
# create the vector
v <- append(c(diag(A),B,C),A[lower.tri(A)]*2), 1)
conicPlot(v)
You could easily wrap the multiplication out into a simple function
# note this does no checking for symmetry or validity of arguments
expand.conic <- function(A, B, C){
append(c(diag(A),B,C),A[lower.tri(A)]*2), 1)
}