Code to evaluate an integral: translating from Matlab to R - r

Consider the following Matlab code to approximate integrals using simulation.
function f
numSim = 1000000;
points = rand(numSim,1);
r3 = mean(feval('func3', points));
points1 = rand(numSim,1);
r8 = mean(feval('func8', points, points1));
disp([r3, r8,]);
end %f
%%%%%%%%%% Nested funcitons %%%%%%%%%%%%
function y = func3(x)
y = exp(exp(x));
end %func3
function z = func8(x,y)
z = exp((x+y).^2);
end %func8
What I've tried in R
f <- function (func3,func8){
numSim <- 1000000
points <- runif(numSim)
r3 <- mean(evaluate(points, func3))
points1 <- runif(numSim)
r8 <- mean(evaluate( points1,func8))
newList<-list(r3,r8)
return(newList)
}
# Nested functions
func3<-function(x) {
func3 <- exp(exp(x))
return(func3)
}
func8 <- function(x,y) {
func8<-exp((x+y)^2)
return(func8)
}
The first problem was a warning message:
In mean.default(evaluate(points,function)) :
argument is not numeric or logical:returning NA
I added r3 <- mean(evaluate(points, func3),na.rm=TRUE)
and when I type r3 the output is [1] NA,
why is it not working correctly?
Additionally,
there was a comment about -Nested functions-, I don't understand how to do that in R.

This appears to work:
f <- function (func3,func8){
numSim <- 1000000
vals <- runif(numSim) ## changed the name: 'points' is a built-in function
r3 <- mean(sapply(vals, func3))
vals2 <- runif(numSim)
## use mapply() to evaluate over multiple parameter vectors
r8 <- mean(mapply(func8, vals, vals2))
newList <- list(r3,r8)
return(newList)
}
I simplified the function definitions.
func3 <- function(x) {
return(exp(exp(x)))
}
func8 <- function(x,y) {
return(exp((x+y)^2))
}
Try it out:
f(func3,func8)
I have no idea if this is correct, but I think it's a correct translation of your MATLAB code. Note that the implementation could be much faster by using vectorization: replace the sapply() and mapply() with mean(func3(vals)) and mean(func8(vals,vals2)) respectively (this only works if the functions to be evaluated are themselves appropriately vectorized, which they are in this case).

Related

Generating a function via for-loop for the Jacobian matrix in R

Suppose I have the following two variables y and z and the variable x
y = 1:10
z = 1:10
Now I would like to create a jacobian of the following function
f <- function(x) c(y[1]*x[1]+z[1]*x[2],
y[2]*x[1]+z[2]*x[2],
: : : :
y[10]*x[1]+z[10]*x[2])
Then obtaining the Jacobian can be easily obtained by
jacobian(f, c(1,1))
Now suppose
y= 1:i.
When i becomes large, computing the function manually becomes a time-consuming task.
Is there a way to construct the same function for i?
I tried the following:
for (i in 1:10) {
f[i] <- function(x) c(y[i]*x[1]+z[i]*x[2])
}
jacobian(f, c(1,1))
ThomasIsCoding suggests:
f <- function(x) tcrossprod(cbind(y, z), t(x))
Which works perfectly for this case.
Now suppose that the function is more complex
y[1]*x[1]^2+z[1]/x[2]
The t(x) suggested does no longer work. How do I now write a vector for x?
You can try the following way for function f
f <- function(x) tcrossprod(cbind(y, z), t(x))

What is R's equivalent to Matlab's subs(f, x, value) for symbolic substitution?

