如果没有解决方法,则fsolve会给出错误+帮我追溯错误消息

时间:2019-04-05 16:57:16

标签: r numerical-methods

我是R的新手,想学习R如何以数字方式求解方程的基础。

我的问题是:

    没有解决方案时,
  • fsolve将返回错误。为什么?如何获取返回nan或空的值?
  • (更为笼统):请帮助我理解R中的回溯和错误消息-它们似乎太隐秘,无法使用。

让我解释一下:

我首先介绍了如何计算内部收益率,这并不是因为没有任何函数可以计算内部收益率,而是因为这是一个简单的示例。

提醒一下,给定一组在相同时期(例如,一年又一年)的现金流量,内部收益率是利率i,因此下面“公式”列中公式的总和为零;当然(1+i)^ 0 = 1

╔════════╦═════════════╦════════════════╗
║ period ║   cashflow  ║     formulas   ║
╠════════╬═════════════╬════════════════╣
║      0 ║       -100  ║ -100 / (1+i)^0 ║
║      1 ║         10  ║  10 /  (1+i)^1 ║
║      2 ║        110  ║ 110 / (1+i)^2  ║
╚════════╩═════════════╩════════════════╝

我将代码放在底部,并且在{-100,10,110)这样的简单情况下,它可以与unirootfsolve一起使用,解决方案为10%。

但是,当没有解(例如所有正数)时,uniroot会按原样返回空值,但是fsolve给了我这个错误:

  

if(norm(s,“ F”)

我找到了类似的question,但没有答案。 我在docs中找不到任何内容。

为什么?这是什么意思?在没有解决方案的情况下,如何在不中断脚本执行的情况下使fsolve返回空值或nan?

编辑:针对以下答案:  您是否可以推荐另一个R软件包,与uniroot不同,R软件包不需要您指定寻找解决方案的上限和下限?

pracma::fsolve仅适用于n >= 2的情况。有记录吗?我找不到docs中提到的内容。 据我所知,Python ScipyMatlab中的fsolve函数没有此限制,也不需要您指定上限和下限。我没有Matlab,但没有解决方案时Scipy不会给出错误。 另外,我试图找到x^2+5的根,pracma::fsolve发出了警告,因为它没有收敛,但不是错误。

相关问题:如何在R中获得有意义且有用的回溯?

例如,这是在Python中发生的,我收到消息,告诉我代码在some_other_code中的第y行失败了。

但是在R中?我在Rstudio中激活了调试->错误检查->错误检查器。如果输入traceback(),则会得到:

> traceback()
6: broyden(f, x0, J0 = J(x0), maxiter = maxiter, tol = tol)
5: fsolve(my_npv, x0 = 0.2, cf = cf) at solve_irr.R#20
4: eval(ei, envir)
3: eval(ei, envir)
2: withVisible(eval(ei, envir))
1: source("H:/R/solve_irr.R")

不太有用,因为它根本无法弄清错误的出处;是的,solve_irr的第20行触发了它,但是什么是“布罗伊登”呢?

在哪里?

具有哪个软件包的功能(好的,这里必须是pracma的一部分,但是调试器应该告诉我-在更复杂的设置中,了解导致错误的原因不会那么简单)?错误在代码的哪一行? if (norm( etc在哪里?在布罗伊登吗?

编辑:代码:

library(rootSolve)
library(pracma)

my_npv <- function(cf,i){
  npv <- 0
    for (t in 1:length(cf)){
      npv <- npv + cf[[t]] / (1+i)^(t-1)
    }
  return(npv)
}

# this works
cf <- c(-100,10,110)

#this doesn't:
cf <- c(100,10,110)

i_uniroot <- uniroot.all(my_npv, c(0,1), cf = cf)
i_fsolve <- fsolve(my_npv, x0 = 0.2, cf = cf)

1 个答案:

答案 0 :(得分:2)

函数fsolve,尤其是 Broyden 方法不适用于单变量根查找,仅适用于f:R ^ n-> R ^ n且n> =的情况2.更精确地讲:“ Sherman-Morrison公式”在1维情况下并不总是正确工作。将来,fsolve将停止为单变量函数工作,并且会发出更多错误消息。

标准的根查找器是Base R中的uniroot。R中还有其他一些1-dim根查找功能,其中一些在 pracma 包中。像uniroot.all一样,findroots会尝试查找给定间隔中的所有根。

这不能回答您有关R中调试功能的问题。例如,请参见Debugging with RStudio,其中包含“调试软件包”部分。 Youtube上有关于使用R进行调试的视频。不过,我还是建议发送错误报告,而不是调试自己没有编写的程序包代码。