Hướng dẫn how do you find the integral in python? - làm thế nào để bạn tìm thấy tích phân trong python?

Gói phụ

>>> print(abs(result[0]-I))
1.03761443881e-11
4 cung cấp một số kỹ thuật tích hợp bao gồm một bộ tích hợp phương trình vi phân thông thường. Tổng quan về mô -đun được cung cấp bởi lệnh trợ giúp:

>>> help(integrate)
 Methods for Integrating Functions given function object.

   quad          -- General purpose integration.
   dblquad       -- General purpose double integration.
   tplquad       -- General purpose triple integration.
   fixed_quad    -- Integrate func(x) using Gaussian quadrature of order n.
   quadrature    -- Integrate with given tolerance using Gaussian quadrature.
   romberg       -- Integrate func using Romberg integration.

 Methods for Integrating Functions given fixed samples.

   trapezoid            -- Use trapezoidal rule to compute integral.
   cumulative_trapezoid -- Use trapezoidal rule to cumulatively compute integral.
   simpson              -- Use Simpson's rule to compute integral from samples.
   romb                 -- Use Romberg Integration to compute integral from
                        -- (2**k + 1) evenly-spaced samples.

   See the special module's orthogonal polynomials (special) for Gaussian
      quadrature roots and weights for other weighting factors and regions.

 Interface to numerical integrators of ODE systems.

   odeint        -- General integration of ordinary differential equations.
   ode           -- Integrate ODE using VODE and ZVODE routines.

Tích hợp chung (________ 35)#

Hàm

>>> print(abs(result[0]-I))
1.03761443881e-11
5 được cung cấp để tích hợp một hàm của một biến giữa hai điểm. Các điểm có thể là \ (\ pm \ infty \) (\ (\ pm \)
>>> print(abs(result[0]-I))
1.03761443881e-11
7) để chỉ ra các giới hạn vô hạn. Ví dụ: giả sử bạn muốn tích hợp hàm Bessel
>>> print(abs(result[0]-I))
1.03761443881e-11
8 dọc theo khoảng \ ([0, 4.5]. \)\(\pm\infty\) (\(\pm\)
>>> print(abs(result[0]-I))
1.03761443881e-11
7) to indicate infinite limits. For example, suppose you wish to integrate a bessel function
>>> print(abs(result[0]-I))
1.03761443881e-11
8 along the interval \([0, 4.5].\)

\ [I = \ int_ {0}^{4.5} j_ {2.5} \ left (x \ right) \, dx. \]

Điều này có thể được tính toán bằng cách sử dụng

>>> print(abs(result[0]-I))
1.03761443881e-11
5:

>>> import scipy.integrate as integrate
>>> import scipy.special as special
>>> result = integrate.quad(lambda x: special.jv(2.5,x), 0, 4.5)
>>> result
(1.1178179380783249, 7.8663172481899801e-09)

>>> from numpy import sqrt, sin, cos, pi
>>> I = sqrt(2/pi)*(18.0/27*sqrt(2)*cos(4.5) - 4.0/27*sqrt(2)*sin(4.5) +
...                 sqrt(2*pi) * special.fresnel(3/sqrt(pi))[0])
>>> I
1.117817938088701

>>> print(abs(result[0]-I))
1.03761443881e-11

Đối số đầu tiên của Quad là đối tượng Python có thể gọi được của người Viking (nghĩa là, một hàm, phương thức hoặc thể hiện lớp). Lưu ý việc sử dụng chức năng Lambda trong trường hợp này làm đối số. Hai đối số tiếp theo là các giới hạn của hội nhập. Giá trị trả về là một tuple, với phần tử đầu tiên giữ giá trị ước tính của tích phân và phần tử thứ hai giữ một giới hạn trên trên lỗi. Lưu ý rằng trong trường hợp này, giá trị thực của tích phân này là

