fsolve выдает ошибку, когда нет решения + помогите отследить сообщения об ошибках - PullRequest
1 голос
/ 05 апреля 2019

Я новичок в R и хотел бы изучить основы того, как R может численно решать уравнения.

Мои вопросы:

  • fsolve returnошибка, когда нет решений.Зачем?Как я могу заставить его возвращать nan или empty?
  • (более общий): пожалуйста, помогите мне понять трассировку и сообщения об ошибках в R - они кажутся слишком загадочными, чтобы их можно было использовать.

Позвольте мне объяснить:

Я начал с того, как рассчитать внутреннюю норму прибыли, не потому, что нет никаких функций для ее расчета, а потому, что это простой примерначать с.

В качестве напоминания, учитывая набор денежных потоков в равные периоды (например, все один год за другим), IRR представляет собой процентную ставку 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  ║
╚════════╩═════════════╩════════════════╝

Я собрал код внизу, и он работает с uniroot и fsolve в простом случае, например (-100,10,110), гдерешение составляет 10%.

Однако, , когда нет решения (например, все положительные числа), тогда uniroot возвращает пустое значение, как и должно быть, но fsolve выдает мне эту ошибку:

Ошибка в if (norm (s, "F")

Я нашел этот вопрос , но ответа не было.Я ничего не нашел в документах .

Почему?Что это значит?Как я могу заставить fsolve возвращать пустое значение или значение nan, если нет решения, не прерывая выполнение сценария?

РЕДАКТИРОВАТЬ : В ответ на ответ ниже: Можете ли вы порекомендовать другой пакет R, в котором, в отличие от uniroot, не требуется указывать верхнюю и нижнюю границы для поиска решения?

pracma::fsolve предназначен только для случаев, когдаn >= 2.Это задокументировано?Я не смог найти это упомянутое в документах .Функции fsolve в Python Scipy и в Matlab , насколько мне известно, не имеют этого ограничения и не требуют указания верхней и нижней границ.У меня нет Matlab, но Сципи не выдает ошибку, когда нет решения.Кроме того, я попытался найти корень x^2+5, и pracma::fsolve дал предупреждение, потому что оно не сходилось, но не ошибка.

Связанный вопрос: как я могу получить осмысленный иполезная трассировка в R?

Например, это происходит в Python, где я получаю сообщения, которые сообщают мне, что строка x в моем коде называется строкой y в some_other_code, что не удалось.

Но в 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")

, что не очень полезно, потому что не совсем понятно, где ошибка;да, строка 20 execute_irr сработала, но тогда что такое «broyden»?

Где это?

Функция какого пакета (ОК, здесь он должен быть частью 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 Ответ

2 голосов
/ 06 апреля 2019

Функция fsolve и особенно метод Broyden не подходит для одномерного поиска корня, он предназначен только для случая f: R ^ n -> R ^ n с n> = 2. Подробнееточно: «формула Шермана-Моррисона» не всегда работает правильно в случае 1-dim.В будущем fsolve перестанет работать для одномерных функций с более понятным сообщением об ошибке.

Стандартный искатель корней в Base R. uniroot. В R есть несколько других 1-мерных функций поиска корней, некоторые из которых находятся в пакете pracma .Как и uniroot.all, findroots будет пытаться найти все корни в заданном интервале.

Это не ответит на ваш вопрос о средствах отладки в R. См., Например, Отладка с помощью RStudio , котораясодержит раздел «Отладка в пакетах».На Youtube есть видео об отладке с помощью R. Тем не менее, я бы рекомендовал отправлять отчет об ошибках вместо отладки кода пакета, который вы сами не написали.

...