Zor salınımlı integralin sayısal entegrasyonu için yöntem


25

Aşağıdaki integrali sayısal olarak değerlendirmem gerekiyor:

0sbennc'(xr)rE(r)dr

burada , x \ in \ mathbb {R} _ + ve \ lambda, \ kappa, \ nu> 0 . Burada K , ikinci türün değiştirilmiş Bessel işlevidir. Benim özel durumumda \ lambda = 0.00313 , \ kappa = 0.00825 ve \ nu = 0.33 .xR+λ,κ,ν>0Kλ=0.00313κ=0.00825ν=E(r)=r4(λκ2+r2)-ν-5/2K-ν-5/2(λκ2+r2)xR,+λ,κ,ν>0Kλ=0,00313κ=0,00825ν=0.33

MATLAB kullanıyorum ve yerleşik fonksiyonları denedim integralve quadgkbu da bana çok fazla hata veriyor (aşağıya bakınız). Doğal olarak bu tür parçalar ile entegre ve gelen integraller toplayarak olarak, hem de çok sayıda başka şeyler denedim kxπ için (k+1)xπ .

Peki, daha sonra hangi yöntemi denemem gerektiği konusunda herhangi bir öneriniz var mı?

GÜNCELLEME (eklenmiş sorular)
PEDRO'yu bağlantılı olarak okudum ve anlaşılması zor olduğunu sanmıyorum. Ancak birkaç sorum var:

  • tek değişkenli Levin yönteminde temel öğeleri olarak kullanmak uygun olur mu?xkψk
  • Salınımların sıklığı sabit olduğu için bunun yerine sadece bir Filon yöntemi kullanabilir miyim?

Örnek kod
>> 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


İntegralinizde nedir ? x
Pedro

Olumlu, gerçek sayı. Yayınımı yeni güncelledim.
torbonde

Bazı kod ve hataları gösterebiliyorsanız, birçoğunu çözmek için muhtemelen çok zor değildir. Elbette, lütfen önce hatayı dikkatlice okumayı deneyin ve kendi başınıza kaybolabilir mi görün.
Dennis Jaheruddin

Bugün daha sonra bazı kod ve hatalarla yorum yapacağım. Veya yarın.
Torbonde

Tamam, unuttum. Ama şimdi yazımı bir örnekle güncelledim ( açıkça hesaplayarak integrali ikiye ). sinc
torbonde

Yanıtlar:


12

quadccMatlab entegratörlerinden büyük ölçüde daha iyi başa çıkabilen ve daha güvenilir bir hata tahmini sağlayan kendi entegratörümü yazdım .

Sorununuz için kullanmak için aşağıdakileri yaptım:

>> 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) );

İşlev fşimdi sizin integrandiniz. Sadece eski bir değer atadığımı unutmayın x.

Sonsuz bir alana entegre etmek için değişkenlerin yerine geçiyorum:

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

yani g, 0'dan 1'e entegrasyon f, 0'dan kadar entegrasyonla aynı olmalıdır . Farklı dönüşümler farklı kalite sonuçlarına yol açabilir: Matematiksel olarak tüm dönüşümler aynı sonucu vermelidir, ancak farklı dönüşümler daha yumuşak veya daha kolay entegre edilebilir s üretebilir .g

Daha sonra her iki taraftakilerle quadccbaşa çıkabilen kendi entegratörümü arıyorum NaN:

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

Hata tahmininin çok büyük olduğunu, yani quadccsonuçlara pek güvenmediğini unutmayın. İşleve bakarsak, bu, gerçek integralin üzerindeki üç büyüklük değerinde salındığı için bu şaşırtıcı değildir. Yine, farklı bir aralık dönüşümü kullanmak daha iyi sonuçlar üretebilir.

Ayrıca gibi daha spesifik yöntemlerle bakmak isteyebilirsiniz bu . Bu biraz daha karmaşık, ama kesinlikle bu tür bir problem için doğru yöntem .


Çok teşekkür ederim. Farklı yöntemlere bakacağım. Amaçlarım için, hatanın integraleşdeğerde standart olduğu kadar küçük olması gerekmez (1e-10 sanırım), ancak 1.7e + 07 hala gerçekten çok büyük. Bahsettiğiniz gibi, belki başka bir dönüşüm iyi sonuç verecektir.
torbonde