\ [I = \ sqrt {\ frac {2} {\ pi}} \ left (\ frac {18} {27} \ sqrt } \ sqrt {2} \ sin \ left (4.5 \ right)+\ sqrt {2 \ pi} \ textrm {si} \ trái (\ frac , \]

ở đâu

\ [\ Textrm {si} \ left (x \ right) = \ int_ {0}^{x} \ sin \ left (\ frac {\ pi} {2} t^{2} \ right) \, dt. \]

là tích phân sin Fresnel. Lưu ý rằng tích phân được tính toán bằng số nằm trong \ (1.04 \ lần10^{-11} \) của kết quả chính xác-thấp hơn mức lỗi được báo cáo.\(1.04\times10^{-11}\) of the exact result — well below the reported error bound.

Nếu hàm để tích hợp có các tham số bổ sung, chúng có thể được cung cấp trong đối số Args. Giả sử rằng tích phân sau sẽ được tính toán:

\ [I (a, b) = \ int_ {0}^{1} ax^2+b \, dx. \]

Tích hợp này có thể được đánh giá bằng cách sử dụng mã sau:

>>> from scipy.integrate import quad
>>> def integrand(x, a, b):
...     return a*x**2 + b
...
>>> a = 2
>>> b = 1
>>> I = quad(integrand, 0, 1, args=(a,b))
>>> I
(1.6666666666666667, 1.8503717077085944e-14)

Đầu vào vô hạn cũng được cho phép trong

>>> print(abs(result[0]-I))
1.03761443881e-11
5 bằng cách sử dụng \ (\ pm \)
>>> print(abs(result[0]-I))
1.03761443881e-11
7 làm một trong những đối số. Ví dụ: giả sử rằng một giá trị số cho tích phân theo cấp số nhân:\(\pm\)
>>> print(abs(result[0]-I))
1.03761443881e-11
7 as one of the arguments. For example, suppose that a numerical value for the exponential integral:

A

được mong muốn (và thực tế là tích phân này có thể được tính toán là

>>> from scipy.integrate import quad
>>> def integrand(x, a, b):
...     return a*x**2 + b
...
>>> a = 2
>>> b = 1
>>> I = quad(integrand, 0, 1, args=(a,b))
>>> I
(1.6666666666666667, 1.8503717077085944e-14)
2 bị lãng quên). Chức năng của hàm
>>> from scipy.integrate import quad
>>> def integrand(x, a, b):
...     return a*x**2 + b
...
>>> a = 2
>>> b = 1
>>> I = quad(integrand, 0, 1, args=(a,b))
>>> I
(1.6666666666666667, 1.8503717077085944e-14)
3 có thể được sao chép bằng cách xác định hàm mới
>>> from scipy.integrate import quad
>>> def integrand(x, a, b):
...     return a*x**2 + b
...
>>> a = 2
>>> b = 1
>>> I = quad(integrand, 0, 1, args=(a,b))
>>> I
(1.6666666666666667, 1.8503717077085944e-14)
4 dựa trên thói quen
>>> print(abs(result[0]-I))
1.03761443881e-11
5:

>>> from scipy.integrate import quad
>>> def integrand(t, n, x):
...     return np.exp(-x*t) / t**n
...

>>> def expint(n, x):
...     return quad(integrand, 1, np.inf, args=(n, x))[0]
...

>>> vec_expint = np.vectorize(expint)

>>> vec_expint(3, np.arange(1.0, 4.0, 0.5))
array([ 0.1097,  0.0567,  0.0301,  0.0163,  0.0089,  0.0049])
>>> import scipy.special as special
>>> special.expn(3, np.arange(1.0,4.0,0.5))
array([ 0.1097,  0.0567,  0.0301,  0.0163,  0.0089,  0.0049])

Hàm được tích hợp thậm chí có thể sử dụng đối số Quad (mặc dù ràng buộc lỗi có thể đánh giá thấp lỗi do lỗi số có thể có trong tích phân từ việc sử dụng

>>> print(abs(result[0]-I))
1.03761443881e-11
5). Tích hợp trong trường hợp này là

\ [I_ {n} = \ int_ {0}^{\ infty} \ int_ {1}^{\ infty} \ frac {e^{-xt}} = \ frac {1} {n}. \]

>>> result = quad(lambda x: expint(3, x), 0, np.inf)
>>> print(result)
(0.33333333324560266, 2.8548934485373678e-09)

>>> import scipy.integrate as integrate
>>> import scipy.special as special
>>> result = integrate.quad(lambda x: special.jv(2.5,x), 0, 4.5)
>>> result
(1.1178179380783249, 7.8663172481899801e-09)
0

>>> import scipy.integrate as integrate
>>> import scipy.special as special
>>> result = integrate.quad(lambda x: special.jv(2.5,x), 0, 4.5)
>>> result
(1.1178179380783249, 7.8663172481899801e-09)
1

Ví dụ cuối cùng này cho thấy rằng nhiều tích hợp có thể được xử lý bằng cách sử dụng các cuộc gọi lặp lại đến

>>> print(abs(result[0]-I))
1.03761443881e-11
5.

Tích hợp đa nói chung (>>> from scipy.integrate import quad >>> def integrand(x, a, b): ... return a*x**2 + b ... >>> a = 2 >>> b = 1 >>> I = quad(integrand, 0, 1, args=(a,b)) >>> I (1.6666666666666667, 1.8503717077085944e-14) 8, >>> from scipy.integrate import quad >>> def integrand(x, a, b): ... return a*x**2 + b ... >>> a = 2 >>> b = 1 >>> I = quad(integrand, 0, 1, args=(a,b)) >>> I (1.6666666666666667, 1.8503717077085944e-14) 9, ________ 50)#

Các cơ chế để tích hợp gấp đôi và ba đã được kết thúc vào các chức năng

>>> from scipy.integrate import quad
>>> def integrand(x, a, b):
...     return a*x**2 + b
...
>>> a = 2
>>> b = 1
>>> I = quad(integrand, 0, 1, args=(a,b))
>>> I
(1.6666666666666667, 1.8503717077085944e-14)
8 và
>>> from scipy.integrate import quad
>>> def integrand(x, a, b):
...     return a*x**2 + b
...
>>> a = 2
>>> b = 1
>>> I = quad(integrand, 0, 1, args=(a,b))
>>> I
(1.6666666666666667, 1.8503717077085944e-14)
9. Các chức năng này có chức năng để tích hợp và bốn, hoặc sáu đối số, tương ứng. Các giới hạn của tất cả các tích phân bên trong cần được định nghĩa là các hàm.

Một ví dụ về việc sử dụng tích hợp kép để tính toán một số giá trị của \ (i_ {n} \) được hiển thị bên dưới:\(I_{n}\) is shown below:

>>> import scipy.integrate as integrate
>>> import scipy.special as special
>>> result = integrate.quad(lambda x: special.jv(2.5,x), 0, 4.5)
>>> result
(1.1178179380783249, 7.8663172481899801e-09)
2

>>> import scipy.integrate as integrate
>>> import scipy.special as special
>>> result = integrate.quad(lambda x: special.jv(2.5,x), 0, 4.5)
>>> result
(1.1178179380783249, 7.8663172481899801e-09)
3

Ví dụ cho các giới hạn không liên tục, hãy xem xét tích phân

\ [I = \ int_ {y = 0}^{1/2} \ int_ {x = 0}^{1-2y} x y \, dx \, dy = \ frac {1} {96}.

Tích phân này có thể được đánh giá bằng cách sử dụng biểu thức bên dưới (lưu ý việc sử dụng các hàm Lambda không liên tục cho giới hạn trên của tích phân bên trong):

>>> import scipy.integrate as integrate
>>> import scipy.special as special
>>> result = integrate.quad(lambda x: special.jv(2.5,x), 0, 4.5)
>>> result
(1.1178179380783249, 7.8663172481899801e-09)
4

Để tích hợp n-gấp, SCIPY cung cấp chức năng

>>> from scipy.integrate import quad
>>> def integrand(t, n, x):
...     return np.exp(-x*t) / t**n
...
0. Các giới hạn tích hợp là một đối tượng có thể lặp lại: một danh sách các giới hạn không đổi hoặc danh sách các hàm cho giới hạn tích hợp không liên tục. Thứ tự tích hợp (và do đó giới hạn) là từ tích phân trong cùng đến một trong số ngoài cùng.

Tích hợp từ trên cao

\ [I_ {n} = \ int_ {0}^{\ infty} \ int_ {1}^{\ infty} \ frac {e^{-xt}} = \ frac {1} {n} \]

có thể được tính là

>>> import scipy.integrate as integrate
>>> import scipy.special as special
>>> result = integrate.quad(lambda x: special.jv(2.5,x), 0, 4.5)
>>> result
(1.1178179380783249, 7.8663172481899801e-09)
5

Lưu ý rằng thứ tự các đối số cho F phải khớp với thứ tự của các giới hạn tích hợp; tức là, tích phân bên trong đối với \ (t \) nằm trên khoảng \ ([1, \ infy] \) và tích phân bên ngoài đối với \ (x \) nằm trên khoảng \ ([0, \ infy ] \).\(t\) is on the interval \([1, \infty]\) and the outer integral with respect to \(x\) is on the interval \([0, \infty]\).

Giới hạn tích hợp không liên tục có thể được xử lý theo cách tương tự; ví dụ từ trên cao

\ [I = \ int_ {y = 0}^{1/2} \ int_ {x = 0}^{1-2y} x y \, dx \, dy = \ frac {1} {96}.

Tích phân này có thể được đánh giá bằng cách sử dụng biểu thức bên dưới (lưu ý việc sử dụng các hàm Lambda không liên tục cho giới hạn trên của tích phân bên trong):

>>> import scipy.integrate as integrate
>>> import scipy.special as special
>>> result = integrate.quad(lambda x: special.jv(2.5,x), 0, 4.5)
>>> result
(1.1178179380783249, 7.8663172481899801e-09)
6

Để tích hợp n-gấp, SCIPY cung cấp chức năng

>>> from scipy.integrate import quad
>>> def integrand(t, n, x):
...     return np.exp(-x*t) / t**n
...
0. Các giới hạn tích hợp là một đối tượng có thể lặp lại: một danh sách các giới hạn không đổi hoặc danh sách các hàm cho giới hạn tích hợp không liên tục. Thứ tự tích hợp (và do đó giới hạn) là từ tích phân trong cùng đến một trong số ngoài cùng.

Tích hợp từ trên cao

\ [I_ {n} = \ int_ {0}^{\ infty} \ int_ {1}^{\ infty} \ frac {e^{-xt}} = \ frac {1} {n} \]

Tích hợp Romberg#

Phương pháp Romberg [WPR] là một phương pháp khác để đánh giá bằng số. Xem chức năng trợ giúp cho

>>> from scipy.integrate import quad
>>> def integrand(t, n, x):
...     return np.exp(-x*t) / t**n
...
8 để biết thêm chi tiết.[WPR] is another method for numerically evaluating an integral. See the help function for
>>> from scipy.integrate import quad
>>> def integrand(t, n, x):
...     return np.exp(-x*t) / t**n
...
8 for further details.

Tích hợp bằng cách sử dụng các mẫu#

Nếu các mẫu có khoảng cách đều nhau và số lượng mẫu có sẵn là \ (2^{k} +1 \) cho một số số nguyên \ (k \), thì romberg

>>> from scipy.integrate import quad
>>> def integrand(t, n, x):
...     return np.exp(-x*t) / t**n
...
9 có thể được sử dụng Sử dụng các mẫu có sẵn. Tích hợp Romberg sử dụng quy tắc hình thang ở các kích thước bước liên quan bởi sức mạnh của hai và sau đó thực hiện ngoại suy Richardson trên các ước tính này để xấp xỉ tích phân với mức độ chính xác cao hơn.\(2^{k}+1\) for some integer \(k\), then Romberg
>>> from scipy.integrate import quad
>>> def integrand(t, n, x):
...     return np.exp(-x*t) / t**n
...
9 integration can be used to obtain high-precision estimates of the integral using the available samples. Romberg integration uses the trapezoid rule at step-sizes related by a power of two and then performs Richardson extrapolation on these estimates to approximate the integral with a higher degree of accuracy.

Trong trường hợp các mẫu khoảng cách tùy ý, hai hàm

>>> def expint(n, x):
...     return quad(integrand, 1, np.inf, args=(n, x))[0]
...
0 và
>>> def expint(n, x):
...     return quad(integrand, 1, np.inf, args=(n, x))[0]
...
1 có sẵn. Họ đang sử dụng các công thức Newton-Coates theo thứ tự 1 và 2 tương ứng để thực hiện tích hợp. Quy tắc hình thang xấp xỉ hàm như một đường thẳng giữa các điểm liền kề, trong khi quy tắc Simpson, xấp xỉ hàm giữa ba điểm liền kề như một parabola.

Đối với một số mẫu lẻ của các mẫu có cách đặt cách đều nhau quy tắc Simpson, là chính xác nếu hàm là đa thức của thứ tự 3 hoặc ít hơn. Nếu các mẫu không được đặt cách đều nhau, thì kết quả chỉ chính xác nếu hàm là đa thức của thứ tự 2 hoặc ít hơn.

>>> import scipy.integrate as integrate
>>> import scipy.special as special
>>> result = integrate.quad(lambda x: special.jv(2.5,x), 0, 4.5)
>>> result
(1.1178179380783249, 7.8663172481899801e-09)
7

Điều này tương ứng chính xác với

\ [\ int_ {1}^{4} x^2 \, dx = 21, \]

trong khi đó tích hợp hàm thứ hai

>>> import scipy.integrate as integrate
>>> import scipy.special as special
>>> result = integrate.quad(lambda x: special.jv(2.5,x), 0, 4.5)
>>> result
(1.1178179380783249, 7.8663172481899801e-09)
8

không tương ứng với

\ [\ int_ {1}^{4} x^3 \, dx = 63,75 \]

bởi vì thứ tự của đa thức trong F2 lớn hơn hai.

Tích hợp nhanh hơn bằng cách sử dụng các chức năng gọi lại cấp thấp#

Một người dùng mong muốn giảm thời gian tích hợp có thể vượt qua con trỏ hàm C thông qua

>>> def expint(n, x):
...     return quad(integrand, 1, np.inf, args=(n, x))[0]
...
2 đến
>>> print(abs(result[0]-I))
1.03761443881e-11
5,
>>> from scipy.integrate import quad
>>> def integrand(x, a, b):
...     return a*x**2 + b
...
>>> a = 2
>>> b = 1
>>> I = quad(integrand, 0, 1, args=(a,b))
>>> I
(1.6666666666666667, 1.8503717077085944e-14)
8,
>>> from scipy.integrate import quad
>>> def integrand(x, a, b):
...     return a*x**2 + b
...
>>> a = 2
>>> b = 1
>>> I = quad(integrand, 0, 1, args=(a,b))
>>> I
(1.6666666666666667, 1.8503717077085944e-14)
9 hoặc
>>> from scipy.integrate import quad
>>> def integrand(t, n, x):
...     return np.exp(-x*t) / t**n
...
0 và nó sẽ được tích hợp và trả về kết quả của Python. Sự gia tăng hiệu suất ở đây phát sinh từ hai yếu tố. Cải thiện chính là đánh giá chức năng nhanh hơn, được cung cấp bằng cách tổng hợp chính hàm. Ngoài ra, chúng tôi có một tốc độ được cung cấp bởi việc loại bỏ các cuộc gọi chức năng giữa C và Python trong
>>> print(abs(result[0]-I))
1.03761443881e-11
5. Phương pháp này có thể cung cấp các cải tiến tốc độ ~ 2x cho các chức năng tầm thường như hình sin nhưng có thể tạo ra những cải tiến đáng chú ý hơn (10x+) cho các chức năng phức tạp hơn. Tính năng này sau đó, hướng đến một người dùng với các tích hợp chuyên sâu về số lượng sẵn sàng viết một chút C để giảm đáng kể thời gian tính toán.

Cách tiếp cận có thể được sử dụng, ví dụ, thông qua

>>> def expint(n, x):
...     return quad(integrand, 1, np.inf, args=(n, x))[0]
...
8 trong một vài bước đơn giản:

1.) Viết hàm tích phân trong C với chữ ký hàm

>>> def expint(n, x):
...     return quad(integrand, 1, np.inf, args=(n, x))[0]
...
9, trong đó
>>> vec_expint = np.vectorize(expint)
0 là một mảng chứa điểm hàm f được đánh giá tại và
>>> vec_expint = np.vectorize(expint)
1 để dữ liệu bổ sung tùy ý bạn muốn cung cấp.

>>> import scipy.integrate as integrate
>>> import scipy.special as special
>>> result = integrate.quad(lambda x: special.jv(2.5,x), 0, 4.5)
>>> result
(1.1178179380783249, 7.8663172481899801e-09)
9

2.) Bây giờ biên dịch tệp này với thư viện chia sẻ/động (một tìm kiếm nhanh sẽ giúp với điều này vì nó phụ thuộc vào hệ điều hành). Người dùng phải liên kết bất kỳ thư viện toán học nào, v.v., được sử dụng. Trên Linux, điều này trông giống như:

>>> from numpy import sqrt, sin, cos, pi
>>> I = sqrt(2/pi)*(18.0/27*sqrt(2)*cos(4.5) - 4.0/27*sqrt(2)*sin(4.5) +
...                 sqrt(2*pi) * special.fresnel(3/sqrt(pi))[0])
>>> I
1.117817938088701
0

Thư viện đầu ra sẽ được gọi là

>>> vec_expint = np.vectorize(expint)
2, nhưng nó có thể có một phần mở rộng tệp khác. Một thư viện hiện đã được tạo ra có thể được tải vào Python với
>>> def expint(n, x):
...     return quad(integrand, 1, np.inf, args=(n, x))[0]
...
8.

3.) Tải thư viện được chia sẻ vào Python bằng cách sử dụng

