1

i m a beginner in R and i'm spending hours and hours trying to debug a function with IFELSE statement. I know it could be kind of obvious but i can't find a solution. Here' s my problem.

Using the same funcion with just an unknown factor everything works. here's my function:

tir <- function(i){
 return((-45000 * 1-( 1 + i)^-3)/i + (1600000 * (1+i)^-3))
 }
tir(0.2)

> tir(0.2)
[1] 700923

Then i solve it with the bisection method to find the root.

bisec5 <- function(fun, a, b, tol=0.00001) {
  if (abs(fun(a)) < tol )
    return(a)
  if (abs(fun(b)) < tol )
    return(b)
  x <- (a + b) / 2
  if( abs(fun(x)) < tol )
    return(x)
  if (fun(a)*fun(x) < 0)
    return( Recall( fun, a, x, tol) )
  else
    return( Recall( fun, x, b, tol) )
}

bisec5(fun = tir, a= 50, b= 0.00000001)

[1] 4.380243

My issues begin when i'm tryng to solve the same equation for a vector. here the first function when the exponent of (1+i) is a number included between 2 and 28

tir <- function(i){
    n<- 2:28
    return((-45000 * 1-( 1 + i)^-n)/i + (1600000 * (1+i)^-n))
}
tir(0.2)
[1]  886107.639  700923.032  546602.527  418002.106  310835.088  221529.240  147107.700   85089.750
 [9]   33408.125   -9659.896  -45549.913  -75458.261 -100381.884 -121151.570 -138459.642 -152883.035
[17] -164902.529 -174918.774 -183265.645 -190221.371 -196017.809 -200848.174 -204873.479 -208227.899
[25] -211023.249 -213352.707 -215293.923

Finally, how could i find the 28 roots of this equation applying the same method i used for 1? Using the exactly the same function i just find the first root. therefore, I've tried using IFELSE, since the solution im looking for will be a vector, but i keep find errors. here's one example of my many tryings.

bisec5 <- function(fun, a, b, tol=0.00001) {
  ifelse (abs(fun(a)) < tol, a, "0" )
    
  ifelse (abs(fun(b)) < tol, print(b), next)
   
  x <- (a + b) / 2
  ifelse ( abs(fun(x)) < tol, print(x), next )
   
  ifelse (fun(a)*fun(x) < 0,return( Recall( fun, a, x, tol)), return( Recall( fun, x, b, tol)))
}
bisec5(fun = tir, a= 50, b =0.000001)
Error in ifelse(abs(fun(b)) < tol, print(b), next) : 
  no loop for break/next, jumping to top leve

Hope i coluld explain my problem as clear as possible, be comprehensive to any lack or mistake of terminology i made, and thanks in advance.

  • For that paticular try, the error you're getting is the `next` argument. Why don't you just do `if()` instead? – Érico Patto Nov 15 '20 at 10:55
  • What I think might work is using a `for(i in 1:28)` loop inside `bisec5` and instead of doing return (which would then stop the entire function the first time the loop rolls, essentially removing the error message), you'd want to concatinate (`c()`) the result to a `result` vector os something like that. Don't forget to define it first. – Érico Patto Nov 15 '20 at 11:07

1 Answers1

0

I would offer a solution by using for loop (as suggested by @Érico Patto).

The idea is to create a vector with the length of n that contains your roots, and then apply tir function to each element of the vector. For example, n = 2:13.

First, create the vector, and assign NA as the initial values. Giving a name for each element would be a good idea.

roots = rep(NA, length(n))
names(roots) = paste0("root for n = ", n)
roots
#root for n = 2  root for n = 3  root for n = 4  root for n = 5  root for n = 6  root for n = 7 
             NA              NA              NA              NA              NA              NA 
# root for n = 8  root for n = 9 root for n = 10 root for n = 11 root for n = 12 root for n = 13 
             NA              NA              NA              NA              NA              NA 

Then, set the exponent of (1+i) in tir function to n[k]. Here, k is a vector of the indices for n.

tir_n <- function(i){
    return((-45000 * 1-( 1 + i)^-n[k])/i + (1600000 * (1+i)^-n[k]))
}

Then, by using for loop, apply the tir function to each element of n and assign the result to each element of roots.

for (k in 1:length(n)) roots[k] <- bisec5(fun = tir, a= 50, b = 0.00000001)
roots
#root for n = 2  root for n = 3  root for n = 4  root for n = 5  root for n = 6  root for n = 7 
     33.5257269       4.3802426       1.8465317       1.0706831       0.7145925       0.5148502 
# root for n = 8  root for n = 9 root for n = 10 root for n = 11 root for n = 12 root for n = 13 
      0.3884500       0.3016256       0.2381644       0.1892135       0.1491551       0.1126293 

The result shows that for n = 3, the root is 4.3802426, which matches your result.

I set n=2:13 instead of n=2:28 because in my computer, the latter generates an error because its usage of C stack is too close to the limit of the C stack size in my computer, and I don't want to change the limit. In case you encounter this kind of error and you want to change your C stack size limit, you can refer to this thread Error: C stack usage is too close to the limit

Abdur Rohman
  • 2,691
  • 2
  • 7
  • 12