Tích hợp vùng dưới đường cong python

% Chuyển tiếp Động học của Bộ điều khiển Cánh tay Robot 2-D xóa tất cả đóng tất cả clc l1= 2; . e. , không gian cho các chuyển động t2=linspace(0,90,20); . chiều dài(t1) T1=t1(i); . chiều dài(t2) T2= t2(j);

Các điểm mẫu tương ứng với các giá trị y. Nếu x là Không, các điểm mẫu được coi là cách đều nhau dx. Mặc định là Không có

dx vô hướng, tùy chọn

Khoảng cách giữa các điểm mẫu khi x là Không có. Mặc định là 1

trục int, tùy chọn

Trục dọc theo đó để tích hợp

Trả về . trapz float hoặc ndarray

Tích phân xác định của y = mảng n chiều được xấp xỉ dọc theo một trục đơn theo quy tắc hình thang. Nếu y là mảng 1 chiều thì kết quả là float. Nếu n lớn hơn 1 thì kết quả là mảng n-1 chiều

Xem thêm

,

ghi chú

Hình ảnh minh họa quy tắc hình thang – vị trí trục y của các điểm sẽ được lấy từ mảng y, theo mặc định, khoảng cách trục x giữa các điểm sẽ là 1. 0, ngoài ra, chúng có thể được cung cấp với mảng x hoặc với vô hướng dx. Giá trị trả về sẽ bằng diện tích kết hợp dưới các đường màu đỏ

Người giới thiệu

[ 1 ]

trang Wikipedia. https. // vi. wikipedia. org/wiki/Trapezoidal_rule

[]

Hình ảnh minh họa. https. // vi. wikipedia. org/wiki/Tệp. Composite_trapezoidal_rule_illustration. png

ví dụ

>>> np.trapz([1,2,3])
4.0
>>> np.trapz([1,2,3], x=[4,6,8])
8.0
>>> np.trapz([1,2,3], dx=2)
8.0

Sử dụng x giảm tương ứng với tích phân ngược lại

>>> np.trapz([1,2,3], x=[8,6,4])
-8.0

Tổng quát hơn x được sử dụng để lấy tích phân dọc theo đường cong tham số. Điều này tìm thấy diện tích của một vòng tròn, lưu ý rằng chúng tôi lặp lại mẫu đóng đường cong

Diện tích dưới đường cong biểu thị tổng của một hàm trong một khoảng và được quan tâm trong nhiều ứng dụng. Thông thường, quy tắc Trapezium được sử dụng để ước tính diện tích dưới đường cong. Những tính toán như vậy có thể được tự động hóa và phần đóng góp này mô tả một phần mềm Python được thiết kế để tính diện tích dưới đường cong của y = x2. Trước tiên, hàm đọc trong giới hạn tích phân dưới và trên cũng như số lượng khoảng thời gian để tích hợp. Sau đó, nó tính toán kích thước bước tích hợp để giúp thực hiện quy tắc Trapezium để có được diện tích dưới đường cong. Tính mô đun trong mã phần mềm đảm bảo rằng phần mềm Python có thể dễ dàng điều chỉnh để tính diện tích dưới đường cong cho các hàm toán học khác

Kinh phí

Không có tài trợ đã được sử dụng trong công việc này

Gói con cung cấp một số kỹ thuật tích hợp bao gồm một bộ tích phân 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 ()

Hàm được cung cấp để tích phân hàm một biến giữa hai điểm. Điểm có thể là \(\pm\infty\) ( \(\pm\)

>>> print(abs(result[0]-I))
1.03761443881e-11
8) to indicate infinite limits. For example, suppose you wish to integrate a bessel function
>>> print(abs(result[0]-I))
1.03761443881e-11
9 along the interval \([0, 4. 5]. \)

\[I=\int_{0}^{4. 5}J_{2. 5}\trái(x\phải)\, dx. \]

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

>>> 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à một đối tượng Python “có thể gọi được” (i. e. , một hàm, phương thức hoặc thể hiện của lớp). Lưu ý việc sử dụng hàm 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 tích hợp. Giá trị trả về là một bộ, 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ữ giới hạn trên của 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{2}\cos\left(4. 5\right)-\frac{4}{27}\sqrt{2}\sin\left(4. 5\right)+\sqrt{2\pi}\textrm{Si}\left(\frac{3}{\sqrt{\pi}}\right)\right),\]

ở đâ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\times10^{-11}\) của kết quả chính xác — thấp hơn rất nhiều so với giới hạn lỗi được báo cáo.

Nếu chức năng 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

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

Tích phân này có thể được đánh giá bằng cách sử dụng đoạn mã sau

________số 8

Số lượng đầu vào vô hạn cũng được cho phép bằng cách sử dụng \(\pm\)