>>> def expint(n, x):
...     return quad(integrand, 1, np.inf, args=(n, x))[0]
...
8 và đặt
>>> vec_expint = np.vectorize(expint)
5 và
>>> vec_expint = np.vectorize(expint)
6 - Điều này cho phép SCIPY diễn giải chính xác chức năng:

>>> from numpy import sqrt, sin, cos, pi
>>> I = sqrt(2/pi)*(18.0/27*sqrt(2)*cos(4.5) - 4.0/27*sqrt(2)*sin(4.5) +
...                 sqrt(2*pi) * special.fresnel(3/sqrt(pi))[0])
>>> I
1.117817938088701
1

>>> vec_expint = np.vectorize(expint)
7 cuối cùng trong hàm là tùy chọn và có thể được bỏ qua (cả trong hàm C và ctypes argtypes) nếu không cần thiết. Lưu ý rằng các tọa độ được truyền vào như một mảng đôi thay vì một đối số riêng biệt.

4.) Bây giờ tích hợp chức năng thư viện như bình thường, ở đây bằng cách sử dụng

>>> from scipy.integrate import quad
>>> def integrand(t, n, x):
...     return np.exp(-x*t) / t**n
...
0:

>>> from numpy import sqrt, sin, cos, pi
>>> I = sqrt(2/pi)*(18.0/27*sqrt(2)*cos(4.5) - 4.0/27*sqrt(2)*sin(4.5) +
...                 sqrt(2*pi) * special.fresnel(3/sqrt(pi))[0])
>>> I
1.117817938088701
2

