Phương pháp tích phân số của tích phân dao động khó


25

Tôi cần đánh giá số nguyên dưới đây:

0sinc(xr)rE(r)dr

trong đó , và . Ở đây là hàm Bessel biến đổi của loại thứ hai. Trong trường hợp cụ thể của tôi, tôi có , và .E(r)=r4(λκ2+r2)ν5/2Kν5/2(λκ2+r2)xR+λ,κ,ν>0Kλ=0.00313κ=0.00825ν=0.33

Tôi đang sử dụng MATLAB và tôi đã thử các hàm dựng sẵn integralquadgk, điều này mang lại cho tôi rất nhiều lỗi (xem bên dưới). Tôi cũng đã tự nhiên thử rất nhiều thứ khác, chẳng hạn như tích hợp bởi các bộ phận và tính tổng các tích phân từ đến .kxπ(k+1)xπ

Vì vậy, bạn có gợi ý nào về phương pháp nào tôi nên thử tiếp theo không?

CẬP NHẬT (thêm câu hỏi)
Tôi đọc bài báo @Pedro được liên kết đến và tôi không nghĩ nó quá khó hiểu. Tuy nhiên, tôi có một vài câu hỏi:

  • Có thể sử dụng làm các yếu tố cơ bản , trong phương pháp Levin đơn biến được mô tả không?xkψk
  • Thay vào đó tôi có thể sử dụng phương pháp Filon không, vì tần số dao động là cố định?

Mã ví dụ
>> 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


Là gì trong không thể thiếu của bạn? x
Pedro

Bất kỳ số dương, số thực. Tôi vừa cập nhật bài viết của tôi.
torbonde

Nếu bạn có thể hiển thị một số mã và lỗi, có lẽ không quá khó để giải quyết hầu hết chúng. Tất nhiên, vui lòng thử đọc lỗi một cách cẩn thận trước và xem liệu bạn có thể tự khắc phục nó không.
Dennis Jaheruddin

Tôi sẽ đưa ra một nhận xét sau ngày hôm nay với một số mã và lỗi. Hay ngày mai.
torbonde

Được rồi, vì vậy tôi quên. Nhưng bây giờ tôi cập nhật bài của tôi với một ví dụ (Tôi có chia không thể thiếu trong hai bằng cách tính toán rõ ràng). Stôinc'
torbonde

Câu trả lời:


12

Tôi đã viết bộ tích hợp của riêng mình, quadccứng dụng này tốt hơn đáng kể so với bộ tích hợp Matlab với các điểm kỳ dị và cung cấp ước tính lỗi đáng tin cậy hơn.

Để sử dụng nó cho vấn đề của bạn, tôi đã làm như sau:

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

Các chức năng fbây giờ là integrand của bạn. Lưu ý rằng tôi vừa gán bất kỳ giá trị cũ nào x.

Để tích hợp trên một miền vô hạn, tôi áp dụng thay thế các biến:

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

tức là tích hợp g0-1 nên được giống như tích hợp ftừ 0 đến . Các biến đổi khác nhau có thể tạo ra kết quả chất lượng khác nhau: Về mặt toán học, tất cả các biến đổi sẽ cho cùng một kết quả, nhưng các biến đổi khác nhau có thể tạo ra mượt mà hơn hoặc dễ dàng tích hợp hơn .g

Sau đó, tôi gọi cho nhà tích hợp của riêng tôi quadcc, có thể xử lý các NaNs ở cả hai đầu:

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

Lưu ý rằng ước tính lỗi là rất lớn, tức là quadcckhông có nhiều niềm tin vào kết quả. Tuy nhiên, nhìn vào hàm, điều này không có gì đáng ngạc nhiên vì nó dao động ở các giá trị ba bậc độ lớn trên tích phân thực. Một lần nữa, sử dụng một biến đổi khoảng khác nhau có thể tạo ra kết quả tốt hơn.

Bạn cũng có thể muốn xem xét các phương pháp cụ thể hơn như thế này . Nó liên quan nhiều hơn một chút, nhưng chắc chắn là phương pháp phù hợp cho loại vấn đề này.


Cảm ơn nhiều. Tôi sẽ có một cái nhìn về các phương pháp khác nhau. Đối với mục đích của tôi, lỗi không cần phải nhỏ như tiêu chuẩn trong eq integral(tôi nghĩ là 1e-10), nhưng 1.7e + 07 vẫn thực sự rất lớn. Có lẽ một biến đổi khác sẽ làm tốt, như bạn đề cập.
torbonde

