Подтвердить что ты не робот

Численное интегрирование сложной функции

Пакет prob численно оценивает характеристические функции для базовых R-распределений. Для почти всех распределений существуют существующие формулы. Однако для нескольких случаев не известно, что решение с закрытой формой неизвестно. Пример: распределение Вейбулла (но см. Ниже).

Для характерной функции Вейбулла я по существу вычисляю два интеграла и объединяю их:

fr <- function(x) cos(t * x) * dweibull(x, shape, scale)
fi <- function(x) sin(t * x) * dweibull(x, shape, scale)
Rp <- integrate(fr, lower = 0, upper = Inf)$value
Ip <- integrate(fi, lower = 0, upper = Inf)$value
Rp + (0+1i) * Ip

Да, это неуклюже, но это работает на удивление хорошо!... гм, большую часть времени. Недавно пользователь сообщил, что следующие разрывы:

cfweibull(56, shape = 0.5, scale = 1)

Error in integrate(fr, lower = 0, upper = Inf) : 
  the integral is probably divergent

Теперь мы знаем, что интеграл не расходится, поэтому это должна быть численная проблема. С помощью некоторых упражнений я мог бы заставить следующее работать:

fr <- function(x) cos(56 * x) * dweibull(x, 0.5, 1)

integrate(fr, lower = 0.00001, upper = Inf, subdivisions=1e7)$value
[1] 0.08024055

Это хорошо, но это не совсем правильно, плюс для этого требуется честная битва, которая плохо масштабируется. Я изучал это для лучшего решения. Я нашел недавно опубликованную "закрытую форму" для характеристической функции с scale > 1 (см. Здесь), но она включает Райт обобщенная конфлюэнтная гипергеометрическая функция, которая не реализована в R (пока). Я заглянул в архивы для альтернатив integrate, и там есть масса вещей, которые не кажутся очень хорошо организованными.

В рамках этого поиска мне пришло в голову преобразовать область интегрирования в конечный интервал через обратную касательную и вуаля! Проверьте это:

cfweibull3 <- function (t, shape, scale = 1){
  if (shape <= 0 || scale <= 0) 
    stop("shape and scale must be positive")
  fr <- function(x) cos(t * tan(x)) * dweibull(tan(x), shape, scale)/(cos(x))^2
  fi <- function(x) sin(t * tan(x)) * dweibull(tan(x), shape, scale)/(cos(x))^2
  Rp <- integrate(fr, lower = 0, upper = pi/2, stop.on.error = FALSE)$value
  Ip <- integrate(fi, lower = 0, upper = pi/2, stop.on.error = FALSE)$value
  Rp + (0+1i) * Ip
}

> cfweibull3(56, shape=0.5, scale = 1)
[1] 0.08297194+0.07528834i

Вопросы:

  • Вы можете сделать лучше, чем это?
  • Есть ли что-то в процедурах цифровой интеграции, что люди, которые разбираются в таких вещах, могут пролить свет на то, что происходит здесь? У меня есть тайное подозрение, что при больших t косинус быстро флуктуирует, что вызывает проблемы...?
  • Существуют ли существующие подпрограммы/пакеты R, которые лучше подходят для такого типа проблем, и может ли кто-нибудь указать мне на хорошо расположенную позицию (на горе), чтобы начать подъем?

Комментарии:

  • Да, использование t в качестве аргумента функции - это плохая практика.
  • Я вычислил точный ответ для shape > 1, используя опубликованный результат с помощью Maple, и brute-force-integrate-by-the-definition-with-R ногами клена. То есть, я получаю один и тот же ответ (вплоть до числовой точности) за небольшую долю секунды и даже меньшую часть цены.

Изменить:

Я собирался записать точные интегралы, которые я ищу, но кажется, что этот конкретный сайт не поддерживает MathJAX, поэтому я дам ссылки. Я хочу, чтобы численно оценить характеристическую функцию распределения Weibull для разумных входов t (что угодно это значит). Значение представляет собой комплексное число, но мы можем разбить его на его действительную и мнимую части и на то, что я называл Rp и Ip выше.

Один заключительный комментарий: Wikipedia имеет формулу, указанную (бесконечную серию) для Weibull c.f. и эта формула соответствует той, которая доказана в документе, на который я ссылался выше, однако, эта серия доказана для shape > 1. Случай 0 < shape < 1 остается открытой проблемой; Подробнее см. в документе.