Tuple Python được trả lại như mong đợi trong một khoảng thời gian giảm. Tất cả các tham số tùy chọn có thể được sử dụng với phương pháp này bao gồm chỉ định điểm kỳ dị, giới hạn vô hạn, v.v.

Phương trình vi phân thông thường (________ 79)#

Tích hợp một tập hợp các phương trình vi phân thông thường (ODE) được đưa ra các điều kiện ban đầu là một ví dụ hữu ích khác. Hàm

>>> vec_expint = np.vectorize(expint)
9 có sẵn trong SCIPY để tích hợp phương trình vi phân vectơ bậc nhất:

\]

Cho các điều kiện ban đầu \ (\ mathbf {y} \ left (0 \ right) = y_ {0} \), trong đó \ (\ mathbf {y} \) là một vectơ \ (n \) và \ (\ mathbf { f} \) là một ánh xạ từ \ (\ mathcal {r}^{n} \) đến \ (\ mathcal {r}^{n}. \) Phương trình của loại này bằng cách giới thiệu các dẫn xuất trung gian vào vector \ (\ mathbf {y} \).\(\mathbf{y}\left(0\right)=y_{0}\), where \(\mathbf{y}\) is a length \(N\) vector and \(\mathbf{f}\) is a mapping from \(\mathcal{R}^{N}\) to \(\mathcal{R}^{N}.\) A higher-order ordinary differential equation can always be reduced to a differential equation of this type by introducing intermediate derivatives into the \(\mathbf{y}\) vector.