@ cimrg.joe: Lưu ý rằng ước tính lỗi là ước tính sai số tuyệt đối dựa trên các giá trị tuyệt đối tối đa của tích phân. Trong một số trường hợp cực đoan, giá trị trả về có thể thực sự khá ok. Nếu bạn đang tìm kiếm mười chữ số chính xác, thì tôi thực sự khuyên bạn nên sử dụng các phương pháp loại Levin mà tôi đã đề cập ở cuối bài viết của mình.
Pedro

Tôi có thể không cần mười chữ số chính xác, nhưng tôi nghĩ tôi cần ít nhất năm chữ số. Phương pháp của bạn có thể tạo ra điều đó?
torbonde

Phương pháp không thể đảm bảo loại chính xác cho tích phân của bạn vì các giá trị ở cuối bên phải của khoảng là một số bậc lớn hơn chính tích phân.
Pedro

11

Như Pedro chỉ ra, các phương pháp kiểu Levin là phương pháp được thiết lập tốt nhất cho các loại vấn đề này.

Bạn có quyền truy cập vào Mathicala? Đối với vấn đề này, Mathicala sẽ phát hiện và sử dụng chúng theo mặc định:

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.

Đây là một âm mưu trong một loạt các giá trị của x:

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

Âm mưu từ x = 0,5 đến x = 10

Bạn cũng có thể chỉ định thủ công phương pháp loại Levin cụ thể để áp dụng, trong trường hợp này có thể mang lại sự cải thiện hiệu suất nhẹ:

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.

Xem tài liệu để biết chi tiết về các phương pháp loại Levin trong Mathicala .


Thật không may, tôi không có quyền truy cập vào Mathicala - chỉ MATLAB. Tôi sẽ chỉ cập nhật câu hỏi của mình với một số câu hỏi được thêm vào, liên quan đến bài báo @Pedro được liên kết đến.
torbonde

OK, như bạn nói bạn sẽ phải làm với Matlab. Tôi sẽ thêm một câu trả lời về điều đó.
Andrew Moylan

5

Nếu bạn không có quyền truy cập vào Mathicala, bạn có thể viết phương pháp kiểu Levin (hoặc dao động chuyên dụng khác) trong Matlab như Pedro gợi ý.

Bạn có sử dụng thư viện chebfun cho Matlab không? Tôi mới biết nó chứa một triển khai phương pháp kiểu Levin cơ bản ở đây . Việc thực hiện được viết bởi Olver (một trong những chuyên gia trong lĩnh vực cầu phương dao động). Nó không giải quyết các điểm kỳ dị, phân khu thích ứng, v.v., nhưng nó có thể chỉ là những gì bạn cần để bắt đầu.


Tôi đã nghĩ về việc thực hiện một phương pháp Levin cho mình, nhưng tôi không chắc liệu tôi đã sẵn sàng cho thử thách chưa. Tôi nghĩ rằng tôi cần phải hiểu phương pháp tốt hơn một chút. Có lẽ tôi có thể nói chuyện với cố vấn của tôi về điều đó. Dù sao, lý do mà tôi hỏi về các phương pháp Filon, là chúng có vẻ dễ thực hiện hơn. Và vì tôi không cần độ chính xác cực cao, nhưng đây là một phần trong luận văn thạc sĩ của tôi, khó khăn sẽ tăng lên.
torbonde

Tôi đã xem qua thư viện chebfun (rất ấn tượng) và ví dụ tích hợp Levin. Nhưng tôi không thể chạy nó. Tôi thực sự đã đăng một câu hỏi liên quan đến nó ở đây .
torbonde

0

Việc chuyển đổi được đề xuất bởi Pedro là một ý tưởng tuyệt vời. Bạn đã thử chơi xung quanh với các tham số trong chức năng "quadgk" của Matlab chưa? Ví dụ: sử dụng phép biến đổi của Pedro, bạn có thể thực hiện như sau:
quadgk(f, 0.0+eps, 1.0-eps, 'AbsTol', eps, 'MaxIntervalCount', 100000)
Sử dụng phương pháp này mang lại cho tôi một giải pháp:
-2184689.50220729
và chỉ mất 0,8 giây (sử dụng các giá trị được đề cập ở trên: x = 10)
Walter Gander và Walter Gautschi có một bài viết về phương pháp thích nghi với Matlab mã bạn cũng có thể sử dụng (liên kết tại đây )

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.