In the following code I'm trying to use the function norm.dem to generate a contour plot of the points given by x and y. I can't seems to figure out how to do this. I've tried everything I could think of. For some reason the function isn't letting me put in values of sequence. Shouldn't the outer function give me a list of values?
x=seq(-10,10,length=1000)
y=seq(-10,10,length=1000)
sigma <- matrix(c(10,-5,-5,20), ncol=2)
sigma
norm.den=function(x,y,sigma,mu)
{
j<-c(x,y)
k=j-mu
t<-t(k)
s<-solve(sigma)
d<-det(sigma)
((2.718)^(-t%*%s%*%k/2))/(2*(3.14)*sqrt(d))
}
z=outer(x,y,norm.den,sigma=sigma,mu=c(0,0))
Forcibly using for() loops works.
normden <- function(x, y, solvsig=ss, detsig=ds, mu=c(0, 0)) {
k <- c(x, y) - mu
tk <- t(k)
(exp(-tk %*% ss %*% k / 2)) / (2*pi*sqrt(ds))
}
sigma <- matrix(c(10, -5, -5, 20), ncol=2)
ss <- solve(sigma)
ds <- det(sigma)
x <- seq(-10, 10, length=10)
y <- seq(-10, 10, length=10)
z <- array(dim=c(length(x), length(x)))
for(i in seq(x)) {
for(j in seq(y)) {
z[i, j] <- normden(x=x[i], y=y[j])
}}
z
I couldn't get outer() to work with the normden() function. Don't know why.
outer(x, y, "normden")
I get the same error that the OP mentioned, Error in -tk %*% ss : non-conformable arguments.
Related
I am new to R. As simple as the question sounds, I haven't been able to find a simple way of doing it in the documentation. So far, the best way I've come up, to generate Z is the below. But surely there is some built in function.
Example for the function
grid_size <- 10
x <- seq(0,1,length.out =grid_size)
y <- seq(0,1,length.out =grid_size)
xgrid <- matrix(x, nrow=grid_size, ncol=grid_size, byrow=TRUE)
ygrid <- matrix(x, nrow=grid_size, ncol=grid_size, byrow=FALSE)
f2v <- function(xgrid, ygrid) {
return (1 - xgrid + xgrid*ygrid)
}
Z <- f2v(xgrid, ygrid)
Thank you.
Use outer:
grid_size <- 10
x <- seq(0 ,1, length.out = grid_size)
y <- seq(0, 1, length.out = grid_size)
t(outer(x, y, function(x,y) 1 - x + x*y))
I am trying to create an empirical histogram of eigenvalue spacing for random matrices using loop. Seems simple but not working so far... I am getting this error: "Error in M[k] <- (c(x[k], y[k], y[k], z[k])) :
number of items to replace is not a multiple of replacement length.”
I tried writing M[ ,k] but I still got the same error. If anyone can help me with that line, it would be great! Here is my code:
x <- rnorm(1000,0,1)
y <- rnorm(1000,0,1/2)
z <- rnorm(1000,0,1)
M <- matrix(0,2,2)
a <- rep(0,1000)
b <- rep(0,1000)
s <- rep(0,1000)
for(k in 1:1000){
M[k] =(c(x[k],y[k],y[k],z[k]))
temp = eigen(M[k])$value
a[k] <- max(temp)
b[k] <- min(temp)
s[k] <- a[k]-b[k]
}
If you are only interested in creating s, you can make your code considerably simpler by using sapply instead of a loop. You create the matrix M for each iteration and return the difference between the maximum and minimum eigenvalue. This will make your vector s without all the intermediate variables.
set.seed(69) # Makes the example reproducible
x <- rnorm(1000, 0, 1)
y <- rnorm(1000, 0, 1/2)
z <- rnorm(1000, 0, 1)
s <- sapply(seq(1000), function(k) {
M <- matrix(c(x[k], y[k], y[k], z[k]), 2, 2)
max(eigen(M)$value) - min(eigen(M)$value)
})
hist(s)
You can even get rid of x, y, z if you just sample as you go:
set.seed(69) # Makes the example reproducible
s <- sapply(seq(1000), function(k) {
M <- matrix(c(rnorm(1), rep(rnorm(1, 0, 1/2), 2), rnorm(1)), 2, 2)
max(eigen(M)$value) - min(eigen(M)$value)
})
hist(s)
I would like to calculate the double integrals on a function with matrix output. My code is here:
foo <- function(x,t){
out1 <- sin(x*t)
out2 <- cos(x*t)
out <- matrix(c(out1,out2),ncol=2)
return(out)
}
library(pracma)
quad2d(foo, xa = 0, xb = 1, ya = 0, yb= 10)
When I run this code, I receive a message:
Error in wx %*% Z : non-conformable arguments
I wonder how I can calculate this double integrals? The 'foo' is just a simple example here; to seperate the 'foo' into two functions is not I want. Thanks in advance!
quad2dapplies Gaussian quadrature internally, but needs the function to be vectorized. Instead, you can apply the quadrature rules explicitly.
Assume the matrix-valued function foo is defined as
foo <- function(x, t)
matrix(c(sin(x*t), cos(x*t), x, t), 2, 2)
Utilize the Gaussian quadrature rules directly like this:
library(pracma)
n <- 32
xa <- 0; xb <- 1; ya <- 0; yb <- 10
cx <- gaussLegendre(n, xa, xb)
x <- cx$x; wx <- cx$w
cy <- gaussLegendre(n, ya, yb)
y <- cy$x; wy <- cy$w
I <- matrix(0, 2, 2)
for (i in 1:n) {
for (j in 1:n) {
I <- I + wx[i] * wy[j] * foo(x[i], y[j])
}
}
I
## [,1] [,2]
## [1,] 2.925257 5
## [2,] 1.658348 50
This may be a bit slower than quad2d as there are two for loops, but may be sufficient if your function is somewhat well behaved.
Of course, all this can be wrapped into a new integration routine like
mquad2d(f, xa, xb, ya, yb, n = 32).
There may be an elegant way to pass a matrix of functions as the first argument of the function quad2d! I don't know that, but I can re-write your code to get the same result:
mquad2d <- function(xa, xb, ya, yb){
fun1 <- function(x,t){
return(sin(x*t))
}
fun2 <- function(x, t){
return(cos(x*t))
}
out1 <- quad2d(fun1, xa, xb, ya, yb)
out2 <- quad2d(fun2, xa, xb, ya, yb)
out <- matrix(c(out1,out2),ncol=2)
return(out)
}
mquad2d(xa = 0, xb = 1, ya = 0, yb= 10)
#output:
# [,1] [,2]
#[1,] 2.925257 1.658348
Hope this helps!
How to plot in R the following function
$l(\theta) = ln(\theta)*\sum{y_i} -n*\theta -n*ln(1-e^{-\theta})-\sum{ln(y_i!)}$
where the summations are from $i=1$ to $n$
I have the data set, but I know how to enter that already.
Something like this:
L <- function(theta, y){
log(theta)*sum(y) -
length(y) *(theta + log(1 - exp(-theta))) -
sum(lfactorial(y))
}
L_theta <- function(theta){
L(theta, y)
}
#example
y <- c(1, 3, 5, 7)
L(2, y)
# [1] -11.4324
plot(L_theta, xlim=c(0, 2), xlab="θ" )
producing something like
Suppose I have the following code:
X <- model.matrix(~factor(1:2))
beta <- c(1, 2)
I then draw 70 and 40 values from two multivariate normal distributions:
library(MASS)
S1 <- mvrnorm(70, mu = c(0,0), Sigma = matrix(c(10, 3, 3, 2), ncol = 2))
S2 <- mvrnorm(40, mu = c(0,0), Sigma = matrix(c(10, 4, 4, 2), ncol = 2))
As can be easily seen S1 is 70x2 matrix und S2 a 40x2 matrix.
Now I build a for loop in R:
z <- list()
for(i in 1:dim(S2)[1]){
z[[i]] <- X %*% beta + X %*% S1[1,] + X %*% S2[i,] + rnorm(2, mean = 0, sd = 0.45)
Y <- do.call(rbind, z)
}
This gives me a matrix that contains all combinations for the 40 elements in S2 with the 1st element of S1. What I want is to completely cross the two matrices S1 and S2. That is I want the for loop to pick out S1[1,] first, then iterate completely through S2[i,] (e.g. in an inner loop) and store the results in a matrix then pick out S1[2,] iterate again through S2[i,] and store the results in a matrix and so on. If I would need to give a name to what I am looking for I would say "crossed for loops". I find it incredibly hard to come up with R-code that will allow me to do this. Any hints would be appreciated.
Maybe the idea will get clearer with this example:
My idea is equivalent to construction 70 for-loops for every element in S1[i,] and binding the result in a 70*40*2x1 matrix:
for(i in 1:dim(S2)[1]){
z[[i]] <- X %*% beta+X %*% S1[1,]+X %*% S2[i,]+rnorm(2, mean = 0 , sd = sigma)
Y1 <- unname(do.call(rbind, z))
}
for(i in 1:dim(S2)[1]){
z[[i]] <- X %*% beta+X %*% S1[2,]+X %*% S2[i,]+rnorm(2, mean = 0 , sd = sigma)
Y2 <- unname(do.call(rbind, z))
}
for(i in 1:dim(S2)[1]){
z[[i]] <- X %*% beta+X %*% S1[3,]+X %*% S2[i,]+rnorm(2, mean = 0 , sd = sigma)
Y3 <- unname(do.call(rbind, z))
}
.
.
.
for(i in 1:dim(S2)[1]){
z[[i]] <- X %*% beta+X %*% S1[70,]+X %*% S2[i,]+rnorm(2, mean = 0 , sd = sigma)
Y70 <- unname(do.call(rbind, z))
}
Y <- rbind(Y1, Y2, Y3, …, Y70)
What I ideally would want is to do this with for-loops or any other flexible way that can handle different dimensions for S1 and S2.
OK. I might do a few things to make this as efficient as possible. First, we can pre-calculate all the matrix multiplication with
Xb <- X %*% beta
XS1 <- X %*% t(S1)
XS2 <- X %*% t(S2)
Then we can clculate all the combinations of the S1/S2 values with expand.grid
idx <- unname(c(expand.grid(A=1:ncol(XS1), B=1:ncol(XS2))))
Then we can define the transformation
fx<-function(a, b) {
t(Xb + XS1[,a, drop=F] + XS2[,b,drop=F] + rnorm(2, mean = 0, sd = 0.45))
}
we assume we will be passed an index for S1 and an index for S2. Then we combine the data as in your formula. Finally, we use this helper function and the indexes with a set of do.calls
xx <- do.call(rbind, do.call(Map,c(list(fx), idx)))
First we use Map to calculate all the combinations, then we use rbind to merge all the results. This actually produces a 2800x2 matrix. (70*40)*2. The rows are ordered with S1 moving the fastest, then S2.
I realised that this was not a problem with for-loops but with the way I stored the variables. The solution to what I want is:
library(MASS)
z <- list()
y <- list()
for(j in 1:dim(S1)[1]){
for(i in 1:dim(S2)[1]){
z[[i]] <- X %*% beta+X %*% S1[j,]+X %*% S2[i,]+matrix(rnorm(2, mean = 0 , sd = sigma), ncol = 2, nrow = 2)
Z <- unname(do.call(rbind, z))
}
y[[j]] <- Z
Y <- unname(do.call(rbind, y))
}