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)
Related
I have the following exercise to be solved in R. Under the exercise, there is a hint towards the solution.
Exercise: If there are no ties in the data set, the function above will produce breakpoints with h observations in the interval between two consecutive breakpoints (except the last two perhaps). If there are ties, the function will by construction return unique breakpoints, but there may be more than h observations in some intervals.
Hint:
my_breaks <-function(x, h = 5) {
x <-sort(x)
breaks <- xb <- x[1]
k <- 1
for(i in seq_along(x)[-1])
{if(k<h)
{k <- k+1}
else{
if(xb<x[i-1]&&x[i-1]<x[i])
{xb <- x[i-1]
breaks <-c(breaks, xb)
k <- 1
}
}
}
However, I am having a hard time understanding the above function particularly the following lines
for(i in seq_along(x)[-1])
{if(k<h)
{k <- k+1}
Question:
How is the for loop supposed to act in k if k is previously defined as 1 and i is different than k? How are the breakpoints chosen according to the h=5 gap if the for loop is not acting on x? Can someone explain to me how this function works?
Thanks in advance!
First, note that your example is incomplete. The return value and the final brace are missing there. Here is the correct version.
my_breaks <-function(x, h = 5) {
x <- sort(x)
breaks <- xb <- x[1]
k <- 1
for(i in seq_along(x)[-1]){
if(k<h) {
k <- k+1
} else {
if(xb<x[i-1]&&x[i-1]<x[i]){
xb <- x[i-1]
breaks <-c(breaks, xb)
k <- 1
}
}
}
breaks
}
Let's check if it works.
my_breaks(c(1,1,1:5,8:10), 2)
#[1] 1 2 4 8
my_breaks(c(1,1,1:5,8:10), 5)
#[1] 1 3
As you can see, everything is fine. And what is seq_along(x)[-1]? We could write this equation as 2:length(x). So the for loop goes through each element of the vector x in sequence, skipping the first element.
What is the k variable for? It counts the distance to take into account the h parameter.
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)
I have a function called in the example fn_example_1 that needs to change with a parameter that comes from another function (n).
It needs to have a fixed part that never changes, and a variable part that gets longer with n, as an example:
# this is the function that needs to change
fn_example_1 <- function(x, mod) {
# -- this part is fixed
mod$a <- x^2 # fixed
# -- this part can change with n
mod$b[5,5, k] <- x + 1 # variable
mod$b[6, 6, k] <- x + 1 # variable
# mod$b[7,7, k] <- x + 1 # if n = 3 ecc..
# k is an arg from a third function, more on that later..
mod
}
This is what I have in mind, basically a wrapper function that gives back a different version of fn_example_1 that depens on n.
fn_wrap_example <- function(fn, n) {
# something
# something
# I've thought about a long if else, of course with a max value for n.
return(fn)
}
fn_wrap_example(fn_example_1, n = 2) # call to the wrapper
It is crucial that fn_wrap_example returns a function, this will be an argument to a third function. As a semplification n can have a max value, ie: 20.
The key is that fn_example_1 is a function that changes with n.
Here is how you can modify a function in your wrapper:
fn_factory <- function(n) {
fn <- function(x, mod) {
# -- this part is fixed
mod$a <- x^2 # fixed
x #place holder
# k is an arg from a third function, more on that later..
mod
}
ins <- switch(n,
"1" = quote(mod$b[5,5, k] <- x + 1),
"2" = quote(mod$b[6, 6, k] <- x + 1)
)
body(fn)[[3]] <- ins
return(fn)
}
fn_factory(2)
#function (x, mod)
#{
# mod$a <- x^2
# mod$b[6, 6, k] <- x + 1
# mod
#}
#<environment: 0x0000000008334eb8>
I seriously doubt you need this, but it can of course be done.
What you are looking for is called a closure.
https://www.r-bloggers.com/closures-in-r-a-useful-abstraction/
http://adv-r.had.co.nz/Functional-programming.html
Simple example:
power <- function(exponent) {
function(x) {
x ^ exponent
}
}
square <- power(2)
square(2)
Suppose I have a vector x which I want to convolve with itself n times. What is the good way to do this in R?
Suppose that we already have a function conv(u,v) that convolves two vectors.
I can do this:
autoconv<-function(x,n){
r<-1;
for(i in 1:n){
r<-conv(r,x);
}
return(r);
}
is there a more efficient way?
Take the Fast Fourier Transform (fft) of x, raise it to the kth power and take the inverse fft. Then compare that to performing convolutions of k copies of x. No packages are used.
# set up test data
set.seed(123)
k <- 3 # no of vectors to convolve
n <- 32 # length of x
x <- rnorm(n)
# method 1 using fft and inverse fft
yy <- Re(fft(fft(x)^k, inverse = TRUE) / n)
# method 2 using repeated convolutions
y <- x
if (k >= 2) for(i in 2:k) y <- convolve(x, y, FALSE)
# check that the two methods give the same result
all.equal(y, yy)
## TRUE
autoconv <- function(x, n){
if(n == 0){
return(1)
} else if(n == 1){
return(x)
} else {
i <- 2
xi <- conv(x,x)
while(n %% i != 0){
i <- i + 1
xi <- conv(xi,x)
}
return(autoconv(xi,n/i))
}
}
This will call conv() once for each prime factor of n, rather than 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