Mã python tích phân kép

Cách đây không lâu, tôi đã thực hiện một số nghiên cứu về lý thuyết số giải tích. Đó chỉ là vì lợi ích của riêng tôi ở nhà vào buổi tối. Đó chỉ là một dự án sở thích để thỏa mãn trí tò mò của tôi

Vấn đề

Tại một thời điểm nào đó, tôi gặp phải một tích phân kép khó chịu và tôi muốn kiểm tra xem những gì tôi tìm được có thực sự đúng hay không. Để thêm một số ngữ cảnh cho người đọc quan tâm, tôi đã cố gắng tìm một công thức cho số lượng các số nguyên tố sinh đôi bên dưới một số đã cho bằng cách sử dụng hàm đếm số nguyên tố và một số kỹ thuật từ giải tích phức… Phew. , bây giờ thì đã hết cách, hãy tiếp tục với câu chuyện

Vì vậy, người ta sẽ làm gì khi đối mặt với một vấn đề như vậy liên quan đến một chức năng không liên tục cao? . Trong trường hợp của tôi, ngôn ngữ lập trình của tôi là Python, vì vậy tôi đã tạo một tệp python trống với hy vọng quá trình này chỉ mất từ ​​10 đến 15 phút

tôi đã sai. Nguyên nhân? . Vấn đề là khi tôi muốn tích hợp chúng

“Thông thường, các thư viện liên quan đến khoa học hoặc dữ liệu của Python sẽ tiết kiệm thời gian, nhưng lần này nó đã làm tôi thất bại. ”

Bây giờ, SciPy có một gói [tất nhiên] cho loại thứ này được gọi là quad. Và đó là lý do tại sao ban đầu tôi nghĩ rằng nó sẽ dễ dàng. Thông thường, các thư viện liên quan đến khoa học hoặc dữ liệu của Python tiết kiệm thời gian và thường rất dễ sử dụng, nhưng lần này tôi đã thất bại. Vấn đề là tích phân của tôi [tích phân kép của tôi] có một cực trong khoảng tích phân

Một sự tương tự đơn giản

Giả sử bạn muốn tính tích phân sau

Tôi thực sự đã thử ví dụ này và nó không hoạt động. Hàm này hoàn toàn hữu hạn trong một lân cận xung quanh 0 nhưng khi tôi thử tính toán nó, tôi liên tục nhận được giá trị nan. Tôi ngay lập tức hiểu chuyện gì đang xảy ra

SciPy đang sử dụng thứ gì đó như tổng Riemann hoặc quy tắc Hình thang để tính tích phân và yêu cầu thuật toán chia khoảng tích phân thành nhiều khoảng nhỏ. Việc tính diện tích của các hình chữ nhật nhỏ tương ứng đòi hỏi nó phải tính giá trị hàm của tất cả các điểm cuối khoảng này — một trong số chúng là [rất gần] bằng không

Và tất nhiên, cố gắng chia cho 0 trong Python sẽ ném ZeroDivisonError. Hóa ra, ít nhất theo tài liệu của SciPy, nên có một số cách xung quanh nó. Ví dụ, người ta có thể chỉ định các cực đã biết [tất nhiên điều này đòi hỏi chúng ta phải biết các cực của hàm không phải lúc nào cũng đúng], nhưng một lần nữa, điều đó không hoạt động với tích phân kép của tôi [mặc dù nó thực sự hoạt động đối với tích phân kép].

Kế hoạch

Điểm của tất cả các giới thiệu này là như sau

  • Một công cụ tích hợp số chỉ nên quan tâm đến sự hội tụ — chứ không phải các cực
  • Bạn không cần phải tự tìm các cực hoặc thậm chí nghĩ về chúng
  • Bạn muốn thứ gì đó có thể hack được mà bạn có thể sửa đổi để phù hợp với nhu cầu của mình. g. sửa đổi lỗi so với tham số thời gian chạy [chúng ta sẽ tìm hiểu vấn đề này một chút]
  • Các lỗi phải có ý nghĩa và dễ hiểu

Tại thời điểm này, tôi đã rất thất vọng, vì vậy tôi quyết định tự xây dựng một công cụ

Sau khi nhận ra rằng tôi phải làm điều này, tôi cần phải đi lấy thêm một ít cà phê và suy nghĩ về một thiết kế cho công cụ này. Tất nhiên bạn có thể làm điều này theo nhiều cách khác nhau. Tôi đã sử dụng phương pháp nhẹ nhất vì tôi tin rằng một công cụ như vậy cần phải điều chỉnh liên tục để phù hợp với nhu cầu của người dùng

Hãy xây dựng nó

Tôi quyết định thiết kế hướng đối tượng, chọn xây dựng một lớp xung quanh chức năng được tích hợp. Tôi đã làm điều này để người dùng có thể dễ dàng thêm nhiều tính năng hơn vào nó trong tương lai và để lưu thông tin meta về phép tính, chẳng hạn như khoảng thời gian lỗi, v.v.

Mật mã

Hãy bắt đầu với những điều cơ bản. Trước hết, chương trình này chỉ thực sự phụ thuộc vào Numpy. Tuy nhiên, để thuận tiện, chúng tôi sẽ nhập quad

Nếu bạn chưa cài đặt các gói này, bạn có thể cài đặt chúng bằng

pip install numpy quad

hoặc pip3 tùy thuộc vào hệ điều hành của bạn

Để mã trong bài viết này hoạt động, bạn cần chạy mã đó bằng Python 3

Hãy tạo lớp Tích hợp

