Мне нужно численно оценить интеграл ниже:
где , и . Здесь - модифицированная функция Бесселя второго рода. В моем конкретном случае у меня , и .x∈R+λ,κ,ν>0Kλ=0,00313κ=0,00825ν=0,33
Я использую MATLAB, и я попробовал встроенные функции integral
и quadgk
, что дает мне много ошибок (см. Ниже). Естественно, я пробовал и множество других вещей, таких как интегрирование по частям и суммирование интегралов от до .( k + 1 ) x π
Итак, есть ли у вас какие-либо предложения относительно следующего метода?
ОБНОВЛЕНИЕ (добавленные вопросы)
Я прочитал статью @Pedro, на которую ссылается, и я не думаю, что это было слишком сложно понять. Однако у меня есть несколько вопросов:
- Можно ли использовать качестве элементов в описанном одномерном методе Левина?ψ k
- Могу ли я вместо этого просто использовать метод Филона, поскольку частота колебаний фиксирована?
Пример кода
>> integral(@(r) sin(x*r).*sqrt(E(r)),0,Inf)
Warning: Reached the limit on the maximum number of intervals in use. Approximate
bound on error is 1.6e+07. The integral may not exist, or it may be difficult to
approximate numerically to the requested accuracy.
> In funfun\private\integralCalc>iterateScalarValued at 372
In funfun\private\integralCalc>vadapt at 133
In funfun\private\integralCalc at 84
In integral at 89
ans =
3.3197e+06
источник
Ответы:
Я написал свой собственный интегратор,
quadcc
который справляется значительно лучше, чем интеграторы Matlab с особенностями, и обеспечивает более надежную оценку ошибок.Чтобы использовать это для вашей проблемы, я сделал следующее:
Функция
f
теперь ваша интеграция. Обратите внимание, что я только что присвоил любое старое значениеx
.Чтобы интегрировать в бесконечную область, я применяю подстановку переменных:
т.е. интегрирование∞
g
от 0 до 1 должно быть таким же, как интегрированиеf
от 0 до . Разные преобразования могут давать разные результаты качества: математически все преобразования должны давать один и тот же результат, но разные преобразования могут давать более гладкие или более легко интегрируемые s.g
Затем я вызываю свой собственный интегратор,
quadcc
который может работать сNaN
s на обоих концах:Обратите внимание, что оценка ошибки огромна, то
quadcc
есть не очень уверен в результатах. Однако, глядя на функцию, это не удивительно, поскольку она колеблется при значениях на три порядка выше фактического интеграла. Опять же, использование другого интервального преобразования может дать лучшие результаты.Вы также можете посмотреть на более конкретные методы, такие как этот . Это немного сложнее, но определенно правильный метод для этого типа проблемы.
источник
integral
(я думаю, что 1e-10), но 1.7e + 07 по-прежнему действительно очень велика. Возможно, другое преобразование принесет пользу, как вы упоминаете.Как указывает Педро, методы типа Левина являются наилучшими методами для решения подобных проблем.
У вас есть доступ к Mathematica? Для этой проблемы Mathematica обнаружит и использует их по умолчанию:
Вот график в диапазоне значений х:
Вы также можете вручную указать конкретный метод типа Левина, который будет применяться, что в этом случае может привести к небольшому улучшению производительности:
Смотрите документацию для подробностей о методах типа Левина в Mathematica .
источник
Если у вас нет доступа к Mathematica, вы можете написать в Matlab метод Левина (или другой специализированный колебательный), как предлагает Педро.
Вы используете библиотеку chebfun для Matlab? Я только что узнал , что содержит реализацию основного метода Levin типа здесь . Реализация написана Олвером (одним из экспертов в области колебательных квадратур). Это не касается особенностей, адаптивного подразделения и т. Д., Но может быть именно тем, что вам нужно для начала.
источник
Рекомендованное Педро преобразование - отличная идея. Вы пытались поиграться с параметрами в функции quadgk в Matlab? Например, используя преобразование Педро, вы можете сделать следующее:
quadgk(f, 0.0+eps, 1.0-eps, 'AbsTol', eps, 'MaxIntervalCount', 100000)
Использование этого дает мне решение:
-2184689.50220729
и занимает всего 0,8 секунды (с использованием значений, упомянутых выше: x = 10). У
Уолтера Гандера и Уолтера Гаутски есть статья по адаптивной квадратуре с Matlab. код, который вы также можете использовать (ссылка здесь )
источник