[英]vectorized IF for bisection method in R
ima beginner in R and i'm spending hours and hours trying to debug a function with IFELSE statement.我是 R 的初学者,我花了很多时间尝试使用 IFELSE 语句调试 function。 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:这是我的 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这里第一个 function 当 (1+i) 的指数是 2 到 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?最后,我如何使用我用于 1 的相同方法找到该方程的 28 个根? Using the exactly the same function i just find the first root.使用完全相同的 function 我只是找到了第一个根。 therefore, I've tried using IFELSE, since the solution im looking for will be a vector, but i keep find errors.因此,我尝试使用 IFELSE,因为我正在寻找的解决方案将是一个向量,但我一直在寻找错误。 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.希望我能尽可能清楚地解释我的问题,全面解决我所用术语的任何不足或错误,并在此先感谢。
I would offer a solution by using for
loop (as suggested by @Érico Patto).我会通过使用for
循环提供解决方案(正如@É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.这个想法是创建一个包含根的长度为n
的向量,然后将tir
function 应用于向量的每个元素。 For example, n = 2:13
.例如, n = 2:13
。
First, create the vector, and assign NA
as the initial values.首先,创建向量,并将NA
指定为初始值。 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]
.然后,将tir
function 中(1+i)
的指数设置为n[k]
。 Here, k
is a vector of the indices for n
.此处, k
是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
循环,将tir
function 应用于n
的每个元素,并将结果分配给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.结果显示对于n = 3
,根是4.3802426
,这与您的结果相匹配。
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.我设置n=2:13
而不是n=2:28
因为在我的计算机中,后者会产生错误,因为它对 C 堆栈的使用太接近我计算机中 C 堆栈大小的限制,我不这样做想改变限制。 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如果您遇到这种错误并且想要更改您的 C 堆栈大小限制,您可以参考此线程错误:C 堆栈使用量太接近限制
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.