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!
Related
I have been trying to figure out the core part of the varimax function in R. I found a wiki link that writes out the algorithm. But why is B <- t(x) %*% (z^3 - z %*% diag(drop(rep(1, p) %*% z^2))/p) is computed? I also am not sure as to why SVD is computed of the matrix B. The iteration step is probably to maximize/minimize the variance, and the singular values would really be variances of Principal Components. But I am also unsure about that. I am pasting the whole code of varimax for convenience, but really the relevant part and therefore my question on what is actually happening under the hood, is within the for loop.
function (x, normalize = TRUE, eps = 1e-05)
{
nc <- ncol(x)
if (nc < 2)
return(x)
if (normalize) {
sc <- sqrt(drop(apply(x, 1L, function(x) sum(x^2))))
x <- x/sc
}
p <- nrow(x)
TT <- diag(nc)
d <- 0
for (i in 1L:1000L) {
z <- x %*% TT
B <- t(x) %*% (z^3 - z %*% diag(drop(rep(1, p) %*% z^2))/p)
sB <- La.svd(B)
TT <- sB$u %*% sB$vt
dpast <- d
d <- sum(sB$d)
if (d < dpast * (1 + eps))
break
}
z <- x %*% TT
if (normalize)
z <- z * sc
dimnames(z) <- dimnames(x)
class(z) <- "loadings"
list(loadings = z, rotmat = TT)
}
Edit: The algorithm is available in the book "Factor Analysis of Data Matrices" by Holt, Rinehart and Winston and the actual sources can be found therein. This book is also cited with the varimax function in R.
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))
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.
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))
}
I am not able to apply ucminf function to minimise my cost function in R.
Here is my cost function:
costfunction <- function(X,y,theta){
m <- length(y);
J = 1/m * ((-t(y)%*%log(sigmoid(as.matrix(X)%*%as.matrix(theta)))) - ((1-t(y))%*%log(1-sigmoid(as.matrix(X)%*%as.matrix(theta)))))
}
Here is my sigmoid function:
sigmoid <- function(t){
g = 1./(1+exp(-t))
}
Here is my gradient function:
gradfunction <- function(X,y,theta){
grad = 1/ m * t(X) %*% (sigmoid(as.matrix(X) %*% as.matrix(theta) - y));
}
I am trying to do the following:
library("ucminf")
data <- read.csv("ex2data1.txt",header=FALSE)
X <<- data[,c(1,2)]
y <<- data[,3]
qplot(X[,1],X[,2],colour=factor(y))
m <- dim(X)[1]
n <- dim(X)[2]
X <- cbind(1,X)
initial_theta <<- matrix(0,nrow=n+1,ncol=1)
cost <- costfunction(X,y,initial_theta)
grad <- gradfunction(X,y,initial_theta)
This is where I want to call ucminf to find the minimum cost and values of theta. I am not sure how to do this.
Looks like you are trying to do the week2 problem of the machine learning course of Coursera.
No need to use ucminf packages here, you can simply use the R function optim it works
We will define the sigmoid and cost function first.
sigmoid <- function(z)
1 / (1 + exp(-z))
costFunction <- function(theta, X, y) {
m <- length(y)
J <- -(1 / m) * crossprod(c(y, 1 - y),
c(log(sigmoid(X %*% theta)), log(1 - sigmoid(X %*% theta))))
grad <- (1 / m) * crossprod(X, sigmoid(X %*% theta) - y)
list(J = J, grad = grad)
}
Let's load the data now, to make this code it reproductible, I put the data in my dropbox.
download.file("https://dl.dropboxusercontent.com/u/8750577/ex2data1.txt",
method = "curl", destfile = "/tmp/ex2data1.txt")
data <- matrix(scan('/tmp/ex2data1.txt', what = double(), sep = ","),
ncol = 3, byrow = TRUE)
X <- data[, 1:2]
y <- data[, 3, drop = FALSE]
m <- nrow(X)
n <- ncol(X)
X <- cbind(1, X)
initial_theta = matrix(0, nrow = n + 1)
We can then compute the result of the cost function at the initial theta like this
cost <- costFunction(initial_theta, X, y)
(grad <- cost$grad)
## [,1]
## [1,] -0.100
## [2,] -12.009
## [3,] -11.263
(cost <- cost$J)
## [,1]
## [1,] 0.69315
Finally we can use optim to ge the optimal theta
res <- optim(par = initial_theta,
fn = function(t) costFunction(t, X, y)$J,
gr = function(t) costFunction(t, X, y)$grad,
method = "BFGS", control = list(maxit = 400))
(theta <- res$par)
## [,1]
## [1,] -25.08949
## [2,] 0.20566
## [3,] 0.20089
(cost <- res$value)
## [1] 0.2035
If you have some problem with the function download.file, the data can be downloaded
here
As you did not provide a reproducible example it is hard to exactly give you the code you need, but the general idea is to hand the functions over to ucminf:
ucminf(start, costfunction, gradfunction, y = y, theta = initial_theta)
Note that start needs to be a vector of initial starting values which when handed over as X to the two functions need to produce a result. Usually you use random starting value (e.g., runif).