Pengantar Matematika Numerik
Ini adalah "Halo, Dunia!" PDE (Persamaan Diferensial Parsial). Persamaan Laplace atau Difusi sering muncul dalam Fisika, misalnya Persamaan Panas, Deforming, Fluid Dynamics, dll ... Karena kehidupan nyata adalah 3D tetapi kami ingin mengatakan "Halo, Dunia!" dan tidak menyanyikan "99 botol bir, ..." tugas ini diberikan dalam 1D. Anda dapat menafsirkan ini sebagai jubah karet yang diikat ke dinding di kedua ujungnya dengan beberapa kekuatan yang diterapkan padanya.
Pada [0,1]
domain, temukan fungsi u
untuk fungsi sumber f
dan nilai batas yang diberikan u_L
dan u_R
sedemikian rupa sehingga:
-u'' = f
u(0) = u_L
u(1) = u_R
u''
menunjukkan turunan kedua dari u
Ini dapat dipecahkan sepenuhnya teoretis tetapi tugas Anda adalah menyelesaikannya secara numerik pada domain yang didiskritisasi x untuk N
poin:
- x =
{i/(N-1) | i=0..N-1}
atau berbasis 1:{(i-1)/(N-1) | i=1..N}
h = 1/(N-1)
adalah spasi
Memasukkan
f
sebagai fungsi atau ekspresi atau stringu_L
,u_R
sebagai nilai floating pointN
sebagai integer> = 2
Keluaran
- Array, List, semacam string terpisah
u
sehinggau_i == u(x_i)
Contohnya
Contoh 1
Input: f = -2
, u_L = u_R = 0
, N = 10
(Do tidak mengambil f=-2
salah, itu bukan nilai tapi fungsi konstan yang kembali -2
untuk semua x
Hal ini seperti gaya gravitasi konstan pada tali kami..)
Keluaran: [-0.0, -0.09876543209876543, -0.1728395061728395, -0.22222222222222224, -0.24691358024691357, -0.24691358024691357, -0.22222222222222224, -0.1728395061728395, -0.09876543209876547, -0.0]
Ada solusi tepat yang mudah: u = -x*(1-x)
Contoh 2
Input: f = 10*x
, u_L = 0
u_R = 1
, N = 15
(Di sini ada banyak melawan angin di sisi kanan)
Keluaran: [ 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.]
Solusi tepat untuk kondisi ini: u = 1/3*(8*x-5*x^3)
Contoh 3
Input: f = sin(2*pi*x)
, u_L = u_R = 1
, N = 20
(Seseorang masuk gravitasi atau ada semacam atas dan melawan arah angin)
Keluaran: [ 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.]
Di sini solusinya adalah u = (sin(2*π*x))/(4*π^2)+1
Contoh 4
Input: f = exp(x^2)
, u_L = u_R = 0
,N=30
Keluaran:
[ 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. ]
Perhatikan sedikit ketidaksimetrisan
FDM
Salah satu metode yang mungkin untuk menyelesaikan ini adalah Metode Perbedaan Hingga :
- tulis ulang
-u_i'' = f_i
sebagai (-u_{i-1} + 2u_i - u{i+1})/h² = f_i
yang sama dengan-u_{i-1} + 2u_i - u{i+1} = h²f_i
- Siapkan persamaan:
- Yang sama dengan persamaan matriks-vektor:
- Selesaikan persamaan ini dan hasilkan
u_i
Salah satu implementasi ini untuk demonstrasi di 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)
Implementasi alternatif tanpa Matriks Aljabar (menggunakan metode 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
Namun Anda dapat menggunakan metode lain untuk menyelesaikan persamaan Laplace. Jika Anda menggunakan metode berulang, Anda harus mengulanginya sampai residual|b-Au|<1e-6
, dengan b
menjadi vektor sisi kananu_L,f_1h²,f_2h²,...
Catatan
Bergantung pada metode solusi Anda, Anda mungkin tidak dapat menyelesaikan contoh dengan tepat untuk solusi yang diberikan. Setidaknya untukN->infinity
kesalahan harus mendekati nol.
Celah standar tidak diijinkan , built-in untuk PDE diizinkan.
Bonus
Bonus -30% untuk menampilkan solusi, baik grafis atau ASCII-art.
Kemenangan
Ini codegolf, jadi kode terpendek dalam byte menang!
log(log(x))
atau sqrt(1-x^4)
yang memiliki integral, yang bagaimanapun tidak dapat diekspresikan dalam fungsi dasar.
u(x) = 1/2 (-sqrt(π) x erfi(x)+sqrt(π) erfi(1) x+e^(x^2)-e x+x-1)
tidak dapat dihitung secara tepat.
f(x) = exp(x^2)
.