Evaluating a multivariable function with constraints - r

I have a function f(x,y) where both the inputs are integers. Given a natural number K, I would like to evaluate f at all points in the set { (x,y) : 0 <= x <= K-1 , x < y <= K }. In other words, evaluating f at all feasible 0 <=x,y <= K which satisfy y>x.
I know this can be done with nested for loops but I am wondering if there is a more efficient way to do it through one of the apply functions perhaps.

Here is one way of doing what the question asks for. It's a simple double *apply loop with a function call in the inner most loop.
f <- function(x, y) {x + y + x*y}
K <- 10
sapply(0:(K - 1), function(x){
sapply((x + 1):K, function(y) f(x, y))
})
This is easily rewritten as a function of K and f.
fun <- function(K, FUN){
f <- match.fun(FUN)
lapply(0:(K - 1), function(x){
sapply((x + 1):K, function(y) f(x, y))
})
}
fun(10, f)

Related

How to pass the output of a function to another function in R?

So I want to pass the output of func1 to func2.
func1 <- function(x, y, z) {
k = x*2
j = y*2
i = z*2
}
func2 <- function(x, y, z) {
func1(x, y, z)
m = k * j * i
return (m)
}
It keeps printing errors.
Here is another solution. This is called a function factory which means a function that creates another function. Since func2 only uses the outputs of func1, it can find them through lexical scoping in its parent environment which is the execution environment of func1.
Just note the additional pair of parentheses I used in order to call the function since the output of the first function is a function.
func1 <- function(x, y, z) {
k <- x * 2
j <- y * 2
i <- z * 2
func2 <- function() {
m <- k * j * i
m
}
}
func1(1, 2, 3)()
[1] 48
For more information you can read this section of Hadley Wickham's Advanced R.
There are quite a few things going on here, and it really partly depends on if you are showing us a very simplified version. For example, are you really doing the same thing to x, y, z in the first function or are you possibly doing different things?
First, the i, j and k vectors that you are creating in func1() do not exist outside of func1().
As #akrun said you could rectify this bye making them into a vector (if they are always of the same type) or a list and then returning that.
So then you could get, say,
func1 <- function(x, y, z) {
k <- x*2
j <- y*2
i <- z*2
c(k, j, i)
}
At which point you could a a parameter to your second function.
func2 <- function(x, y, z) {
ijk <- func1(x, y, z)
prod(ijk)
}
Of course even easier if you can vectorize func1() (but I don't know how much you simplified).
func1v2 <- function(x, y, z) {
2* c(k, j, i)
}
We may return a named list from the first function and then access the names of the output of the first function using with
func1 <- function(x, y, z) {
list(k = x*2,
j = y*2,
i = z*2)
}
func2 <- function(x, y, z) {
with(func1(x, y, z), k * j * i)
}
-testing
func2(3, 5, 6)
Since func2 only makes the product of a vector you do not need to define a second function. You can do it like this: First define func1 as you did
func1 <- function(x, y, z) {
k = x*2
j = y*2
i = z*2
return(c(k,j,i))
}
Then use it inside the prod function like this
prod(func1(1, 2, 3))
48

Self-referencing nested functions in R?

So, I'm trying to write a function that builds a large complicated formula recursively. Basically, what I would love to work simply, is the following:
f <- function(x) {
g <- function(y) y
for( i in 1:4 ) {
h <- g
g <- function(y) h(y)^2
}
g(x)
}
Please refrain from laughing at this insane motivation. Now what I would like to get, is a function that returns ((((x^2)^2)^2)^2), but what actually happens is that my runtime just crashes immediately, probably because there's some sort of call to an unreferenced function or something, since I'm overwriting the expression for g every time (obviously I don't really know how r works in this scenario).
How can I achieve this idea of retaining the information from the older g references?
1) Recursion We can use recursion like this:
h1 <- function(f, n) if (n == 1) f else function(x) f(h1(f, n-1)(x))
# test using g from questioun
h1(g, 4)(3)
## [1] 43046721
(((3^2)^2)^2)^2
## [1] 43046721
2) Reduce This uses Reduce to compose a function f with itself iteratively n times.
h2 <- function(f, n) function(y) Reduce(function(x, f) f(x), rep(list(f), n), y)
h2(g, 4)(3)
## [1] 43046721
3) for
h3 <- function(f, n) {
function(x) {
for(i in 1:n) x <- f(x)
x
}
}
h3(g, 4)(3)
## [1] 43046721
4) Fixed If there are a small fixed number we could just write it out
explicitly:
h4 <- function(x) g(g(g(g(x))))
h4(3)
## [1] 43046721
5) Compose We could slightly simplify any of the above using Compose from the functional package. (The purrr package also has a compose function. Use that if you are already using purrr; otherwise, functional has a smaller footprint.)
library(functional)
h1a <- function(f, n) if (n == 1) f else Compose(f, h(f, n-1))
h2a <- function(f, n) Reduce(Compose, rep(list(f), n))
h2b <- function(f, n) do.call(Compose, rep(list(f), n))
h3a <- function(f, n) {
for(i in 1:n) ff <- if (i == 1) f else Compose(ff, f)
ff
}
h4a <- Compose(g, g, g, g)