Ví dụ: giả sử nó mong muốn tìm giải pháp cho phương trình vi phân bậc hai sau:

\ [\ frac {d^{2} w} {dz^{2}}-zw (z) = 0 \]

với các điều kiện ban đầu \ (w \ left (0 \ right) = \ frac {1} {\ sqrt [3] {3^{2}} \ gamma \ left (\ frac {2} {3} \ right)} \ ) và \ (\ left. {3} \ right)}. \) Người ta biết rằng giải pháp cho phương trình vi phân này với các điều kiện biên này là hàm thoáng qua\(w\left(0\right)=\frac{1}{\sqrt[3]{3^{2}}\Gamma\left(\frac{2}{3}\right)}\) and \(\left.\frac{dw}{dz}\right|_{z=0}=-\frac{1}{\sqrt[3]{3}\Gamma\left(\frac{1}{3}\right)}.\) It is known that the solution to this differential equation with these boundary conditions is the Airy function

\ [W = \ Textrm {ai} \ trái (z \ phải), \]

trong đó cung cấp một phương tiện để kiểm tra bộ tích hợp bằng

>>> vec_expint(3, np.arange(1.0, 4.0, 0.5))
array([ 0.1097,  0.0567,  0.0301,  0.0163,  0.0089,  0.0049])
>>> import scipy.special as special
>>> special.expn(3, np.arange(1.0,4.0,0.5))
array([ 0.1097,  0.0567,  0.0301,  0.0163,  0.0089,  0.0049])
1.

Đầu tiên, hãy chuyển đổi ode này thành dạng tiêu chuẩn bằng cách cài đặt \ (\ mathbf {y} = \ left [\ frac {dw} {dz}, w \ right] \) và \ (t = z \). Do đó, phương trình vi phân trở thành\(\mathbf{y}=\left[\frac{dw}{dz},w\right]\) and \(t=z\). Thus, the differential equation becomes

\ [\ start = \ left [\ started {mảng} {cc} 0 & t \\ 1 & 0 \ end {mảng} \ right] \ left [\ start end {mảng} \ right] = \ trái [\ start

Nói cách khác,

\]

Như một lời nhắc nhở thú vị, nếu \ (\ mathbf {a} \ left (t \ right) \) đi lại với \ (\ int_ {0}^{t} \ mathbf {a} \ left (\ tau d \ tau \) trong phép nhân ma trận, sau đó phương trình vi phân tuyến tính này có một giải pháp chính xác bằng cách sử dụng ma trận theo cấp số nhân:\(\mathbf{A}\left(t\right)\) commutes with \(\int_{0}^{t}\mathbf{A}\left(\tau\right)\, d\tau\) under matrix multiplication, then this linear differential equation has an exact solution using the matrix exponential:

\] {y} \ trái (0 \ phải), \]

Tuy nhiên, trong trường hợp này, \ (\ mathbf {a} \ left (t \ right) \) và tích phân của nó không đi lại.\(\mathbf{A}\left(t\right)\) and its integral do not commute.

Phương trình vi phân này có thể được giải quyết bằng hàm

>>> vec_expint = np.vectorize(expint)
9. Nó yêu cầu đạo hàm, fprime, khoảng thời gian [t_start, t_end] và vectơ điều kiện ban đầu, y0, làm đối số đầu vào và trả về một đối tượng có trường y là một mảng có giá trị giải pháp liên tiếp làm cột. Do đó, các điều kiện ban đầu được đưa ra trong cột đầu ra đầu tiên.

>>> from numpy import sqrt, sin, cos, pi
>>> I = sqrt(2/pi)*(18.0/27*sqrt(2)*cos(4.5) - 4.0/27*sqrt(2)*sin(4.5) +
...                 sqrt(2*pi) * special.fresnel(3/sqrt(pi))[0])
>>> I
1.117817938088701
3

Như có thể thấy

>>> vec_expint = np.vectorize(expint)
9 tự động xác định các bước thời gian của nó nếu không được chỉ định khác. Để so sánh giải pháp của
>>> vec_expint = np.vectorize(expint)
9 với hàm thoáng mát, vectơ thời gian được tạo bởi
>>> vec_expint = np.vectorize(expint)
9 được truyền đến hàm thoáng.

>>> from numpy import sqrt, sin, cos, pi
>>> I = sqrt(2/pi)*(18.0/27*sqrt(2)*cos(4.5) - 4.0/27*sqrt(2)*sin(4.5) +
...                 sqrt(2*pi) * special.fresnel(3/sqrt(pi))[0])
>>> I
1.117817938088701
4

Giải pháp của

>>> vec_expint = np.vectorize(expint)
9 với các tham số tiêu chuẩn của nó cho thấy độ lệch lớn đối với hàm thoáng mát. Để giảm thiểu độ lệch này, dung sai tương đối và tuyệt đối có thể được sử dụng.

>>> from numpy import sqrt, sin, cos, pi
>>> I = sqrt(2/pi)*(18.0/27*sqrt(2)*cos(4.5) - 4.0/27*sqrt(2)*sin(4.5) +
...                 sqrt(2*pi) * special.fresnel(3/sqrt(pi))[0])
>>> I
1.117817938088701
5

Để chỉ định điểm thời gian xác định của người dùng cho giải pháp của

>>> vec_expint = np.vectorize(expint)
9,
>>> vec_expint = np.vectorize(expint)
9 cung cấp hai khả năng cũng có thể được sử dụng bổ sung. Bằng cách chuyển tùy chọn t_eval cho chức năng gọi
>>> vec_expint = np.vectorize(expint)
9 trả về các giải pháp của các điểm thời gian này của t_eval trong đầu ra của nó.

