Primera Derivada con Diferencias divididas hacia adelante
Una aproximación a primera derivada, usa los primeros dos términos del polinomio de Taylor alrededor de xi en para un punto a la derecha xi+1 a una distancia h = xi+1–xi
f(xi+1)=f(xi)+1!f′(xi)(h)+2!f′′(xi)(h)2+...
se puede simplificar en un polinomio de grado uno y un término de error:
fi+1=fi+(h)fi′+O(h2)...
Despejando la expresión para f’i
fi′=hfi+1−fi=hΔfi
La expresión también es la primera diferencia finita dividida con un error del orden O(h). (tema usado en interpolación).
Revise que el término de la expresión queda O(h2)/h con lo que se disminuye el exponente en uno.
Primera derivada con diferencias divididas centradas
Se realiza el mismo procedimiento que el anterior, usando un punto xi+1 y xi-1 alrededor de xi. En el término xi-1 el valor de h es negativo al invertir el orden de la resta.
Para visualizar el concepto de Cuadratura de Gauss de dos puntos considere lo siguiente:
Se tiene un corte transversal del un recipiente rectangular lleno de líquido limitado en x entre [-1,1], al que se le ha depositado encima otro recipiente con perfil f(x) = x2 hasta que reposan sus extremos en x[-1,1].
La altura de ambos recipientes es la misma.
La superficie entre f(x) y el eje x es el integral de f(x) en el intervalo.
Si suponemos que la figura es el corte transversal de una vasija y la parte en amarillo es líquida, la vasija ha desplazado el líquido que ocupa ahora el «área» mostrada en la gráfica que corresponde al integral de f(x)=x2. entre [-1,1].
Ahora, suponga que se perfora el perfil de f(x) en dos puntos equidistantes cercanos x=0. Los orificios permitirían el desplazamiento del liquido al interior de f(x) que dejando pasar suficiente tiempo, permitiría tener todo el líquido en el recipiente rectangular entre [-1,1] como una línea horizontal.
Podría medir la altura que tiene el líquido y que tiene un equivalente en un punto f(x1). Debería encontrar el valor de x1 que permite disponer del mismo valor entre el área debajo de f(x) y el rectángulo del corte transversal amarillo ahora formado.
Se usa el resultado analítico del integral restando el área del rectángulo obtenido al evaluar la función f(x) entre [0,1], teniendo un problema de búsqueda de raíces. Obtenemos el valor de x1.
Se muestra que el área bajo f(x) es equivalente al área del rectángulo conformado.
Si utilizamos el desplazamiento horizontal desde el centro para un punto encontrado como un «factor», tendremos que el área del rectángulo se mantendría equivalente, y el desplazamiento proporcional a la mitad del intervalo si se varía el intervalo de observación. Este factor coincide con el factor de Cuadratura de Gauss de dos puntos.
funcion fx: x**2
Integral Fx: x**3/3
I analitico: 0.6666666666666666
I aproximado: 0.6666666666654123
desplaza centro: 0.5773502691890826
factor desplaza: 0.5773502691890826
Factor CuadGauss: 0.5773502691896258
erradoFactor: 1.2545520178264269e-12
error integral: 1.2543299732215019e-12
El error del integral es del orden de 10-12
Cambiamos la figura geométrica a un trapecio generado por la recta que pasa por los puntos xi desplazados desde el centro.
Usamos la función f(x) = x2 + x + 1, observaremos si los resultado son equivalentes.
La figura al inicio del experimento será:
Luego de realizar realizar el mismo cálculo anterior usando un equivalente a trapecio se tiene:
con valores numéricos:
funcion fx: x**2 + x + 1
Integral Fx: x**3/3 + x**2/2 + x
I analitico: 2.6666666666666665
I aproximado: 2.6666666666654124
desplaza centro: 0.5773502691890826
factor desplaza: 0.5773502691890826
Factor CuadGauss: 0.5773502691896258
erradoFactor: 1.2545520178264269e-12
error integral: 1.2541079286165768e-12
El error del integral es también del orden de 10-12, además observe que el factor de cuadratura de Gauss se mantiene.
Realice el experimento usando un polinomio de grado superior y observe los errores para el integral y las diferencia con el coeficiente de Cuadratura de 2 puntos.
La cuadratura de Gauss aproxima el integral de una función en un intervalo [a,b] centrado en cero mediante un cálculo numérico con menos operaciones y evaluaciones de la función. Se representa como una suma ponderada:
I≅(2b−a)(c0f(xa)+c1f(xb))
para la fórmula de dos puntos con referencia a una función centrada en cero y ancho unitario a cada lado, se tiene:
c0=c1=1,x0=−31,x1=31
Para un intervalo de evaluación desplazado en el eje x se requiere convertir los puntos al nuevo intervalo. Se desplaza el punto cero al centro del intervalo [a,b] y se corrige el desplazamiento hacia la izquierda y derecha del centro con x0 y x1.
xa=2b+a−2b−a(31)xb=2b+a+2b−a(31)
con lo que el resultado aproximado del integral se convierte en:
I≅2b−a(f(xa)+f(xb))
cuya fórmula es semejante a una mejor aproximación de un trapecio, cuyos promedios de alturas son puntos internos de [a,b], concepto mostrado en la gráfica.
el resultado se puede mejorar aumentando el número de tramos en el intervalo [a,b]. Por ejemplo, el resultado usando 4 tramos el resultado es semejante al usar el método del trapecio con 128 tramos, lo que muestra el ahorro en cálculos entre los métodos
Instrucciones en Python usando la Cuadratura de Gauss de dos puntos para una función f(x):
# Integración: Cuadratura de Gauss de dos puntos# modelo con varios tramos entre [a,b]import numpy as np
import matplotlib.pyplot as plt
# cuadratura de Gauss de dos puntosdefintegraCuadGauss2p(fx,a,b, vertabla=False):
''' funcion fx, intervalo[a,b]
vertabla=True para ver resultados parciales
'''
x0 = -1/np.sqrt(3)
x1 = -x0
xa = (b+a)/2 + (b-a)/2*(x0)
xb = (b+a)/2 + (b-a)/2*(x1)
area = ((b-a)/2)*(fx(xa) + fx(xb))
if vertabla==True:
print('[xa,xb,f(xa),f(xb)],area')
print([xa,xb,fx(xa),fx(xb)],area)
return(area)
# INGRESO
fx = lambda x: np.sqrt(x)*np.sin(x)
# intervalo de integración
a = 1
b = 3
tramos = 4
# PROCEDIMIENTO
muestras = tramos+1
xi = np.linspace(a,b,muestras)
area = 0
for i inrange(0,muestras-1,1):
deltaA = integraCuadGauss2p(fx,xi[i],xi[i+1],vertabla=True)
area = area + deltaA
# SALIDAprint('Integral: ', area)
Gráfica por tramos
La gráfica que complementa el resultado anterior, se realiza añadiendo las instrucciones presentadas a continuación.
Considere que la gráfica es útil con pocos tramos en el intervalo[a,b]
# GRAFICAR por cada Segmento/tramo# para concepto con 'pocos' segmentos
subtramo = xi
muestrastramo = 10
x0 = -1/np.sqrt(3)
x1 = 1/np.sqrt(3)
# gráficas de todos los tramos
aj = [] ; bj = []
xj = [] ; fj = []
recta = []
for i inrange(0,tramos,1):
ai = subtramo[i]
bi = subtramo[i+1]
xk = np.linspace(ai,bi,muestrastramo)
fk = fx(xk)
xj = xj + list(xk)
fj = fj + list(fk)
# puntos xa y xb por tramo
xa = (bi+ai)/2 + (bi-ai)/2*(x0)
xb = (bi+ai)/2 + (bi-ai)/2*(x1)
aj.append(xa)
bj.append(xb)
# Recta entre puntos x0 y x1 por tramo
m = (fx(xb)-fx(xa))/(xb-xa)
b0 = fx(xa) - m*xa
linea = b0 + m*xk
recta = recta + list(linea)
# Marcadores 'o' de xa y xb por tramos
puntox = np.concatenate((aj,bj))
puntoy = fx(puntox)
# Trazado de lineas
plt.plot(xj,recta, label = 'grado 1', color = 'tab:orange')
plt.fill_between(xj,0,recta, color='tab:olive')
plt.plot(xj,fj, label='f(x)', color = 'blue')
# Verticales para dividir los tramosfor i inrange(0,len(subtramo),1):
plt.axvline(subtramo[i], color='tab:gray')
# Marcadores de puntos xa y xb por tramosfor j inrange(0,len(aj),1):
plt.axvline(aj[j], color='w')
plt.axvline(bj[j], color='w')
plt.plot(puntox,puntoy, 'o', color='g')
plt.title('Integral: Cuadratura Gauss')
plt.xlabel('x')
plt.ylabel('f(x)')
plt.legend()
plt.show()
A partir del algoritmo para Simpson de 1/3, se realizan modificaciones para obtener el algoritmo de Simpson de 3/8:
Resultados de algoritmo
tramos: 6
Integral con Simpson 3/8: 2.0542043270535757
Caso: f(x) es una expresión matemática
# Integración Simpson 3/8import numpy as np
import matplotlib.pyplot as plt
defintegrasimpson38(fx,a,b,tramos):
''' integral con método de Simpson 3/8
tramos debe ser múltiplo de 3
'''# Validar cantidad de tramos múltiplo de 3
esmult3 = tramos%3
if esmult3 != 0:
suma = 'tramos debe ser múltiplo de 3'# Regla de Simpson 3/8if esmult3 == 0:
h = (b-a)/tramos
xi = a
suma = 0
for i inrange(0,tramos,3):
unS38 = (3/8)*h*(fx(xi)+3*fx(xi+h)+3*fx(xi+2*h)+fx(xi+3*h))
suma = suma + unS38
xi = xi + 3*h
return(suma)
# PROGRAMA -----------------# INGRESO
fx = lambda x: np.sqrt(x)*np.sin(x)
# intervalo de integración
a = 1
b = 3
tramos = 6
# PROCEDIMIENTO
Area = integrasimpson38(fx,a,b,tramos)
# SALIDAprint('tramos: ',tramos)
print('Integral con Simpson 3/8: ',Area)
iftype(Area)==str:
print(' Revisar errores...')
Gráfica
Se puede observar mejor lo expresado usando la gráfica para observar los tramos, muestras, por segmento.
Se puede cambiar el número de tramos en el algoritmo anterior, considerando que deben ser múltiplo de 3.
Instrucciones en Python adicionales al algoritmo anterior
# GRAFICA# fx muestras por tramo
muestras = tramos + 1
xi = np.linspace(a,b,muestras)
fi = fx(xi)
fi0 = np.zeros(muestras) # linea base# fx suave aumentando muestras
muestrasfxSuave = 4*tramos + 1
xk = np.linspace(a,b,muestrasfxSuave)
fk = fx(xk)
# Rellenofor i inrange(0,muestras-2,3):
relleno = 'lightgreen'if (i/3)%2==0: # i/3 multiplo 2
relleno ='lightblue'
xktramo = xk[i*4:(i+3)*4+1]
fktramo = fk[i*4:(i+3)*4+1]
plt.fill_between(xktramo,fktramo,fktramo*0,color=relleno)
# Funcion f(x)
plt.plot(xk,fk, label='f(x)')
plt.plot(xi,fi,'o', label='f(xi)')
# Divisiones entre Simpson 3/8for i inrange(0,muestras,1):
tipolinea = 'dotted'if i%3==0: # multiplo de 3
tipolinea = 'dashed'
plt.vlines(xi[i],fi0[i],fi[i],
linestyle=tipolinea)
plt.axhline(0)
plt.xlabel('x')
plt.ylabel('f')
plt.title('Integral: Regla de Simpson 3/8')
plt.legend()
plt.show()
que simplificando tiene como resultado para un solo tramo:
I≅3h[f(x0)+4f(x1)+f(x2)]
siendo h el tamaño de paso, donde para la expresión el divisor debe ser par, múltiplo de 2, al cubrir todo el intervalo [a,b]. En caso de usar valores de muestras xi, fi, el valor de h debe ser constante.
h=2b−a
Error de truncamiento
la cota del error de truncamiento se estima como O(h5)
errortrunca=−90h5f(4)(z)
para un valor de z dentro del intervalo [a,b] de integración.
para cuantificar el valor, se puede usar la diferencia finita Δ4f, pues con la derivada sería muy laborioso.
Del ejercicio con trapecios, se repite el ejercicio con n tramos; usando dos tramos (tres puntos) en cada iteración.
Cada iteración se procesa avanzando dos puntos xi, xi+h, xi+2h . Ejemplo:
tramos: 8
Integral: 2.053709383061734
>>>
Instrucciones en Python
Se realiza mediante la aplicación directa de la fórmula para cada segmento conformado de dos tramos. Se verifica que el valor de tramos sea par.
# Integración: Regla Simpson 1/3import numpy as np
import matplotlib.pyplot as plt
# INGRESO:
fx = lambda x: np.sqrt(x)*np.sin(x)
# intervalo de integración
a = 1
b = 3
tramos = 8
# Validar cantidad de tramos pares
esimpar = tramos%2
while (esimpar == 1):
print('tramos: ',tramos)
tramos = int(input('tramos debe ser par: '))
esimpar = tramos%2
# PROCEDIMIENTO# Regla de Simpson 1/3
h = (b-a)/tramos
xi = a
area = 0
for i inrange(0,tramos,2):
deltaA = (h/3)*(fx(xi)+4*fx(xi+h)+fx(xi+2*h))
area = area + deltaA
xi = xi + 2*h
# SALIDAprint('tramos:', tramos)
print('Integral: ', area)
Gráfica
Se puede observar mejor lo expresado usando la gráfica para observar los tramos, muestras, por segmento. Para este caso se ejecuta el algoritmo anterior usando tramos =8
Instrucciones en Python adicionales al algoritmo anterior
# GRAFICA# fx muestras por tramo
muestras = tramos + 1
xi = np.linspace(a,b,muestras)
fi = fx(xi)
fi0 = np.zeros(muestras) # linea base# fx suave aumentando muestras
muestrasfxSuave = 4*tramos + 1
xk = np.linspace(a,b,muestrasfxSuave)
fk = fx(xk)
# Rellenofor i inrange(0,muestras-1,2):
relleno = 'lightgreen'if (i/2)%2==0: # i/2 par
relleno ='lightblue'
xktramo = xk[i*4:(i+2)*4+1]
fktramo = fk[i*4:(i+2)*4+1]
plt.fill_between(xktramo,fktramo,fktramo*0,color=relleno)
# Funcion f(x)
plt.plot(xk,fk, label='f(x)')
plt.plot(xi,fi,'o', label='f(xi)')
# Divisiones entre Simpson 1/3for i inrange(0,muestras,1):
tipolinea = 'dotted'if i%2==0: # i par
tipolinea = 'dashed'
plt.vlines(xi[i],fi0[i],fi[i],
linestyle=tipolinea)
plt.axhline(0)
plt.xlabel('x')
plt.ylabel('f')
plt.title('Integral: Regla de Simpson 1/3')
plt.legend()
plt.show()
A partir del ejercicio anterior, se resume en una función de Python si la entrada f(x) es una expresión matemática:
defintegrasimpson13(fx,a,b,tramos):
''' integral con método de Simpson 1/3
tramos debe debe ser múltiplo de 2
'''# Validar cantidad de tramos pares
esmult2 = tramos%2
if esmult2 != 0:
suma = 'tramos debe ser múltiplo de 2'# Regla de Simpson 1/3if esmult2 == 0:
h = (b-a)/tramos
xi = a
suma = 0
for i inrange(0,tramos,2):
unS13 = (h/3)*(fx(xi)+4*fx(xi+h)+fx(xi+2*h))
suma = suma + unS13
xi = xi + 2*h
return(suma)
Caso: x[i], f[i] son muestras
xi = [1. , 1.5, 2. , 2.5, 3.]
fi = [0.84147098, 1.22167687, 1.28594075,
0.94626755, 0.24442702]
Cuando se integra sobre muestras dadas por los vectores xi, fi. Se revisa que los tramos entre muestras sean iguales para un Simpson 1/3 y que existan suficientes puntos para completar el integral.
# Integración Simpson 1/3# Usando una muestras xi,fiimport numpy as np
import matplotlib.pyplot as plt
defintegrasimpson13_fi(xi,fi,tolera = 1e-10):
''' sobre muestras de fi para cada xi
integral con método de Simpson 1/3
respuesta es np.nan para tramos desiguales,
no hay suficientes puntos.
'''
n = len(xi)
i = 0
suma = 0
whilenot(i>=(n-2)):
h = xi[i+1]-xi[i]
dh = abs(h - (xi[i+2]-xi[i+1]))
if dh<tolera:# tramos iguales
unS13 = (h/3)*(fi[i]+4*fi[i+1]+fi[i+2])
suma = suma + unS13
else: # tramos desiguales
suma = 'tramos desiguales en i: '+str(i)
suma = suma ' , '+str(i+2)
i = i + 2
if i<(n-1): # incompleto, faltan tramos por calcular
suma = 'tramos incompletos, faltan '
suma = suma ++str((n-1)-i)+' tramos'return(suma)
# PROGRAMA -----------------# INGRESO
xi = [1. , 1.5, 2. , 2.5, 3.]
fi = [0.84147098, 1.22167687, 1.28594075,
0.94626755, 0.24442702]
# PROCEDIMIENTO
Area = integrasimpson13_fi(xi,fi)
# SALIDAprint('tramos: ',len(xi)-1)
print('Integral con Simpson 1/3: ',Area)
iftype(Area)==str:
print(' Revisar errores...')
resultados
tramos: 4
Integral con Simpson 1/3: 2.0549261966666665
>>>
Usado cuando el intervalo a integrar tiene varios segmentos, cada segmento tiene dos tramos. Ejemplo para dos segmentos, cuatro tramos, semejante al usado en la gráfica. La simplificación es válida si h es constante.
La integración numérica con la regla del trapecio usa un polinomio de primer grado como aproximación de f(x) entre los extremos a y b del intervalo.
Es la primera de las formulas cerradas de Newton-Cotes.
I=∫abf(x)dx≅∫abf1(x)dx
usando el rango entre [a,b] el polinomio se aproxima con una línea recta:
f1(x)=f(a)+b−af(b)−f(a)(x−a)
el área bajo esta línea recta es una aproximación de la integral de f(x) entre los límites a y b.
El resultado del integral es la regla del trapecio:
I=(b−a)2f(a)+f(b)
que se interpreta como la multiplicación entre la base y altura promedio de un trapecio. También se llega al resultando sumando las áreas de sus componentes: rectángulo y triángulo.
El error de truncamiento se encuentra como el integral del término que le sigue al polinomio de Taylor en la aproximación, es decir el de grado 2, que al integrarlo tiene un orden de h3. (Rodríguez p275)
y el integral de todo el intervalo es la suma de todos los trapecios.
Integral=A1+A2+A3+A4
si se quiere tomar el factor común entre las sumas de áreas de cada tramo, también se tiene la forma de la ecuación con un h equidistante entre cada tramo del intervalo.
Integral=20.5(f(1)+2f(1.5)+2f(2)+2f(2.5)+f(3))
Interpretando la fórmula, el integral es la suma de:
una vez la función evaluada en cada extremo,
mas dos veces cada valor de la función evaluada en los puntos intermedios.
El resultado de la suma se multiplica por h/2.
En caso que los puntos no sean equidistantes la simplificación NO procede, y se sumaran las áreas de los trapecios de cada tramo.
Siguiendo el procedimiento, para cada cantidad de tramos en el intervalo, los resultados serán:
Algoritmo con fórmula simplificada para varios tramos, con puntos de muestras equidistantes h.
# Integración: Regla de los trapecios# Usando una función fx()import numpy as np
import matplotlib.pyplot as plt
# INGRESO
fx = lambda x: np.sqrt(x)*np.sin(x)
# intervalo de integración
a = 1
b = 3
tramos = 4
# PROCEDIMIENTO# Regla del Trapecio# Usando tramos equidistantes en intervalo
h = (b-a)/tramos
xi = a
suma = fx(xi)
for i inrange(0,tramos-1,1):
xi = xi + h
suma = suma + 2*fx(xi)
suma = suma + fx(b)
area = h*(suma/2)
# SALIDAprint('tramos: ', tramos)
print('Integral: ', area)
La gráfica como ayuda didáctica, si la cantidad de tramos sea «poca», muestra los trapecios, si aumenta la cantidad de tramos, no es necesario poner líneas verticales en blanco para separar los trapecios:
# GRAFICA# Puntos de muestra
muestras = tramos + 1
xi = np.linspace(a,b,muestras)
fi = fx(xi)
# Linea suave
muestraslinea = tramos*10 + 1
xk = np.linspace(a,b,muestraslinea)
fk = fx(xk)
# Graficando
plt.plot(xk,fk, label ='f(x)')
plt.plot(xi,fi, marker='o',
color='orange', label ='muestras')
plt.xlabel('x')
plt.ylabel('f(x)')
plt.title('Integral: Regla de Trapecios')
plt.legend()
# Trapecios
plt.fill_between(xi,0,fi, color='g')
for i inrange(0,muestras,1):
plt.axvline(xi[i], color='w')
plt.show()
Para rellenar el área bajo la curva se usa la instrucción plt.fill_between(xi,0,fi, color=’g’). La división de los trapecios con una línea blanca (white) se realiza con la instrucción plt.axvline(xi[i], color=’w’).
A partir del ejercicio anterior, se resume en una función de Python si la entrada f(x) es una expresión matemática:
defintegratrapecio(fx,a,b,tramos):
h = (b-a)/tramos
xi = a
suma = fx(xi)
for i inrange(0,tramos-1,1):
xi = xi + h
suma = suma + 2*fx(xi)
suma = suma + fx(b)
area = h*(suma/2)
return(area)
Caso: x[i], f[i] son muestras
Algoritmo usando las muestras y para tramos que pueden tener distancias arbitrarias. En este caso se usa la formula del área del trapecio para cada tramo.
Usado para ejercicios donde los datos proporcionados son muestras. Se adapta el bloque de ingreso y el procedimiento inicia desde «Regla de Trapecio». La cantidad de tramos será el numero de muestras menos uno tramos = len(xi) - 1
# Integración: Regla de los trapecios# Usando una muestras xi,fiimport numpy as np
import matplotlib.pyplot as plt
defintegratrapecio_fi(xi,fi):
''' sobre muestras de fi para cada xi
integral con método de trapecio
'''
n = len(xi)
suma = 0
for i inrange(0,n-1,1):
dx = xi[i+1]-xi[i]
untrapecio = dx*(fi[i+1]+fi[i])/2
suma = suma + untrapecio
return(suma)
# PROGRAMA -----------------# INGRESO
xi = [1. , 1.5, 2. , 2.5, 3. ]
fi = [0.84147098, 1.22167687, 1.28594075,
0.94626755, 0.24442702]
# PROCEDIMIENTO
Area = integratrapecio_fi(xi,fi)
# SALIDAprint('tramos: ',len(xi)-1)
print('Integral con trapecio: ',Area)