Как использовать R, чтобы найти наименьшее положительное решение для cos (x + b) = a - PullRequest
1 голос
/ 11 мая 2019

Мне нужно написать код R, который надежно находит наименьшее положительное решение уравнения cos (x + b) = a. Переменные a и b могут принимать произвольные значения.

В диапазоне [0, 2 \ pi] уравнение имеет два решения при условии abs (a) <1. Но если я попытаюсь решить это уравнение, используя <code>acos, я получу только один ответ, и это может быть не наименьшее положительное решение. Как показывает график. Graph of cos(x + b) showing intersection with y = a and with result of using acos

Что мне нужно сделать, чтобы получить наименьшее положительное решение?

Ответы [ 3 ]

2 голосов
/ 12 мая 2019

Вот как можно получить точное решение без оптимизации. Как я уже говорил в комментарии выше, решения x в cos (x + b) = a задаются как ± arccos (a) - b + 2πk для целого числа k. Следовательно, мы хотим сравнить два частных решения, которые принадлежат интервалу [0,2π]

  1. x 1 = arccos (a) - b + 2πk с наименьшим целым числом k таким, что arccos (a) - b + 2πk> = 0 и

  2. x 2 = -arccos (a) - b + 2πk с наименьшим целым числом k таким, что -arccos (a) - b + 2πk> = 0.

С учетом таких x 1 и x 2 они оба будут неотрицательными, и мы хотим выбрать min {x 1 , x 2 }. После некоторой алгебры мы приходим к

a <- 0.5
b <- -3
k <- ceiling((c(-1, 1) * acos(a) + b) / (2 * pi))
min(c(1, -1) * acos(a) - b + 2 * pi * k)
# [1] 1.952802

Работает для любого a∈ [-1,1] и любого b.

0 голосов
/ 11 мая 2019

Редактировать: Находит максимум кривой между 0 и 2 * пи.Затем он находит корень между интервалом 0 и максимумом.

a <- 0.5
b <- -3

max_op <- optimize(function(x) cos(x+b), interval = c(0, 2*pi), maximum = TRUE)$maximum
uniroot(function(x) cos(x+b) - a, interval = c(0,max_op))

Оригинал:

Вот потенциальное решение.optim, кажется, возвращает правильный ответ, но выдает предупреждение.uniroot и optimize работают, но требуют некоторого контроля, поскольку вы должны обеспечить узкий интервал.

optim(par = 1, fn = function(x) abs(cos(x+b) - a))
uniroot(function(x) cos(x+b) - a, interval = c(1,2))
optimize(function(x) abs(cos(x+b) - a), interval = c(0,2))
0 голосов
/ 11 мая 2019

Я только что обнаружил функцию uniroot.all в пакете rootSolve.Это полностью решает мою проблему (за счет добавления еще одного пакета в мой код.

fun2 <- function(x)
   cos(x + b) - a
 x <- min(rootSolve::uniroot.all(
   f = fun2,
   lower = 0,
   upper = 2 * pi
 ))

Возможно, использование min не является необходимым, если uniroot.all неизменно дает корни в порядкевеличина, но я не могу быть уверен, что это так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...