Метод чисельної інтеграції складного коливального інтеграла


25

Мені потрібно чисельно оцінити інтеграл нижче:

0sinc(xr)rE(r)dr

де , і . Тут - модифікована функція Бесселя другого роду. У моєму конкретному випадку я , і .xR+λ,κ,ν>0Kλ=0,00313κ=0,00825ν=0,33E(r)=r4(λκ2+r2)ν5/2Kν5/2(λκ2+r2)xR+λ,κ,ν>0Kλ=0.00313κ=0.00825ν=0.33

Я використовую MATLAB, і я спробував вбудовані функції, integralі quadgkце дає мені багато помилок (див. Нижче). Я, звичайно, також пробував багато інших речей, таких як інтеграція по частинах та підсумовування інтегралів від до .( k + 1 ) x πkxπ(k+1)xπ

Отже, чи є у вас якісь пропозиції щодо того, який метод я слід спробувати далі?

ОНОВЛЕННЯ (додаткові запитання)
Я читав статтю @Pedro, пов’язану з цим, і не думаю, що це було занадто важко зрозуміти. Однак у мене є кілька питань:

  • Чи було б добре використовувати як базисні елементи , в описаному уніваріантному методі Левіна?ψ kxkψ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


Що є у вашому інтегралі? x
Педро

Будь-яке позитивне, реальне число. Я щойно оновив свою публікацію.
торбонда

Якщо ви могли показати якийсь код та помилки, можливо, вирішити більшість із них не так вже й складно. Звичайно, спробуйте спочатку уважно прочитати помилку та побачити, чи зможете ви її зникнути самостійно.
Денніс Джахеруддін

Пізніше сьогодні я зроблю коментар із деяким кодом та помилками. Або завтра.
торбонда

Гаразд, так я забув. Але тепер я оновив свою посаду на прикладі (я розділив інтеграл на два, чітко обчисливши ). sinc
торбонда

Відповіді:


12

Я написав власний інтегратор, quadccякий справляється значно краще, ніж інтегратори Matlab з особливостями, і забезпечує більш надійну оцінку помилок.

Щоб скористатися цією проблемою, я зробив наступне:

>> lambda = 0.00313; kappa = 0.00825; nu = 0.33;
>> x = 10;
>> E = @(r) r.^4.*(lambda*sqrt(kappa^2 + r.^2)).^(-nu-5/2) .* besselk(-nu-5/2,lambda*sqrt(kappa^2 + r.^2));
>> sincp = @(x) cos(x)./x - sin(x)./x.^2;
>> f = @(r) sincp(x*r) .* r .* sqrt( E(r) );

Тепер ця функція f- ваш інтегрант. Зауважте, що я щойно присвоїв будь-яке старе значення x.

Для інтеграції в нескінченну область я застосовую підстановку змінних:

>> g = @(x) f ( tan ( pi / 2 * x ) ) .* ( 1 + tan ( pi * x / 2 ).^2 ) * pi / 2;

тобто інтегрування gвід 0 до 1 повинно бути таким же, як інтеграція fвід 0 до . Різні перетворення можуть давати результати різної якості: Математично всі перетворення повинні давати однаковий результат, але різні перетворення можуть давати більш плавні або легше інтегруються .g

Потім я викликаю власний інтегратор, quadccякий може мати справу з NaNs на обох кінцях:

>> [ int , err , npoints ] = quadcc( g , 0 , 1 , 1e-6 )
int =
  -1.9552e+06
err =
   1.6933e+07
npoints =
       20761

Зауважте, що оцінка помилок величезна, тобто quadccне має великої впевненості в результатах. Однак, дивлячись на функцію, це не дивно, оскільки вона коливається на значеннях на три порядки вище фактичного інтеграла. Знову ж таки, використання іншого інтервального перетворення може дати кращі результати.

Ви також можете переглянути більш конкретні методи, такі як цей . Це трохи більше, але, безумовно, правильний метод для такого типу проблем.


Велике спасибі. Я розгляну різні методи. У моїх цілях помилка не повинна бути такою малою, як це є стандартною в еквіваленті integral(1е-10, я думаю), але 1,7е + 07 все-таки дійсно, дуже велика. Можливо, інша трансформація принесе користь, як ви згадуєте.
торбонда

@ cimrg.joe: Зауважте, що оцінка помилки - це оцінка абсолютної помилки, заснованої, серед інших, на максимальних абсолютних значеннях інтегралу. У деяких крайніх випадках повернене значення може бути насправді нормальним. Якщо ви шукаєте десять цифр точності, я настійно рекомендую використовувати методи типу Левіна, про які я згадував наприкінці своєї публікації.
Педро