@ cimrg.joe: Hata tahmininin, diğerleri arasında, integrand'in maksimum mutlak değerlerine dayanan mutlak hatanın bir tahmini olduğunu unutmayın. Bazı aşırı durumlarda, döndürülen değer aslında oldukça iyi olabilir. On doğruluk rakamı arıyorsanız, yazımın sonunda bahsettiğim Levin tipi yöntemleri kullanmanızı şiddetle tavsiye ediyorum.
Pedro

Belki 10 basamak hassasiyete ihtiyacım yok, ama bence en az beşe ihtiyacım var. Yöntemin bunu üretebilir mi?
torbonde

Metod, aralığın sağ ucundaki değerler, integralin kendisinden daha büyük büyüklük dereceleri olduğundan, integraliniz için bu tür bir hassasiyet garanti edemez.
Pedro

11

Pedro'nun işaret ettiği gibi, Levin tipi yöntemler bu tür sorunlar için en iyi kullanılan yöntemlerdir.

Mathematica'ya erişimin var mı? Bu problem için, Mathematica varsayılan olarak bunları algılar ve kullanır:

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.

İşte x değerleri aralığında bir çizim:

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 ile x = 10 arasında arsa

Ayrıca, bu durumda hafif bir performans iyileştirmesi sağlayabilecek özel Levin tipi yöntemi de manuel olarak belirleyebilirsiniz:

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'daki Levin tipi yöntemlerin ayrıntıları için belgelere bakın .


Maalesef, Mathematica - only MATLAB'a erişimim yok. Sorumu, ekli sorularla, @Pedro ile bağlantılı kağıtla ilgili olarak güncelleyeceğim.
torbonde

Tamam, dediğin gibi Matlab ile yapmak zorunda kalacaksın. Bununla ilgili başka bir cevap daha ekleyeceğim.
Andrew Moylan,

5

Mathematica'ya erişiminiz yoksa, Pedro'nun önerdiği gibi Matlab'da Levin tipi (veya başka bir özel osilatör) yöntem yazabilirsiniz.

Matlab için chebfun kütüphanesini kullanıyor musunuz ? Az önce burada temel bir Levin tipi yöntemin uygulanmasını içerdiğini öğrendim . Uygulama Olver tarafından yazılmıştır (osilasyonlu kuadratür alanındaki uzmanlardan biri). Tekillikler, uyarlanabilir alt bölümler vb. İle ilgilenmez, ancak başlamak için tam da ihtiyacınız olabilir.


Kendim bir Levin metodu uygulaması hakkında düşündüm, fakat bu zorluğa hazır olup olmadığımdan emin değilim. Sanırım yöntemi biraz daha iyi anlamam gerekiyor. Belki danışmanımla bunun hakkında konuşabilirim. Her neyse, Filon yöntemleri hakkında sormamın nedeni, uygulanmaları daha kolay görünüyor. Ve son derece yüksek bir doğruluğa ihtiyacım olmadığından, ama bu benim yüksek lisans
tezimin bir

Chebfun kütüphanesine (etkileyici) ve Levin entegrasyonu örneğine bir göz attım. Ama çalışmasını sağlayamıyorum. Aslında bunu ilgili soru gönderdiniz burada .
torbonde

0

Pedro'nun önerdiği dönüşüm harika bir fikir. Matlab'ın "quadgk" fonksiyonundaki parametrelerle oynamayı denediniz mi? Örneğin, Pedro'nun dönüşümünü kullanarak, aşağıdakileri yapabilirsiniz: Bunu
quadgk(f, 0.0+eps, 1.0-eps, 'AbsTol', eps, 'MaxIntervalCount', 100000)
kullanmak bana bir çözüm sunar:
-2184689.50220729
ve sadece 0.8 saniye sürer (yukarıda belirtilen değerleri kullanarak: x = 10)
Walter Gander ve Walter Gautschi'nin Matlab'la uyarlanmış dörtgen üzerinde bir makalesi var kullanabileceğiniz kod ( buraya link )

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.