4b9b3361

Ответ 1

Вам может быть интересно посмотреть на эту статью, в которой обсуждаются различные методы интеграции для сильно осциллирующих интегралов - то, что вы в основном пытаетесь вычислить: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.8.6944

Кроме того, еще один возможный совет заключается в том, что вместо бесконечного ограничения вы можете указать меньший, потому что, если вы укажете требуемую точность, то, основываясь на cdf вейбулла, вы можете легко оценить, сколько из хвост, вы можете усечь. И если у вас есть фиксированный лимит, вы можете точно указать (или почти) количество подразделений (например, чтобы иметь несколько (4-8) баллов за период).

Ответ 2

У меня была такая же проблема, как у Джея - не с распределением Вейбулла, а с интегральной функцией. Я нашел свой ответ на вопрос Jay 3 в комментарии к этому вопросу:

Дивергентный интеграл в R разрешима в Wolfram

Пакет R-пакета содержит несколько функций для численного решения интегралов. В пакете найдены некоторые R-функции для интеграции некоторых математических функций. И есть более общий интеграл функции. Это помогло в моем случае. Пример кода приведен ниже.

К вопросам 2: В первом ответе на связанный вопрос (см. выше) указано, что не полное сообщение об ошибке исходного файла C не распечатывается R (функция может просто сходиться слишком медленно), Поэтому я согласен с Джей, что быстрое колебание косинуса может быть проблемой. В моем случае и в приведенном ниже примере это была проблема.

Пример кода

# load Practical Numerical Math Functions package
library(pracma)

# define function
testfun <- function(r) cos(r*10^6)*exp(-r)

# Integrate it numerically with the basic 'integrate'.
out1 = integarte(testfun, 0, 100)
# "Error in integrate(testfun, 0, 100) : the integral is probably divergent"

# Integrate it numerically with 'integral' from 'pracma' package
# using 'Gauss-Kronrod' method and 10^-8 as relative tolerance. I
# did not try the other ones.
out2 = integral(testfun, 0, 100, method = 'Kronrod', reltol = 1e-8)

Два замечания

  • Интегральная функция не прерывается, как функция интегрирования, но она может занять довольно много времени. Я не знаю (и я не пытался), может ли пользователь ограничивать количество итераций (?).
  • Даже если интегральная функция завершается без ошибок, я не уверен, насколько правильный результат. Численное интегрирование функции, которая быстро флуктуирует вокруг нуля, кажется довольно сложной, поскольку не известно, где вычисляются точно значения флуктуирующей функции (в два раза больше положительных, чем отрицательных, положительные значения близки к локальным максимумам и отрицательным значениям далеко), Я не эксперт по числовой интеграции, но я просто узнал некоторые основные методы интеграции с фиксированным шагом в своих лекциях по численному анализу. Так что, возможно, адаптивные методы, используемые в интеграле, каким-то образом справляются с этой проблемой.

Ответ 3

Я пытаюсь ответить на вопросы 1 и 3. Это говорит о том, что я не вношу никакого вклада в исходный код. Я сделал поиск в google и, надеюсь, это полезно. Удачи!

Источник: http://cran.r-project.org/doc/contrib/Ricci-distributions-en.pdf(стр. 6)

#Script

library(ggplot2)

## sampling from a Weibull distribution with parameters shape=2.1 and scale=1.1
x.wei<-rweibull(n=200,shape=2.1,scale=1.1) 

#Weibull population with known paramters shape=2 e scale=1
x.teo<-rweibull(n=200,shape=2, scale=1) ## theorical quantiles from a

#Figure
qqplot(x.teo,x.wei,main="QQ-plot distr. Weibull") ## QQ-plot
abline(0,1) ## a 45-degree reference line is plotted

Ответ 4

Используется ли это?

http://www.sciencedirect.com/science/article/pii/S0378383907000452

Muraleedharana et al (2007) Модифицированное распределение Вейбулла для моделирования и прогнозирования максимальной и значительной высоты волны, Прибрежная инженерия, том 54, выпуск 8, август 2007 г., стр. 630-638

Из реферата: "Получена характеристическая функция распределения Вейбулла".