Một vài nhận xét theo thứ tự ở đây. Đầu tiên, tôi ghi lại lỗi và bạn sẽ thấy tại sao trong giây lát. Thứ hai, chúng tôi có một thuộc tính dấu hiệu được xác định. Điều này là do khi các giới hạn của phép hoán đổi tích phân, thì dấu của giá trị cũng vậy và chúng ta cần có khả năng tính tích phân khi giới hạn dưới lớn hơn giới hạn trên. Điều này tất nhiên chỉ để cho bạn thấy làm thế nào bạn có thể làm điều này

Và bây giờ là phương pháp tích hợp chính [đơn]

Tôi đã sử dụng quy tắc hình thang ở đây [nếu bạn không nhớ, về cơ bản đây là trung bình cộng của tổng Riemann trái và phải], nhưng điều đó không có gì ngạc nhiên. Bạn có thể thắc mắc tại sao tôi có một mệnh đề try/ngoại trừ lớn xung quanh. Đó thực sự là một trong những điểm chính. Những gì nó làm là nếu có một phép chia cho 0 ẩn trong đó, thì nó sẽ bị bỏ qua một cách duyên dáng mà không cần đầu vào từ người dùng

Chúng tôi cũng thấy rằng chúng tôi đã lưu trữ lỗi nếu một người muốn tính toán theo số học khoảng hoặc chỉ kiểm tra xem kết quả chính xác như thế nào

Điều đó tốt thôi, nhưng chúng ta sử dụng công cụ của mình như thế nào?

Điều này trở nên dễ dàng ngay bây giờ, bất chấp biểu thức “0/0” khi x = 0

và bây giờ chúng tôi nhận được câu trả lời khoảng 1. 892166. Khá tốt

Nhưng chúng ta chưa xong đâu, nhớ không?

Vì vậy, chúng ta cần tổng quát hóa mã này để tính tích phân kép, nhưng trước tiên, hãy đảm bảo rằng chúng ta hiểu các lỗi có thể mắc phải. Để làm được điều đó, chúng ta cần xây dựng một lớp lỗi tùy chỉnh trong Python. Điều này thật dễ dàng, chúng tôi chỉ kế thừa từ Ngoại lệ

Ngoài ra, vì các khoảng thời gian đầu vào bây giờ phải là một tham số của loại danh sách danh sách [hoặc một cái gì đó tương tự], nên một giải pháp khả thi là như sau

Ghi chú. Đây hoàn toàn không phải là mã hiệu suất và nếu muốn, chúng tôi có thể tối ưu hóa mã này bằng e. g. vector hóa trong Numpy

Điều đó đang được nói, bạn có thể điều chỉnh tham số độ chính xác để phù hợp với nhu cầu của mình. Giá trị càng cao, tích phân sẽ càng chính xác, nhưng sẽ mất nhiều thời gian hơn để tính toán. Đó là nơi thuộc tính lỗi xuất hiện. Bạn có thể thử làm bài tập để tối ưu hóa mã này

Nếu muốn, tất nhiên chúng ta có thể tổng quát hóa điều này thành tích phân ba, v.v. nhưng đối với phạm vi của bài viết này, hãy tập trung vào những cái đơn và đôi

Hãy sử dụng công cụ hoàn toàn mới của chúng tôi

Vì vậy, hãy để tôi chỉ cho bạn cách nó hoạt động

Giả sử bạn đang làm việc trên một dự án bằng Python và đột nhiên, bạn gặp phải vấn đề tính gần đúng tích phân sau

Chà, bây giờ bạn đã có công cụ cho công việc. Ở đầu tệp của bạn, hãy nhập công cụ tích hợp mới của bạn

Xa hơn nữa trong dự án, bây giờ bạn có thể giải quyết nó

Điều này mang lại một đầu ra của

The result is 3.1415926535897944The accuracy of this result is -1.7319479184152442e-14

Điều này là khá d… gần. Để so sánh với thỏa thuận thực sự, sự khởi đầu thực sự của số pi là 3. 141592653589793238… và phạm vi lỗi của chúng tôi tất nhiên đã cho chúng tôi biết chính xác điều đó— cụ thể là, chúng tôi đã tính đúng 14 chữ số đầu tiên [Ít nhất là trong giới hạn tích hợp của chúng tôi - chúng tôi cần cẩn thận một chút trong ví dụ của mình vì về mặt kỹ thuật, chúng tôi đang thiếu “các đuôi . Tất nhiên, việc tăng tham số độ chính xác hoặc giới hạn của tích phân cho vấn đề đó sẽ cho chúng ta nhiều chữ số hơn đúng không

Nhưng đây là điểm quan trọng

Mặc dù tích phân kép ở trên phải được tính trên toàn bộ mặt phẳng thực, nhưng chúng ta có thể đảm bảo rằng trong khoảng của mình, chúng ta có thể tiến gần đến giá trị thực một cách tùy ý — và chúng ta có thể kiểm tra điều đó nhờ thuộc tính sai số của mình. Vì vậy, đó là vấn đề trao đổi độ chính xác cho thời gian chạy

Bây giờ tôi có thể quay lại công việc của mình và hy vọng rằng nếu bạn gặp phải một số vấn đề theo hướng này hoặc nếu bạn chỉ muốn tìm hiểu thêm về Python, vui lòng sử dụng hoặc mở rộng mã này

Bạn có thể sao chép toàn bộ kho lưu trữ tại đây

Sau 7 cốc cà phê, giờ tôi có thể yên tâm đi ngủ. Tôi chỉ hy vọng rằng tôi sẽ không bị Riemann điên truy đuổi trong những giấc mơ của tôi

Chủ Đề