Error in seq.default(a, b, by = h) : 'to' cannot be NA, NaN or infinite

I have a two functions one is to calculate the integration and another one is fixed-point method to find the root.This is the function to calculate the integration:
trapezoid <- function(fun, a, b, n=100) {
h <- (b-a)/n
x <- seq(a, b, by=h)
y <- fun(x)
s <- h * (y[1]/2 + sum(y[2:n]) + y[n+1]/2)
return(s)
}
And this is the root finding function:
fixedpoint <- function(fun, x0, tol=1e-03, niter=5000){
## fixed-point algorithm to find x such that fun(x) == x
## assume that fun is a function of a single variable
## x0 is the initial guess at the fixed point
xold <- x0
xnew <- fun(xold)
for (i in 1:niter) {
xold <- xnew
xnew <- fun(xold)
if ( abs((xnew-xold)) < tol )
return(xnew)
}
stop("exceeded allowed number of iterations")
}
Now I define a function f f<-function(x) {x^2}
And get its integration function h<-function(x) trapezoid(f,2,x)
Last I want to find the roots of h by doingfixedpoint(h,2)
But I got the error message like this:
Error in seq.default(a, b, by = h) : 'to' cannot be NA, NaN or
infinite

In R, is there a built in function for iterating a function n times?

Suppose I have a variable x and a function f. I would like to perform f on x, then again on the result, n times.
I have built a simple function for this:
iterate <- function(x, f, n) {
assertthat::assert_that(n >= 0)
if (n > 0) {
for (i in 1:n) {
x <- f(x)
}
}
x
}
Which works as follows:
iterate(256, f = sqrt, n = 3)
Is this already built into R?
You can do this with a functional programming approach, with Reduce and Compose from functional package. The idea is to create the list of function you want and chain them using Compose. You simply apply this function to x afterwards.
x = 256
n = 3
f = sqrt
library(functional)
Reduce(Compose, replicate(n, f))(x)
#[1] 2
Or use freduce from magrittr:
library(magrittr)
freduce(x, replicate(n, f))
#[1] 2

Function that returns itself in R?

In Lambda calculus, Y -combinator returns itself like this Y a = a Y a, specifially here. Suppose some trivial function such as y(x)=2*x+1 (suppose Church numbers for the sake of simplicity) and I want to do it Y y to which I want some sort of break-out -function. I want to do something like this
calculate y(1) --->3
calculate y(3) --->7
calculate y(7) ...
...
terminate on the n-th case
How can I do this in R using the functional way of thinking? Is there something built-in?
I don't really understand the notation of the lambda calculus, so can't know for sure what the Y-combinator is, but I wonder if the R function Recall() (help page here) wouldn't help you build what you're after. Here is an example of its use to calculate a factorial:
# Calculate 4!
(function(n) {if (n<=1) 1 else n*Recall(n-1)})(4)
And here it is applied to the example you described:
(function(x, n) {if (n<=1) x else Recall(2*x+1, n-1)})(x=1, n=1)
# [1] 1
(function(x, n) {if (n<=1) x else Recall(2*x+1, n-1)})(x=1, n=2)
# [1] 3
(function(x, n) {if (n<=1) x else Recall(2*x+1, n-1)})(x=1, n=3)
# [1] 7
Try this:
myfun = function(x) { 2*x+1 }
N = 10; seed = 3; i = 1
for(i in 1:N){
seed = Y = myfun(seed)
print(Y)
}
If you just want a function, g, that transforms a function f
into function(x) f(f(f(f(...f(x))))) (n times, with n not known in advance),
the following should do.
compose_with_itself_n_times <- function(f,n) {
function(x) {
for(i in seq_len(n)) {
x <- f(x)
}
x
}
}
f <- function(x) 2*x+1
g <- compose_with_itself_n_times(f,10)
g(1)

Resources