In Octave, I use the following to differentiate a function of 2-variables and then substitute 0 for x using subs(). Basically in doing moment-generating-function, Taylor series expansion, etc, we differentiate and then substitute some a for x. I am not able to find the equivalent substitution function in R. Can you please let me know how to do it? Thanks
pkg load symbolic; #octave symbolic package
syms lamb, x; #declare lamb, x symbols
mgf = lamb / (lamb - x); #moment generating function of exponential
mgf1 = diff(mgf, x, 1); #1st differivative
mgf1_0 = subs(mgf1, x, 0); #substitute 0 for E(X)
Using base R:
f <- quote( lambda / (lambda - x) )
Df <- D(f, "x")
do.call("substitute", list(Df, list(x = 0)))
## lambda/(lambda - 0)^2
or we can evaluate Df at specific x and lambda values:
eval(Df, list(x = 0, lambda = 3))
## [1] 0.3333333
Create function to represent result
We can use Df to define an R function der which evaluates the derivative at specific x and lambda values.
der <- function(x, lambda) {}
body(der) <- Df
der(0, 3)
## [1] 0.3333333
Currying
If we want to set x to 0 and create the resulting function of lambda
make_der0 <- function(x = 0) function(lambda) der(x, lambda)
der0 <- make_der0()
der0(3)
## [1] 0.3333333
This is known as currying or partialling and various packages have this as well:
library(functional)
der0a <- Curry(der, x = 0)
der0a(3)
## [1] 0.3333333
library(purrr)
der0b <- partial(der, x = 0)
der0b(3)
## [1] 0.3333333
This appears to be using the symbolic package, which in turn depends on the sympy Python library. R doesn't have built-in symbolic manipulation capabilities, but it does (TIL) have an rSymPy package that works similarly.
## https://kevinkotze.github.io/mm-tut1-symbolic/
library(rSymPy)
rSymPy doesn't have a built-in subs() function, so we'll define one:
subs <- function(expr,x,y) {
Sym(expr,".subs(",x,",",y,")")
}
Also useful to define this (not sure if there's a better way):
r_eval <- function(s,eval_list) {
eval(parse(text=sympy(unclass(s))), eval_list)
}
The rest of the code looks almost identical to the Octave code. Define variables:
## NOTE: 'lambda' is a reserved word in Python, so trying to use it as
## a variable gives rise to confusing errors ...
lam <- Var("lam")
x <- Var("x")
f <- lam/(lam-x)
Differentiate:
mgf1 <- deriv(f,x,1)
Substitute:
subs(mgf1,x,0)
There are other interfaces from R to symbolic math engines, e.g. Ryacas.
If you want to compute the second moment by calculating f''(0), that's not much harder:
v <- subs(deriv(f,x,2),x,0) ## "2/lam**2"
r_eval(v, list(lam=5)) ## 0.08
Maybe you can try package Deriv
library(Deriv)
f <- function(l,x) l/(l-x)
fprim <- Deriv(f,"x")(2,0)
such that
> fprim(2,0)
[1] 0.5

A problem with wrapping array algorithm into a function

I just started programming in R. I'm working at code which execute operations on arrays. It works when I put there a variable but if i wrap it into a function something is wrong. When I try to recall list_matrices[i] i got NULL.
F <- function(x){
list_matrices=c()
for(i in 1:dim(x)[1]){
list_matrices[[i]] <- t(rbind(x[i,1:dim(x)[2],1:dim(x)[3]]))}
}
It has already been pointed out in the comments that the problem is that the function does not return list_matrices so here we will point out that there is some question of whether you really need to do this in the first place. If the reason to create the list is to later iterate over it with some function g, it would be possible to do that directly over 'x' using apply. These two are the same:
# test inputs
x <- array(1:24, 2:4)
g <- function(x) sum(x*x)
# 1
f <- function(x) {
list_matrices <- c()
for(i in 1:dim(x)[1]) {
list_matrices[[i]] <- t(rbind(x[i,1:dim(x)[2],1:dim(x)[3]]))
}
list_matrices
}
L <- f(x)
sapply(L, g)
## [1] 2300 2600
# 2
apply(x, 1, g)
## [1] 2300 2600
Also note that F is used for FALSE in R and could result in subtle errors if used as the name of an object so above we have renamed the function f.

Variable matrix index and row/column as indices in a single function argument

How to handle a variable matrix index and row/column as indices in a single function argument?
m <- matrix(1:9, 3)
fn <- function(m, subsetArg) {
stopifnot(m[subsetArg] == 6)
}
I'd like to be able to use both situations:
a <- matrix(FALSE, 3, 3)
a[2,3] <- TRUE
# yielding
# F F F
# F F T
# F F F
fn(m, subsetArgument = a) # works
and
fn(m, subsetArgument = tuple(2,3)) # <- does not work logically
Note that I would also be after using a range, for example tuple(2, 1:3)
I understand this could be done very explicitly by testing for either 1 or 2 variables given, but I feel there might be an easier way.
Just slurp all the arguments up and pass them into a call to [:
fn <- function(...) {
stopifnot(do.call(`[`, list(...)) == 6)
}
Everything in R is a function, including subsetting :-)
You can subset a matrix using an integer matrix. For example, instead of
m <- matrix(1:9, 3)
fn <- function(m, subsetArg) {
(m[subsetArg])
}
a <- matrix(FALSE, 3, 3)
a[2,3] <- TRUE
fn(m,subsetArg=a)
You could simply write:
n <- matrix(ncol=2, byrow=TRUE, c(2,3))
m[n]
Which would also work in your function, and returns the same result:
fn(m,subsetArg=n)
If you create your index matrix correct you can get the result that you're looking for in the tuple example:
n.tuple <- as.matrix(expand.grid(x=2, y=1:3))
m[n.tuple]
Of course you could write a tuple function which does it for you, which would work as expected:
tuple <- function(x,y) {
as.matrix(expand.grid(x=x, y=y))
}
fn(m, subsetArg = tuple(2,3)) # 8
fn(m, subsetArg = tuple(2,1:3)) # 2 5 8

Application of mclapply() to a function writing to a global variable

I'm trying to use parallel::mclapply to speed up the calculation of the following code:
library(raster)
library(HistogramTools)#for AddHistogram
#Create a first h here for the first band... omitted for brevity
readNhist <- function(n,mconst) {
l <- raster(filename[i], varname=var[i], band=n, na.rm=T)
gain(l) <- mconst
h <<- AddHistograms(h, hist(l, plot=F, breaks=histbreaks,right=FALSE))
}
lapply( 1:10000, readNhist, mconst=1, mc.cores=7 )
#Then do stuff with the h histogram...
When performing the code above, all is fine. If using mclapply (below), the result is miles away from what I want to obtain: the histograms are all wrong.
library(raster)
library(HistogramTools)#for AddHistogram
library(parallel)
#Create a first h here for the first band... omitted for brevity
readNhist <- function(n,mconst) {
l <- raster(filename[i], varname=var[i], band=n, na.rm=T)
gain(l) <- mconst
h <<- AddHistograms(h, hist(l, plot=F, breaks=histbreaks,right=FALSE))
}
mclapply( 2:10000, readNhist, mconst=1 )
#Then do stuff with the h histogram...
I feel like there's something vital I'm missing with the application of parallel computation to this function.
The problem is the <<- which is bad practice in general as far as I can gather.
The function can be rearranged thusly:
readNhist <- function(n,mconst) {
l <- raster(filename, varname=var, band=n, na.rm=T)
gain(l) <- mconst
hist <- hist(l, plot=F, breaks=histbreaks,right=FALSE)
return(hist)
}
And called like this:
hists <- mclapply( 2:nbands, readNhist, mconst=gain, mc.cores=ncores )
ch <- AddHistograms(x=hists)
h <- AddHistograms(h, ch)
rm(ch, hists)
This is pretty fast even with a huge number of layers (and thus histograms).

Resources