I have the following function f
f <- function (n) if (n==0) 1 else f(n - 1)(n %% 2) - f(n-1)(n+1)
I think it is defined right but I cannot calculate f(8)
f(8)
> Error in f(n - 1) : attempt to apply non-function
what do I have to change?
In R recursion is not terribly well optimised but the basic approach is to use the Recall function. It's unclear what you intend with the "double calling" syntax e.g. f(n-1)(n+1) where f is followed first by a parentheses paired with one argument and then another argument. The f function isn't being designed to return a function. I'm going to make a guess that you wanted the recurrence relation in f(n) to be:
f(n - 1)*(n %% 2) - f(n-1)*(n+1)
If that guess is correct then:
f <- function (n) if (n==0) 1 else {Recall(n - 1) *(n %% 2) - Recall(n-1)*(n+1)}
> f(8)
[1] 99225
I made my guess before the clarifying comments but appears I was correct in thinking you didn't understand that f(n)(n %% 2) was incorrect R syntax. Back to back parentheses (brackets in the English English language) are not signifying multiplication, but rather function application. Look at ?Syntax and for an example see ?ecdf where ecdf(x)(n) is an acceptable nested call because ecdf returns a function as a value.
Related
I am supposed to write a function that, for the values of Pi and P* returns the α.
I am having trouble with the usage of sum in my function.
So far I have something like this:
sqrt((sum(x[i], i == 1, i == length(pstar)])*(p-pstar)^2)/n)/pstar)*100
A sum over a vector x in R is just sum(x), not sum(x[i], i == 1, i == length(x)) * x. (In fact, the latter doesn’t make much sense even if the syntax was correct, since there’s no multiplication involved in a sum.)
So, in your case:
sum((p - pstar) ^ 2)
The following simple recursion finds duplicated elements in a vector. It's taken from chapter 2 Functional Programming in R: Advanced Statistical Programming for Data Science, Analysis and Finance by Thomas Mailund. I wonder why it works when we call rest inside the function as it is calling a function without stating arguments.
Usually this would just return the function definition, but in the recursive function we don't need to and I wondered why.
I can see how this would work if we replaced rest in the function directly with find_duplicates(x, i + 1), but I am struggling to see why it works calling just the name which the function is attached to.
E.g if we define f<- function (x) x and call f it just returns the code function (x) x.
find_duplicates <- function(x, i = 1) {
if (i >= length(x)) return(c())
rest <- find_duplicates(x, i + 1)
if (x[i] == x[i + 1]) c(i, rest)
else rest
}
rest is not a function, it's the output of the function find_duplicates given arguments x and i+1.
So indeed it's the same to type rest or find_duplicates(x, i + 1) in the if clause, they're both values, not functions.
I see that if I use memoise on a function in two different ways, I get two different behaviours, and I'd like to understand why.
# Non Memoised function
fib <- function(n) {
if (n < 2) return(1)
fib(n - 2) + fib(n - 1)
}
system.time(fib(23))
system.time(fib(24))
library(memoise)
# Memoisation stragagy 1
fib_fast <- memoise(function(n) {
if (n < 2) return(1)
fib_fast(n - 2) + fib_fast(n - 1)
})
system.time(fib_fast(23))
system.time(fib_fast(24))
# Memoisation strategy 2
fib_not_as_fast <- memoise(fib)
system.time(fib_not_as_fast(23))
system.time(fib_not_as_fast(24))
Strategy 1, is really fast, as it reuses the recursive results, whereas stratagy 2 is only fast if the exact input has been seen before.
Can someone explain to me why this is?
I think that the reason is simple. In the slow case, the function fib_not_as_fast is memoised. Inside the function, fib is called, which is not memoised. To be more detailed: when you calculate fib_not_so_fast(24), inside the function you have fib(22) + fib(23). Both of these have not been memoised.
In fib_fast, however, you use the memoised version also in the recursion. So, in this case, fib_fast(24) needs to evaluate fib_fast(22) + fib_fast(23). Both these function calls have already happened, when you calculated fib_fast(23) and are thus memoised.
What does work is to memoise a function later, after it has been defined. So, simply redefining the function fib() as fib <- memoise(fib) will work.
We all know the program for this
int fact(int n)
{
if(n==0)
return(1);
return(n*fact(n-1));
}
But what is not clear to me is how the inner thing is happening?
How is it calculating 5*4*3*2*1 (if n is 5)
Please give a clear explanation on this.
Thanks.....
Mathematically, the recursive definition of factorial can be expressed recursively like so (from Wikipedia):
Consider how this works for n = 3, using == to mean equivalence:
3! == 2! * 3 == (1! * 2) * 3 == ((1) * 2) * 3
This can be derived purely symbolically by repeatedly applying the recursive rule.
What this definition does is first expand out a given factorial into an equivalent series of multiplications. It then performs the actual multiplications. The C code you have performs the exact same way.
What might help to understand it, is that when you are recursively calling the function, the new "cycle" will use N-1, not N.
This way, once you get to N==0, the last function you called will return a 1. At this point all the stack of functions are waiting for the return of the nested function. That is how now you exactly multiply the results of each of the functions on the stack.
In other words, you factorize the number given as input.
Consider the following simple function:
f <- function(x, value){print(x);print(substitute(value))}
Argument x will eventually be evaluated by print, but value never will. So we can get results like this:
> f(a, a)
Error in print(x) : object 'a' not found
> f(3, a)
[1] 3
a
> f(1+1, 1+1)
[1] 2
1 + 1
> f(1+1, 1+"one")
[1] 2
1 + "one"
Everything as expected.
Now consider the same function body in a replacement function:
'g<-' <- function(x, value){print(x);print(substitute(value))}
(the single quotes should be fancy quotes)
Let's try it:
> x <- 3
> g(x) <- 4
[1] 3
[1] 4
Nothing unusual so far...
> g(x) <- a
Error: object 'a' not found
This is unexpected. Name a should be printed as a language object.
> g(x) <- 1+1
[1] 4
1 + 1
This is ok, as x's former value is 4. Notice the expression passed unevaluated.
The final test:
> g(x) <- 1+"one"
Error in 1 + "one" : non-numeric argument to binary operator
Wait a minute... Why did it try to evaluate this expression?
Well the question is: bug or feature? What is going on here? I hope some guru users will shed some light about promises and lazy evaluation on R. Or we may just conclude it's a bug.
We can reduce the problem to a slightly simpler example:
g <- function(x, value)
'g<-' <- function(x, value) x
x <- 3
# Works
g(x, a)
`g<-`(x, a)
# Fails
g(x) <- a
This suggests that R is doing something special when evaluating a replacement function: I suspect it evaluates all arguments. I'm not sure why, but the comments in the C code (https://github.com/wch/r-source/blob/trunk/src/main/eval.c#L1656 and https://github.com/wch/r-source/blob/trunk/src/main/eval.c#L1181) suggest it may be to make sure other intermediate variables are not accidentally modified.
Luke Tierney has a long comment about the drawbacks of the current approach, and illustrates some of the more complicated ways replacement functions can be used:
There are two issues with the approach here:
A complex assignment within a complex assignment, like
f(x, y[] <- 1) <- 3, can cause the value temporary
variable for the outer assignment to be overwritten and
then removed by the inner one. This could be addressed by
using multiple temporaries or using a promise for this
variable as is done for the RHS. Printing of the
replacement function call in error messages might then need
to be adjusted.
With assignments of the form f(g(x, z), y) <- w the value
of z will be computed twice, once for a call to g(x, z)
and once for the call to the replacement function g<-. It
might be possible to address this by using promises.
Using more temporaries would not work as it would mess up
replacement functions that use substitute and/or
nonstandard evaluation (and there are packages that do
that -- igraph is one).
I think the key may be found in this comment beginning at line 1682 of "eval.c" (and immediately followed by the evaluation of the assignment operation's RHS):
/* It's important that the rhs get evaluated first because
assignment is right associative i.e. a <- b <- c is parsed as
a <- (b <- c). */
PROTECT(saverhs = rhs = eval(CADR(args), rho));
We expect that if we do g(x) <- a <- b <- 4 + 5, both a and b will be assigned the value 9; this is in fact what happens.
Apparently, the way that R ensures this consistent behavior is to always evaluate the RHS of an assignment first, before carrying out the rest of the assignment. If that evaluation fails (as when you try something like g(x) <- 1 + "a"), an error is thrown and no assignment takes place.
I'm going to go out on a limb here, so please, folks with more knowledge feel free to comment/edit.
Note that when you run
'g<-' <- function(x, value){print(x);print(substitute(value))}
x <- 1
g(x) <- 5
a side effect is that 5 is assigned to x. Hence, both must be evaluated. But if you then run
'g<-'(x,10)
both the values of x and 10 are printed, but the value of x remains the same.
Speculation:
So the parser is distinguishing between whether you call g<- in the course of making an actual assignment, and when you simply call g<- directly.