>>> from numpy import sqrt, sin, cos, pi
>>> I = sqrt(2/pi)*(18.0/27*sqrt(2)*cos(4.5) - 4.0/27*sqrt(2)*sin(4.5) +
...                 sqrt(2*pi) * special.fresnel(3/sqrt(pi))[0])
>>> I
1.117817938088701
6

Nếu ma trận chức năng Jacobian được biết đến, nó có thể được chuyển đến

>>> vec_expint = np.vectorize(expint)
9 để đạt được kết quả tốt hơn. Tuy nhiên, xin lưu ý rằng phương pháp tích hợp mặc định
>>> result = quad(lambda x: expint(3, x), 0, np.inf)
>>> print(result)
(0.33333333324560266, 2.8548934485373678e-09)
1 không hỗ trợ ma trận Jacobian và do đó phải chọn phương pháp tích hợp khác. Một trong những phương pháp tích hợp hỗ trợ ma trận Jacobian là phương pháp
>>> result = quad(lambda x: expint(3, x), 0, np.inf)
>>> print(result)
(0.33333333324560266, 2.8548934485373678e-09)
2 của ví dụ sau.

>>> from numpy import sqrt, sin, cos, pi
>>> I = sqrt(2/pi)*(18.0/27*sqrt(2)*cos(4.5) - 4.0/27*sqrt(2)*sin(4.5) +
...                 sqrt(2*pi) * special.fresnel(3/sqrt(pi))[0])
>>> I
1.117817938088701
7

Giải quyết một hệ thống với Ma trận Jacobian#

>>> result = quad(lambda x: expint(3, x), 0, np.inf)
>>> print(result)
(0.33333333324560266, 2.8548934485373678e-09)
3 có thể được thông báo rằng Jacobian bị băng bó. Đối với một hệ thống lớn các phương trình vi phân được biết là cứng, điều này có thể cải thiện hiệu suất đáng kể.

Ví dụ, chúng tôi sẽ giải các phương trình vi phân một phần màu xám 1-D bằng phương pháp của các dòng [mol]. Các phương trình scott màu xám cho các hàm \ (u (x, t) \) và \ (v (x, t) \) trên khoảng \ (x \ in [0, l] \) là[MOL]. The Gray-Scott equations for the functions \(u(x, t)\) and \(v(x, t)\) on the interval \(x \in [0, L]\) are

\ [\ Begin {split} \ start -u) \\ \ frac {\ partial v} {\ partial t} = d_v \ frac {\ partial^2 v} {\ partial x^2} + uv^2 - (f + k) {split} \ end {split} \]

trong đó \ (d_u \) và \ (d_v \) là các hệ số khuếch tán của các thành phần \ (u \) và \ (v \), tương ứng và \ (f \) và \ (k \) là hằng số. (Để biết thêm thông tin về hệ thống, xem http://groups.csail.mit.edu/mac/projects/amorphous/grayscott/)\(D_u\) and \(D_v\) are the diffusion coefficients of the components \(u\) and \(v\), respectively, and \(f\) and \(k\) are constants. (For more information about the system, see http://groups.csail.mit.edu/mac/projects/amorphous/GrayScott/)

Chúng tôi sẽ giả sử Neumann (tức là, không có thông lượng) Điều kiện biên:

\] Một phần u} {\ Partial x} (l, t) = 0, \ Quad \ frac {\ Partial V} {\ Partial X} (l, t) = 0 \]

Để áp dụng phương thức của các dòng, chúng tôi phân tách biến \ (x \) bằng cách xác định lưới cách đều nhau của các điểm \ (n \) \ (\ trái \ {x_0, x_1, \ ldot \} \), với \ (x_0 = 0 \) và \ (x_ {n-1} = l \). Chúng tôi xác định \ (u_j (t) \ Equiv u (x_k, t) \) và \ (v_j (t) \ Equiv V (x_k, t) \) và thay thế các dẫn xuất \ (x \) bằng sự khác biệt hữu hạn. Đó là,\(x\) variable by defining the uniformly spaced grid of \(N\) points \(\left\{x_0, x_1, \ldots, x_{N-1}\right\}\), with \(x_0 = 0\) and \(x_{N-1} = L\). We define \(u_j(t) \equiv u(x_k, t)\) and \(v_j(t) \equiv v(x_k, t)\), and replace the \(x\) derivatives with finite differences. That is,

\ [\ frac {\ partial^2 u} {\ partial x^2} (x_j, t) +1} (t)} {(\ delta x)^2} \]

Sau đó chúng tôi có một hệ thống vi phân thông thường \ (2n \):\(2N\) ordinary differential equations:

. u_ {j} + u_ {j + 1} \ right) -u_jv_j^2 + f (1 - u_j) \\ \ frac {dv_j} \ left (V_ {J -1} - 2 V_ {J} + V_ {J + 1} \ Right) + U_JV_J^2 - (f + k)\[\begin{split} \begin{split} \frac{du_j}{dt} = \frac{D_u}{(\Delta x)^2} \left(u_{j-1} - 2 u_{j} + u_{j+1}\right) -u_jv_j^2 + f(1 - u_j) \\ \frac{dv_j}{dt} = \frac{D_v}{(\Delta x)^2} \left(v_{j-1} - 2 v_{j} + v_{j+1}\right) + u_jv_j^2 - (f + k)v_j \end{split}\end{split}\]

Để thuận tiện, các đối số \ ((t) \) đã bị loại bỏ.\((t)\) arguments have been dropped.

Để thực thi các điều kiện biên, chúng tôi giới thiệu các điểm Ghost Ghost \ (x _ {-1} \) và \ (x_n \) và xác định \ (u _ {-1} (t) \ Equiv u_1 (t) \), \ (u_n (t) \ Equiv u_ {n-2} (t) \); \ (v _ {-1} (t) \) và \ (v_n (t) \) được xác định tương tự.\(x_{-1}\) and \(x_N\), and define \(u_{-1}(t) \equiv u_1(t)\), \(u_N(t) \equiv u_{N-2}(t)\); \(v_{-1}(t)\) and \(v_N(t)\) are defined analogously.

sau đó