Можливо, мені не потрібно десять цифр точності, але я думаю, що мені потрібно принаймні п'ять. Чи може ваш метод це зробити?
торбонда

Метод не може гарантувати таку точність для вашого інтеграла, оскільки значення в правому кінці інтервалу на кілька порядків більше, ніж сам інтеграл.
Педро

11

Як вказує Педро, методи левінського типу - це найкращі усталені методи для подібних проблем.

Чи маєте ви доступ до Mathematica? Для цієї проблеми Mathematica виявить та використовуватиме їх за замовчуванням:

In[1]:= e[r_] := 
 r^4 (l Sqrt[k^2 + r^2])^(-v - 5/2) BesselK[-v - 5/2, l Sqrt[k^2 + r^2]]

In[2]:= {l, k, v} = {0.00313, 0.00825, 0.33};

In[3]:= Block[{x = 10}, 
 NIntegrate[Sinc'[x r] r Sqrt[e[r]], {r, 0, \[Infinity]}, 
  PrecisionGoal -> 3]]

Out[3]= -112494.

Ось графік у діапазоні значень x:

In[4]:= ListLinePlot[
 Table[NIntegrate[Sinc'[x r] r Sqrt[e[r]], {r, 0, \[Infinity]}, 
   PrecisionGoal -> 3], {x, .5, 10, 0.1}]]

Ділянка від x = 0,5 до x = 10

Ви також можете вручну вказати конкретний метод типу Левіна, який слід застосувати, що в цьому випадку може призвести до невеликого покращення продуктивності:

In[5]:= method = {"LevinRule", "Kernel" -> {Cos[r x], Sin[r x]}, 
   "DifferentialMatrix" -> {{0, -x}, {x, 0}}, 
   "Amplitude" -> {(
     3497.878840962873` Sqrt[(
      r^4 BesselK[-2.17`, 
        0.00313` Sqrt[
         0.00006806250000000001` + r^2]])/(0.00006806250000000001` + 
        r^2)^1.415`])/
     x, -((3497.878840962873` Sqrt[(
       r^4 BesselK[-2.17`, 
         0.00313` Sqrt[
          0.00006806250000000001` + r^2]])/(0.00006806250000000001` + 
         r^2)^1.415`])/(r x^2))}, "AdditiveTerm" -> 0};

In[6]:= Block[{x = 10}, 
 NIntegrate[Sinc'[x r] r Sqrt[e[r]], {r, 0, \[Infinity]}, 
  PrecisionGoal -> 3, Method -> method]]

Out[6]= -112495.

Детальну інформацію про методи Левіна в Mathematica див . У документації.


На жаль, я не маю доступу до Mathematica - лише MATLAB. Я просто оновлю своє запитання деякими додатковими запитаннями стосовно статті @Pedro, пов’язаної з цим.
торбонда

Гаразд, як ви кажете, вам доведеться поводитися з Матлабом. Я додам ще одну відповідь з цього приводу.
Ендрю Майлан

5

Якщо у вас немає доступу до Mathematica, ви можете написати метод Левіна (або інший спеціалізований коливальний) метод у Matlab, як пропонує Педро.

Чи використовуєте ви бібліотеку chebfun для Matlab? Я тільки що дізнався , що містить реалізацію основного методу Levin типу тут . Реалізація написана Олвером (одним із експертів у галузі коливальної квадратури). Він не стосується особливості, адаптивного підрозділу тощо, але, можливо, це саме те, що вам потрібно для початку.


Я думав над тим, щоб реалізувати метод Левіна самостійно, але не впевнений, чи готовий до цього завдання. Я думаю, що мені потрібно зрозуміти метод трохи краще. Можливо, я міг би про це поговорити зі своїм радником. У будь-якому разі, я запитав про методи Філона - це те, що вони здаються легшими у застосуванні. А оскільки мені не потрібна надзвичайно висока точність, але це частина моєї магістерської роботи, складність
зважується

Я ознайомився з бібліотекою chebfun (що вражає) та прикладом інтеграції Левіна. Але я не можу його запустити. Я фактично розмістив питання щодо цього тут .
торбонда

0

Рекомендована Педро трансформація - чудова ідея. Чи намагалися ви пограти з параметрами у функції "quadgk" Matlab? Наприклад, використовуючи перетворення Педро, ви можете зробити наступне:
quadgk(f, 0.0+eps, 1.0-eps, 'AbsTol', eps, 'MaxIntervalCount', 100000)
Використання цього дає мені рішення:
-2184689.50220729
і займає лише 0,8 секунди (використовуючи згадані вище значення: x = 10)
Уолтер Гандер і Вальтер Гауцкі мають документ про адаптивну квадратуру з Matlab код, який ви також можете використовувати (посилання тут )

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.