Introducción a la matemática numérica
Este es el "¡Hola Mundo!" de PDE (ecuaciones diferenciales parciales). La ecuación de Laplace o difusión aparece a menudo en física, por ejemplo, ecuación de calor, deformación, dinámica de fluidos, etc. Como la vida real es 3D, pero queremos decir "¡Hola, mundo!" y no cantar "99 botellas de cerveza, ..." esta tarea se da en 1D. Puede interpretar esto como una túnica de goma atada a una pared en ambos extremos con cierta fuerza aplicada.
En un [0,1]dominio, encuentre una función upara la función fuente dada fy los valores límite u_Ly u_Rtal que:
-u'' = fu(0) = u_Lu(1) = u_R
u'' denota la segunda derivada de u
Esto puede resolverse puramente teórico, pero su tarea es resolverlo numéricamente en un dominio discretizado x para Npuntos:
- x =
{i/(N-1) | i=0..N-1}o basado en 1:{(i-1)/(N-1) | i=1..N} h = 1/(N-1)es el espacio
Entrada
fcomo función o expresión o cadenau_L,u_Rcomo valores de coma flotanteNcomo entero> = 2
Salida
- Matriz, Lista, algún tipo de cadena separada de
utal manera queu_i == u(x_i)
Ejemplos
Ejemplo 1
Entrada: f = -2, u_L = u_R = 0, N = 10(no tome f=-2mal, no es un valor, sino una función constante que los retornos -2para todos xEs como una fuerza de la gravedad constante en nuestra cuerda.).
Salida: [-0.0, -0.09876543209876543, -0.1728395061728395, -0.22222222222222224, -0.24691358024691357, -0.24691358024691357, -0.22222222222222224, -0.1728395061728395, -0.09876543209876547, -0.0]
Existe una solución exacta fácil: u = -x*(1-x)

Ejemplo 2
Entrada: f = 10*x, u_L = 0 u_R = 1, N = 15(Aquí hay una gran cantidad de viento arriba a la derecha)
Salida: [ 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.]
La solución exacta para esto dice: u = 1/3*(8*x-5*x^3)

Ejemplo 3
Entrada: f = sin(2*pi*x), u_L = u_R = 1, N = 20(Alguien rompió la gravedad o hay una especie de arriba y la dirección del viento)
Salida: [ 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.]
Aquí la solución exacta es u = (sin(2*π*x))/(4*π^2)+1

Ejemplo 4
Entrada: f = exp(x^2), u_L = u_R = 0,N=30
Salida:
[ 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. ]

Tenga en cuenta la ligera asimetría
FDM
Un posible método para resolver esto es el método de diferencia finita :
- reescribir
-u_i'' = f_icomo (-u_{i-1} + 2u_i - u{i+1})/h² = f_ique es igual-u_{i-1} + 2u_i - u{i+1} = h²f_i- Configura las ecuaciones:

- Que son iguales a una ecuación matriz-vector:

- Resuelve esta ecuación y genera el
u_i
Una implementación de esto para demostración en 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)
Implementación alternativa sin Matrix Algebra (usando el método 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
Sin embargo, puede usar cualquier otro método para resolver la ecuación de Laplace. Si usa un método iterativo, debe iterar hasta el residual |b-Au|<1e-6, bsiendo el vector del lado derechou_L,f_1h²,f_2h²,...
Notas
Dependiendo de su método de solución, es posible que no resuelva los ejemplos exactamente para las soluciones dadas. Al menos para N->infinityel error debe acercarse a cero.
Las lagunas estándar no están permitidas , se permiten incorporaciones para PDE.
Prima
Una bonificación de -30% para mostrar la solución, ya sea gráfica o ASCII-art.
Victorioso
¡Esto es codegolf, por lo que gana el código más corto en bytes!

f(x) = exp(x^2).log(log(x))osqrt(1-x^4)que tienen una integral, que sin embargo no se puede expresar en funciones elementales.u(x) = 1/2 (-sqrt(π) x erfi(x)+sqrt(π) erfi(1) x+e^(x^2)-e x+x-1)no es exactamente calculable.Respuestas:
Mathematica, 52.5 bytes (= 75 * (1 - 30%))
+0.7 bytes por comentario de @flawr.
Esto traza la salida.
p.ej
Explicación
Resolver para la función
u.Subdivideel intervalo [0,1] en N (cuarta entrada) partes.Mapa
ua la salida deSubdivide.Trazar el resultado final.
Solución no gráfica: 58 bytes
fuente
f(x) = exp(x^2)NDSolvepara el caso general de soluciones no elementales.Matlab,
84, 81.279.1 bytes = 113 - 30%Tenga en cuenta que en este ejemplo utilizo vectores de fila, esto significa que la matriz
Ase transpone.fse toma como un manejador de funciones,a,bson las contracciones de Dirichlet del lado izquierdo / derecho.Para el ejemplo,
f = 10*x, u_L = 0 u_R = 1, N = 15esto resulta en:fuente
R,
123,2 102,998,7 bytes (141-30%)Editar: ¡Ahorré un puñado de bytes gracias a @Angs!
Si alguien quiere editar las imágenes, siéntase libre de hacerlo. Esto es básicamente una adaptación R de las versiones de Matlab y Python publicadas.
Ungolfed y explicado:
Ejemplo y casos de prueba:
La función nombrada y no reflejada se puede llamar usando:
Tenga en cuenta que el
fargumento es una función R.Para ejecutar la versión de golf simplemente use
(function(...){...})(args)fuente
is.numeric(f)cheque si declarafcomo función, no es necesario pasarlo directamente en la llamada de función al solucionador.fcomo una función para que no tenga que verificar el caso, es una constante (función).fser numérico.f = (function(x)-2)funciona para el primer ejemplo, por lo que nunca es necesariorep.x<-0:10/10;f<-function(x){-2};10^-2*sapply(x,f)si f (x) no está garantizado para ser vectorizado o simplemente10^-2*f(x)sifestá vectorizado (laplace(Vectorize(function(x)2),0,0,10)fcomo una función adecuada.Haskell,
195168 bytesLa legibilidad recibió un gran golpe. Sin golf:
TODO: Imprimiendo en
8371 bytes.Déjame ver:
D'oh!
fuente
Axioma,
579460 bytesdeshazte de él y prueba
la función para la pregunta es m (,,,) el código anterior se coloca en el archivo "file.input" y se carga en Axiom. El resultado depende de la función digits ().
si alguien piensa que no es golf => él o ella puede mostrar cómo hacerlo ... gracias
PD
Parecen los 6 números después del. para e ^ (x ^ 2) no están bien aquí o en los ejemplos, pero aquí aumento los dígitos pero los números no cambian ... para mí significa que los números en el ejemplo están mal. ¿Por qué todos los demás no han mostrado sus números?
para sin (2 *% pi * x) también hay problemas
"Aquí la solución exacta es u = (sin (2 * π * x)) / (4 * π ^ 2) +1" copié la solución exacta para x = 1/19:
en WolframAlpha https://www.wolframalpha.com/input/?i=(sin(2% CF% 80% 2F19))% 2F (4 % CF% 80% 5E2)% 2B1 resulta
1.0083001 propuesto como resultado es diferente en el cuarto dígito del resultado real 1.00822473 ... (y no sexto)
fuente
f=-2ejemplo tiene una solución analítica y numérica coincidente.