. 0} A v_ {0} \ right) + u_0V_0^2 - (f + k) v_0 \ end {split} \ end {split} \]\[\begin{split} \begin{split} \frac{du_0}{dt} = \frac{D_u}{(\Delta x)^2} \left(2u_{1} - 2 u_{0}\right) -u_0v_0^2 + f(1 - u_0) \\ \frac{dv_0}{dt} = \frac{D_v}{(\Delta x)^2} \left(2v_{1} - 2 v_{0}\right) + u_0v_0^2 - (f + k)v_0 \end{split}\end{split}\]

. -2}-2 u_ {n-1} \ right) -u_ {n-1} v_ {n-1}^2 + f (1-u_ {n-1}) 1. N-1}^2-(f + k) v_ {n-1} \ end {split} \ end {split} \]\[\begin{split} \begin{split} \frac{du_{N-1}}{dt} = \frac{D_u}{(\Delta x)^2} \left(2u_{N-2} - 2 u_{N-1}\right) -u_{N-1}v_{N-1}^2 + f(1 - u_{N-1}) \\ \frac{dv_{N-1}}{dt} = \frac{D_v}{(\Delta x)^2} \left(2v_{N-2} - 2 v_{N-1}\right) + u_{N-1}v_{N-1}^2 - (f + k)v_{N-1} \end{split}\end{split}\]

Hệ thống hoàn chỉnh của chúng tôi về các phương trình vi phân thông thường \ (2n \) của chúng tôi là (1) cho \ (k = 1, 2, \ ldots, n-2 \), cùng với (2) và (3).\(2N\) ordinary differential equations is (1) for \(k = 1, 2, \ldots, N-2\), along with (2) and (3).

Bây giờ chúng ta có thể bắt đầu triển khai hệ thống này trong mã. Chúng ta phải kết hợp \ (\ {u_k \} \) và \ (\ {v_k \} \) thành một vectơ duy nhất có độ dài \ (2n \). Hai lựa chọn rõ ràng là \ (\ {u_0, u_1, \ ldots, u_ {n-1}, v_0, v_1, \ ldots, v_ {n-1} \} \) và \ (\ {u_0, V_0, U_1 , v_1, \ ldots, u_ {n-1}, v_ {n-1} \} \). Về mặt toán học, nó không quan trọng, nhưng sự lựa chọn ảnh hưởng đến mức độ hiệu quả của

>>> result = quad(lambda x: expint(3, x), 0, np.inf)
>>> print(result)
(0.33333333324560266, 2.8548934485373678e-09)
3 có thể giải quyết hệ thống. Lý do là cách thức thứ tự ảnh hưởng đến mô hình của các yếu tố khác của ma trận Jacobian.\(\{u_k\}\) and \(\{v_k\}\) into a single vector of length \(2N\). The two obvious choices are \(\{u_0, u_1, \ldots, u_{N-1}, v_0, v_1, \ldots, v_{N-1}\}\) and \(\{u_0, v_0, u_1, v_1, \ldots, u_{N-1}, v_{N-1}\}\). Mathematically, it does not matter, but the choice affects how efficiently
>>> result = quad(lambda x: expint(3, x), 0, np.inf)
>>> print(result)
(0.33333333324560266, 2.8548934485373678e-09)
3 can solve the system. The reason is in how the order affects the pattern of the nonzero elements of the Jacobian matrix.

Khi các biến được đặt hàng là \ (\ {u_0, u_1, \ ldots, u_ {n-1}, v_0, v_1, \ ldots, v_ {n-1} \} \) Ma trận là\(\{u_0, u_1, \ldots, u_{N-1}, v_0, v_1, \ldots, v_{N-1}\}\), the pattern of nonzero elements of the Jacobian matrix is

\ [\ BẮT ĐẦU {split} \ start & 0 & 0 & 0 & * & 0 & 0 & 0 & 0 & 0 \\ 0 & * & * & * & 0 & 0 & 0 & 0 & 0 & * & 0 & 0 & 0 & 0 \\ 0 & 0 & * & * & * & 0 & 0 & 0 & 0 & 0 & * & 0 & 0 & 0 \\ 0 & 0 & 0 & * & * & * & 0 & 0 & 0 & 0 & 0 & 0 & * & 0 & 0 \\ 0 & 0 & 0 & 0 & * & * & * & 0 & 0 & 0 & 0 & 0 & * & 0 \\ 0 & 0 & 0 & 0 & 0 & * & * & * & 0 & 0 & 0 & 0 & 0 & 0 & * \\ * & 0 & 0 & 0 & 0 & 0 & 0 & * & * & 0 & 0 & 0 & 0 & 0 \\ 0 & * & 0 & 0 & 0 & 0 & 0 & 0 & 0 & * & * & * & 0 & 0 & 0 & 0 \\ 0 & 0 & * & 0 & 0 & 0 & 0 & 0 & * & * & * & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & * & 0 & 0 & 0 & 0 & 0 & * & * & * & 0 & 0 \\ 0 & 0 & 0 & 0 & * & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & & * & * & * & 0 \\ 0 & 0 & 0 & 0 & 0 & * & 0 & 0 & 0 & 0 & 0 & * & * & * \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & & * & 0 & 0 & 0 & 0 &) & * & * \\ \ end {smallmatrix} \ end {split} \]

Mẫu Jacobian với các biến xen kẽ là \ (\ {u_0, v_0, u_1, v_1, \ ldots, u_ {n-1}, v_ {n-1} \} \)\(\{u_0, v_0, u_1, v_1, \ldots, u_{N-1}, v_{N-1}\}\) is

\ [\ BẮT ĐẦU {split} \ start & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ * & 0 & * & * & * & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & * & * & * & 0 & * & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & * & 0 & * & * & * & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & * & * & * & 0 & * & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & * & 0 & * & * & * & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & * & * & * & 0 & * & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & * & 0 & * & * & * & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & * & * & * & 0 & * & 0 & 0 & 0 & 0 & 0 & 0 & \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & * & 0 & * & * & * & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & * * & * & * & 0 & * \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & * & 0 & * & * \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & & 0 & 0 & 0 & 0 & 0 & * & * & * \\ \ end {smallmatrix} \ end {split} \]