>>> print(abs(result[0]-I))
1.03761443881e-11
8 làm một trong các đối số. Ví dụ, giả sử rằng một giá trị số cho tích phân mũ.

\[E_{n}\left(x\right)=\int_{1}^{\infty}\frac{e^{-xt}}{t^{n}}\, dt. \]

là mong muốn (và thực tế là tích phân này có thể được tính 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)
3 đã bị lãng quên). Chức năng của chức năng có thể được nhân rộng bằng cách xác định chức năng 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)
5 dựa trên thói quen

>>> np.trapz([1,2,3], x=[8,6,4])
-8.0
2

>>> np.trapz([1,2,3], x=[8,6,4])
-8.0
3

>>> np.trapz([1,2,3], x=[8,6,4])
-8.0
4

>>> np.trapz([1,2,3], x=[8,6,4])
-8.0
5

Hàm được tích hợp thậm chí có thể sử dụng đối số quad (mặc dù giới hạn lỗi có thể đánh giá thấp lỗi do lỗi số có thể xảy ra trong tích phân từ việc sử dụng ). Tích phân trong trường hợp này là

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

>>> np.trapz([1,2,3], x=[8,6,4])
-8.0
6

>>> 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ác lệnh gọi lặp lại tới

Tích hợp bội chung ( , , )

Cơ chế tích hợp kép và ba đã được gói gọn trong các chức năng và. Các hàm này lấy hàm để tích phân 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 xác định là các hàm

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

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

Như ví dụ cho các giới hạn không đổi, 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 ước tính 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 cố định 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-fold, scipy cung cấp chức năng. Các giới hạn tích hợp là một đối tượng có thể lặp lại. 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 đổi. Thứ tự của tích phân (và do đó là các giới hạn) là từ tích phân trong cùng đến tích phân ngoài cùng

Tích phân trên

