Giới thiệu về Toán số
Đây là "Xin chào, Thế giới!" của PDEs (Phương trình vi phân từng phần). Phương trình Laplace hoặc Diffusion xuất hiện thường xuyên trong Vật lý, ví dụ Phương trình nhiệt, Biến dạng, Động lực học, v.v ... Vì cuộc sống thực là 3D nhưng chúng tôi muốn nói "Xin chào, Thế giới!" và không hát "99 chai bia, ..." nhiệm vụ này được đưa ra trong 1D. Bạn có thể giải thích điều này như một chiếc áo choàng cao su được buộc vào một bức tường ở cả hai đầu với một lực tác dụng lên nó.
Trên một [0,1]
miền, tìm một hàm u
cho hàm nguồn đã cho f
và các giá trị biên u_L
và u_R
như vậy:
-u'' = f
u(0) = u_L
u(1) = u_R
u''
biểu thị đạo hàm thứ hai của u
Điều này có thể được giải quyết hoàn toàn trên lý thuyết nhưng nhiệm vụ của bạn là giải quyết nó bằng số trên một miền x rời rạc cho N
các điểm:
- x =
{i/(N-1) | i=0..N-1}
hoặc 1 dựa trên:{(i-1)/(N-1) | i=1..N}
h = 1/(N-1)
là khoảng cách
Đầu vào
f
như hàm hoặc biểu thức hoặc chuỗiu_L
,u_R
như các giá trị dấu phẩy độngN
là số nguyên> = 2
Đầu ra
- Mảng, Danh sách, một số loại chuỗi tách biệt
u
như vậyu_i == u(x_i)
Ví dụ
ví dụ 1
Input: f = -2
, u_L = u_R = 0
, N = 10
(không dùng f=-2
sai, nó không phải là một giá trị nhưng một hàm liên tục mà lợi nhuận -2
cho tất cả x
Nó giống như một trọng lực liên tục trên dây của chúng tôi..)
Đầu ra: [-0.0, -0.09876543209876543, -0.1728395061728395, -0.22222222222222224, -0.24691358024691357, -0.24691358024691357, -0.22222222222222224, -0.1728395061728395, -0.09876543209876547, -0.0]
Có một giải pháp chính xác dễ dàng: u = -x*(1-x)
Ví dụ 2
Input: f = 10*x
, u_L = 0
u_R = 1
, N = 15
(Ở đây có rất nhiều hướng gió ở phía bên phải)
Đầu ra: [ 0., 0.1898688, 0.37609329, 0.55502915, 0.72303207, 0.87645773, 1.01166181, 1.125, 1.21282799, 1.27150146, 1.29737609, 1.28680758, 1.2361516, 1.14176385, 1.]
Giải pháp chính xác cho trạng thái này: u = 1/3*(8*x-5*x^3)
Ví dụ 3
Input: f = sin(2*pi*x)
, u_L = u_R = 1
, N = 20
(người đã phá vỡ nghiêm trọng hoặc có một loại cập nhật mới và hướng gió)
Đầu ra: [ 1., 1.0083001, 1.01570075, 1.02139999, 1.0247802, 1.0254751, 1.02340937, 1.01880687, 1.01216636, 1.00420743, 0.99579257, 0.98783364, 0.98119313, 0.97659063, 0.9745249, 0.9752198, 0.97860001, 0.98429925, 0.9916999, 1.]
Đây là giải pháp chính xác u = (sin(2*π*x))/(4*π^2)+1
Ví dụ 4
Input: f = exp(x^2)
, u_L = u_R = 0
,N=30
Đầu ra:
[ 0. 0.02021032 0.03923016 0.05705528 0.07367854 0.0890899
0.10327633 0.11622169 0.12790665 0.13830853 0.14740113 0.15515453
0.16153488 0.1665041 0.17001962 0.172034 0.17249459 0.17134303
0.16851482 0.1639387 0.15753606 0.1492202 0.13889553 0.12645668
0.11178744 0.09475961 0.07523169 0.05304738 0.02803389 0. ]
Lưu ý sự không đối xứng nhẹ
FDM
Một phương pháp khả thi để giải quyết điều này là Phương pháp khác biệt hữu hạn :
- viết lại
-u_i'' = f_i
như (-u_{i-1} + 2u_i - u{i+1})/h² = f_i
bằng-u_{i-1} + 2u_i - u{i+1} = h²f_i
- Thiết lập các phương trình:
- Bằng với phương trình vectơ ma trận:
- Giải phương trình này và xuất ra
u_i
Một triển khai này để trình diễn trong Python:
import matplotlib.pyplot as plt
import numpy as np
def laplace(f, uL, uR, N):
h = 1./(N-1)
x = [i*h for i in range(N)]
A = np.zeros((N,N))
b = np.zeros((N,))
A[0,0] = 1
b[0] = uL
for i in range(1,N-1):
A[i,i-1] = -1
A[i,i] = 2
A[i,i+1] = -1
b[i] = h**2*f(x[i])
A[N-1,N-1] = 1
b[N-1] = uR
u = np.linalg.solve(A,b)
plt.plot(x,u,'*-')
plt.show()
return u
print laplace(lambda x:-2, 0, 0, 10)
print laplace(lambda x:10*x, 0, 1, 15)
print laplace(lambda x:np.sin(2*np.pi*x), 1, 1, 20)
Thực hiện thay thế mà không cần Đại số ma trận (sử dụng phương pháp Jacobi )
def laplace(f, uL, uR, N):
h=1./(N-1)
b=[f(i*h)*h*h for i in range(N)]
b[0],b[-1]=uL,uR
u = [0]*N
def residual():
return np.sqrt(sum(r*r for r in[b[i] + u[i-1] - 2*u[i] + u[i+1] for i in range(1,N-1)]))
def jacobi():
return [uL] + [0.5*(b[i] + u[i-1] + u[i+1]) for i in range(1,N-1)] + [uR]
while residual() > 1e-6:
u = jacobi()
return u
Tuy nhiên, bạn có thể sử dụng bất kỳ phương pháp nào khác để giải phương trình Laplace. Nếu bạn sử dụng phương pháp lặp, bạn nên lặp lại cho đến khi dư |b-Au|<1e-6
, với b
vectơ bên phảiu_L,f_1h²,f_2h²,...
Ghi chú
Tùy thuộc vào phương pháp giải pháp của bạn, bạn có thể không giải quyết chính xác các ví dụ cho các giải pháp đã cho. Ít nhất là cho N->infinity
lỗi nên gần bằng không.
Các lỗ hổng tiêu chuẩn không được phép , tích hợp sẵn cho các PDE được cho phép.
Tặng kem
Phần thưởng -30% khi hiển thị giải pháp, theo đồ họa hoặc nghệ thuật ASCII.
Chiến thắng
Đây là codegolf, vì vậy mã ngắn nhất trong byte thắng!
log(log(x))
hoặc sqrt(1-x^4)
có một tích phân, tuy nhiên không thể biểu thị trong các chức năng cơ bản.
u(x) = 1/2 (-sqrt(π) x erfi(x)+sqrt(π) erfi(1) x+e^(x^2)-e x+x-1)
không thể tính toán chính xác.
f(x) = exp(x^2)
.