Trong cả hai trường hợp, chỉ có năm đường chéo không cần thiết, nhưng khi các biến được xen kẽ, băng thông nhỏ hơn nhiều. Đó là, đường chéo chính và hai đường chéo ngay bên trên và hai đường ngay bên dưới đường chéo chính là các đường chéo khác nhau. Điều này rất quan trọng, bởi vì các đầu vào

>>> result = quad(lambda x: expint(3, x), 0, np.inf)
>>> print(result)
(0.33333333324560266, 2.8548934485373678e-09)
5 và
>>> result = quad(lambda x: expint(3, x), 0, np.inf)
>>> print(result)
(0.33333333324560266, 2.8548934485373678e-09)
6 của
>>> result = quad(lambda x: expint(3, x), 0, np.inf)
>>> print(result)
(0.33333333324560266, 2.8548934485373678e-09)
3 là băng thông trên và dưới của ma trận Jacobian. Khi các biến được xen kẽ,
>>> result = quad(lambda x: expint(3, x), 0, np.inf)
>>> print(result)
(0.33333333324560266, 2.8548934485373678e-09)
5 và
>>> result = quad(lambda x: expint(3, x), 0, np.inf)
>>> print(result)
(0.33333333324560266, 2.8548934485373678e-09)
6 là 2. Khi các biến được xếp chồng lên với \ (\ {v_k \} \) theo sau \ (\ {u_k \} \), băng thông trên và dưới là \ (n \).\(\{v_k\}\) following \(\{u_k\}\), the upper and lower bandwidths are \(N\).

Với quyết định đó, chúng ta có thể viết hàm thực hiện hệ thống vi phân.

Đầu tiên, chúng tôi xác định các chức năng cho các điều khoản nguồn và phản ứng của hệ thống:

>>> from numpy import sqrt, sin, cos, pi
>>> I = sqrt(2/pi)*(18.0/27*sqrt(2)*cos(4.5) - 4.0/27*sqrt(2)*sin(4.5) +
...                 sqrt(2*pi) * special.fresnel(3/sqrt(pi))[0])
>>> I
1.117817938088701
8

Tiếp theo, chúng tôi xác định hàm tính toán phía bên phải của hệ phương trình vi phân:

>>> from numpy import sqrt, sin, cos, pi
>>> I = sqrt(2/pi)*(18.0/27*sqrt(2)*cos(4.5) - 4.0/27*sqrt(2)*sin(4.5) +
...                 sqrt(2*pi) * special.fresnel(3/sqrt(pi))[0])
>>> I
1.117817938088701
9

Chúng tôi đã giành chiến thắng thực hiện một chức năng để tính toán Jacobian, nhưng chúng tôi sẽ nói với

>>> result = quad(lambda x: expint(3, x), 0, np.inf)
>>> print(result)
(0.33333333324560266, 2.8548934485373678e-09)
3 rằng ma trận Jacobian được băng bó. Điều này cho phép bộ giải cơ bản (LSODA) tránh các giá trị điện toán mà nó biết bằng không. Đối với một hệ thống lớn, điều này cải thiện hiệu suất đáng kể, như đã được chứng minh trong phiên ipython sau đây.

Đầu tiên, chúng tôi xác định các đầu vào cần thiết:

>>> print(abs(result[0]-I))
1.03761443881e-11
0

Thời gian tính toán mà không tận dụng cấu trúc dải của ma trận Jacobian:

>>> print(abs(result[0]-I))
1.03761443881e-11
1

Bây giờ đã đặt

>>> import scipy.integrate as integrate
>>> import scipy.special as special
>>> result = integrate.quad(lambda x: special.jv(2.5,x), 0, 4.5)
>>> result
(1.1178179380783249, 7.8663172481899801e-09)
01 và
>>> import scipy.integrate as integrate
>>> import scipy.special as special
>>> result = integrate.quad(lambda x: special.jv(2.5,x), 0, 4.5)
>>> result
(1.1178179380783249, 7.8663172481899801e-09)
02, vì vậy
>>> result = quad(lambda x: expint(3, x), 0, np.inf)
>>> print(result)
(0.33333333324560266, 2.8548934485373678e-09)
3 đã biết rằng ma trận Jacobian được băng bó:

>>> print(abs(result[0]-I))
1.03761443881e-11
2

Đó là khá nhanh hơn một chút!

Hãy để đảm bảo rằng họ đã tính toán cùng một kết quả:

>>> print(abs(result[0]-I))
1.03761443881e-11
3

References#

WPR

https://en.wikipedia.org/wiki/Romberg’s_method

Mol

https://en.wikipedia.org/wiki/Method_of_lines

Làm thế nào để bạn tìm thấy tích phân của một hàm trong Python?

Tích hợp mô -đun.Nó lấy các đối số đầu vào hàm f (x) để được tích hợp (tích phân trên mạng) và phần dưới và trên giới hạn a và b.Nó trả về hai giá trị (trong một tuple): giá trị đầu tiên là kết quả được tính toán và giá trị thứ hai là ước tính sai số số của kết quả đó.. It takes as input arguments the function f(x) to be integrated (the “integrand”), and the lower and upper limits a and b. It returns two values (in a tuple): the first one is the computed results and the second one is an estimation of the numerical error of that result.

Có thể tìm thấy sự tích hợp và khác biệt trong Python không?

Bây giờ bạn có thể tích hợp và phân biệt bằng Python.Các chức năng này có thể được sử dụng để kiểm tra lại công việc của bạn hoặc như một giải pháp nhanh chóng (chắc chắn kiểm tra lại toán học!).you can integrate and differentiate using Python. These functions can be used to double check your work or as a quick solution (definitely double check the math though!).

Làm thế nào để bạn tìm thấy chất chống đối trong Python?

Để tính toán tích phân không xác định của một hàm (chống vi khuẩn) trong Python, chúng tôi sử dụng tích hợp () của sympy.Đối số đầu tiên f là hàm tích phân.Đối số thứ hai x là biến tích hợp (DX).Biến phải được định nghĩa là một biểu tượng.use the integrate() of sympy. The first argument f is the integrand function. The second argument x is the integration variable (dx). The variable must be defined as a symbol.