\[I_{n}=\int_{0}^{\infty}\int_{1}^{\infty}\frac{e^{-xt}}{t^{n}}\, dt\, dx

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

>>> 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ủa các đối số cho f phải khớp với thứ tự của các giới hạn tích phân; . e. , tích phân bên trong của \(t\) nằm trên khoảng \([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 cố định có thể được xử lý theo cách tương tự;

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

có thể được đánh giá bằng

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

đó là kết quả tương tự như trước đây

cầu phương Gaussian

Một vài chức năng cũng được cung cấp để thực hiện cầu phương Gaussian đơn giản trong một khoảng thời gian cố định. Đầu tiên là , thực hiện cầu phương Gaussian có thứ tự cố định. Hàm thứ hai là , thực hiện phép cầu phương Gaussian của nhiều bậc cho đến khi chênh lệch trong ước tính tích phân nằm dưới một số dung sai do người dùng cung cấp. Cả hai hàm này đều sử dụng mô-đun

>>> np.trapz([1,2,3], x=[8,6,4])
-8.0
27, mô-đun này có thể tính toán nghiệm và trọng số cầu phương của nhiều loại đa thức trực giao (bản thân các đa thức có sẵn dưới dạng các hàm đặc biệt trả về các thể hiện của lớp đa thức — e. g. , )

Tích hợp Romberg

Phương pháp của Romberg là một phương pháp khác để đánh giá bằng số một tích phân. Xem chức năng trợ giúp để biết thêm chi tiết

Tích hợp sử dụng mẫu

Nếu các mẫu cách đều nhau và số lượng mẫu có sẵn là \(2^{k}+1\) đối với một số . 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 đến lũy thừa của hai và sau đó thực hiện phép ngoại suy Richardson trên các ước tính này để tính gần đúng tích phân với độ chính xác cao hơn. \(k\), then Romberg 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 có khoảng cách tùy ý, hai chức năng và có sẵn. Họ đang sử dụng các công thức Newton-Coates bậc 1 và bậc 2 tương ứng để thực hiện tích phân. Quy tắc hình thang xấp xỉ hàm dưới dạng 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ề dưới dạng parabol

Đối với một số lẻ các mẫu cách đều nhau, quy tắc Simpson là chính xác nếu hàm là đa thức bậc 3 trở xuống. Nếu các mẫu không cách đều nhau thì kết quả chỉ chính xác nếu hàm là đa thức bậc 2 trở xuống

>>> 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 chức năng 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\]

vì bậc của đa thức ở 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

Người dùng muốn giảm thời gian tích hợp có thể chuyển một con trỏ hàm C đến , hoặc và nó sẽ được tích hợp và trả về kết quả bằng Python. Sự gia tăng hiệu suất ở đây phát sinh từ hai yếu tố. Cải tiến chính là đánh giá chức năng nhanh hơn, được cung cấp bằng cách biên dịch chính chức năng đó. Ngoài ra, chúng tôi có một sự tăng tốc được cung cấp bằng cách loại bỏ các lệnh gọi hàm giữa C và Python trong. Phương pháp này có thể cải thiện tốc độ ~2 lần đối với các hàm tầm thường như sin nhưng có thể tạo ra các cải tiến đáng chú ý hơn nhiều (10x+) đối với các hàm phức tạp hơn. Sau đó, tính năng này hướng đến người dùng có tích hợp số chuyên sâu 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 một vài bước đơn giản

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

>>> np.trapz([1,2,3], x=[8,6,4])
-8.0
40, trong đó
>>> np.trapz([1,2,3], x=[8,6,4])
-8.0
41 là một mảng chứa điểm mà hàm f được ước tính tại đó và
>>> np.trapz([1,2,3], x=[8,6,4])
-8.0
42 là dữ liệu bổ sung tùy ý mà 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ờ hãy biên dịch tệp này thành thư viện dùng chung/động (tìm kiếm nhanh sẽ giúp ích cho việc 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à

>>> np.trapz([1,2,3], x=[8,6,4])
-8.0
43, nhưng nó có thể có phần mở rộng tệp khác. Một thư viện hiện đã được tạo có thể được tải vào Python với

3. ) Tải thư viện dùng chung vào Python bằng cách sử dụng và đặt

>>> np.trapz([1,2,3], x=[8,6,4])
-8.0
46 và
>>> np.trapz([1,2,3], x=[8,6,4])
-8.0
47 - điều này cho phép SciPy diễn giải hàm một cách chính xác

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

>>> np.trapz([1,2,3], x=[8,6,4])
-8.0
48 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 dưới dạng một mảng nhân đôi chứ không phải là một đối số riêng biệt

4. ) Bây giờ hãy tích hợp chức năng thư viện như bình thường, ở đây 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
2

Bộ dữ liệu Python được trả về như mong đợi trong một khoảng thời gian ngắn hơn. 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 ()

Tích hợp một tập hợp các phương trình vi phân thông thường (ODE) với các điều kiện ban đầu là một ví dụ hữu ích khác. Hàm này có sẵn trong SciPy để tích hợp phương trình vi phân vectơ bậc nhất

\[\frac{d\mathbf{y}}{dt}=\mathbf{f}\left(\mathbf{y},t\right),\]

với các điều kiện ban đầu \(\mathbf{y}\left(0\right)=y_{0}\) , trong đó < . \) \(\mathbf{y}\) is a length \(N\) vector and \(\mathbf{f}\) is a mapping from \(\mathcal{R}^{N}\) to \(\mathcal{R}^{N}.\) Phương trình vi phân thường cấp cao hơn luôn có thể được rút gọn thành phương trình vi phân loại này bằng cách đưa đạo hàm trung gian vào \(\mathbf{y . vector.

Ví dụ: giả sử muốn tìm nghiệm của phương trình vi phân cấp hai sau đây

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

với điều kiện ban đầu \(w\left(0\right)=\frac{1}{\sqrt[3]{3^{2}}\Gamma\left . \frac{dw}{dz}\right. _{z=0}=-\frac{1}{\sqrt[3]{3}\Gamma\left(\frac{1}{3}\right)}. \) and \(\left.\frac{dw}{dz}\right|_{z=0}=-\frac{1}{\sqrt[3]{3}\Gamma\left(\frac{1}{3}\right)}.\) Được biết, nghiệm của phương trình vi phân với các điều kiện biên này là hàm Airy

\[w=\textrm{Ai}\left(z\right),\]

cung cấp một phương tiện để kiểm tra bộ tích hợp bằng cách sử dụng

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

\[\begin{split}\frac{d\mathbf{y}}{dt}=\left[\begin{array}{c} ty_{1}\\ y_{0}\end{array}\right] . \end{split}\]

Nói cách khác,

\[\mathbf{f}\left(\mathbf{y},t\right)=\mathbf{A}\left(t\right)\mathbf{y}. \]

Xin lưu ý rằng nếu \(\mathbf{A}\left(t\right)\) đi làm bằng \(\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:

\[\mathbf{y}\left(t\right)=\exp\left(\int_{0}^{t}\mathbf{A}\left(\tau\right)d\tau\right)\mathbf

Tuy nhiên, trong trường hợp này, \(\mathbf{A}\left(t\right)\) và tích phân của nó thì không .

Phương trình vi phân này có thể được giải bằng hàm. 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 với các giá trị nghiệm liên tiếp dưới dạng 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, nó tự động xác định các bước thời gian nếu không được chỉ định khác. Để so sánh nghiệm của hàm thoáng, vectơ thời gian được tạo bởi 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 với các tham số tiêu chuẩn của nó cho thấy độ lệch lớn đối với chức năng thoáng khí. Để giảm thiểu sai lệch này, có thể sử dụng dung sai tương đối và tuyệt đối

>>> 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 các mốc thời gian do người dùng xác định cho giải pháp của , 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 lệnh gọi hàm trả về nghiệm 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 biết ma trận jacobian của hàm, nó có thể được chuyển đến để đạt được kết quả tốt hơn. Tuy nhiên, hãy lưu ý rằng phương thức tích hợp mặc định không hỗ trợ ma trận jacobian và do đó phải chọn một phương thức tích hợp khác. Ví dụ, một trong những phương pháp tích hợp hỗ trợ ma trận jacobian là phương pháp 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 một hệ thống với ma trận Jacobian dải

có thể nói rằng Jacobian là dải. Đối với một hệ phương trình vi phân lớ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 ta sẽ giải phương trình đạo hàm riêng Gray-Scott 1-D bằng phương pháp đường thẳng. Các phương trình Gray-Scott cho các hàm \(u(x, t)\)\(v( on the interval \(x \in [0, L]\) are

\[\begin{split}\begin{split} \frac{\partial u}{\partial t} = D_u \frac{\partial^2 u}{\partial x^2} - uv^2 + f(1

ở đâu \(D_u\)\(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 ta sẽ giả sử Neumann (i. e. , “không có từ thông”) điều kiện biên

\[\frac{\partial u}{\partial x}(0,t) = 0, \quad \frac{\partial v}{\partial x}(0,t) = 0, \quad \frac{\

Để áp dụng phương pháp đường kẻ, chúng ta phân biệt biến \(x\) bằng cách xác định lưới cách đều nhau của \(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)\)\(v_j( . Tức là,, and replace the \(x\) derivatives with finite differences. That is,

\[\frac{\partial^2 u}{\partial x^2}(x_j, t) \rightarrow \frac{u_{j-1}(t) - 2 u_{j}(t) + u_{j

Sau đó, chúng ta có một hệ gồm \(2N\) phương trình vi phân thường.

(1) \[\begin{split} \begin{split} \frac{du_j}{dt} = \frac{D_u}{(\Delta x)^

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

Để thực thi các điều kiện biên, chúng tôi giới thiệu các điểm "ma" \(x_{-1}\)\(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 đó

(2) \[\begin{split} \begin{split} \frac{du_0}{dt} = \frac{D_u}{(\Delta x)^

(3) \[\begin{split} \begin{split} \frac{du_{N-1}}{dt} = \frac{D_u}{(

Hệ thống đầy đủ của chúng tôi về \(2N\) phương trình vi phân thông thường dành cho \(k = . , along with and .

Bây giờ chúng ta có thể bắt đầu triển khai hệ thống này bằng mã. Chúng ta phải kết hợp \(\{u_k\}\)\(\{v_k\}\)< . Hai lựa chọn rõ ràng là 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}\}\)< . Về mặt toán học, điều đó không thành vấn đề, nhưng sự lựa chọn ảnh hưởng đến mức độ hiệu quả của việc giải quyết hệ thống. Lý do là cách thứ tự ảnh hưởng đến mẫu của các phần tử khác không của ma trận Jacobian. 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 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 sắp xếp theo thứ tự \(\{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

\[\begin{split}\begin{smallmatrix} * & * & 0 & 0 & 0 & 0 & 0 & * & 0 & 0 & 0 & 0 & 0 & 0 \\ * & * & * & 0 & 0

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}\ is

\[\begin{split}\begin{smallmatrix} * & * & * & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ * & * & 0 & * & 0

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 sẽ nhỏ hơn nhiều. Nghĩa là, đường chéo chính và hai đường chéo ngay phía trên và hai đường chéo ngay phía dưới đường chéo chính là các đường chéo khác không. Điều này rất quan trọng, bởi vì các đầu vào

>>> np.trapz([1,2,3], x=[8,6,4])
-8.0
66 và
>>> np.trapz([1,2,3], x=[8,6,4])
-8.0
67 của là băng thông trên và dưới của ma trận Jacobian. Khi các biến được xen kẽ,
>>> np.trapz([1,2,3], x=[8,6,4])
-8.0
66 và
>>> np.trapz([1,2,3], x=[8,6,4])
-8.0
67 là 2. Khi các biến được xếp chồng lên nhau với \(\{v_k\}\) theo sau \(\{u_k\} . , the upper and lower bandwidths are \(N\).

Với quyết định được đưa ra, chúng ta có thể viết hàm thực hiện hệ phương trình vi phân

Đầu tiên, chúng tôi xác định các chức năng cho các thuật ngữ 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 ta xác định hàm tính vế 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 sẽ không triển khai một hàm để tính toán Jacobian, nhưng chúng tôi sẽ nói rằng ma trận Jacobian được phân dải. Điều này cho phép bộ giải cơ bản (LSODA) tránh các giá trị tính toán mà nó biết là 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 minh họa trong phiên ipython sau