31 de mayo de 2021

El método de la trisección Examen interciclo semestre mar-ago 2021

El método numérico llamado método de la trisección no existe, sin embargo, resulta en un práctica interesante de programación.

La única diferencia entre el método de la bisección y el de la trisección es que, en este último, el intervalo de búsqueda de la raíz se divide en tres parte iguales.

La definición completa del examen se encuentra en https://www.scribd.com/doc/306301095/Ejercicios-Basicos-de-Programacion

Una posible solución

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu May 20 19:36:44 2021
Me tomó 27 minutos resolver
27*3 + 15 min. para leer el texto = 96 min.
96 min. + 5 min. para subir a evirtual = 101 min.
@author: Angel Vázquez-Patiño
"""
from math import factorial

def seno(x):
    suma = 0
    for i in range(50):
        numerador = ((-1)**i)*(x**(2*i+1))
        denominador = factorial(2*i+1)
        suma += numerador/denominador
    return suma

def f(x):
    return seno(2*x+1)-(3/5)*x+1

def triseccion(f, a, b):
    aproximaciones = [(a+b)/2]
    e_a = 1 # para que entre al menos una vez al while
    while e_a > 0.000001:
        mi = a + (b-a)/3
        md = (mi + b)/2
        
        if f(a)*f(mi) < 0:
            aproximaciones.append((a+mi)/2)
            b = mi
        elif f(mi)*f(md) < 0:
            aproximaciones.append((mi+md)/2)
            a, b = mi, md
        elif f(md)*f(b) < 0:
            aproximaciones.append((md+b)/2)
            a = md
        elif f(mi) == 0:
            aproximaciones.append(mi)
            return aproximaciones
        elif f(md) == 0:
            aproximaciones.append(md)
            return aproximaciones
        
        e_a = abs((aproximaciones[-1]-aproximaciones[-2])/aproximaciones[-1])
    return aproximaciones

def grabar(lista, path):
    with open(path, 'w') as f:
        f.write('Aproximación, Valor\n')
        for i in range(len(lista)):
            f.write(str(i)+','+str(lista[i])+'\n')
a, b = -19, 3.5          
aproxs = triseccion(f, -19, 3.5)
grabar(aproxs, 'interciclo_resultados.csv')
# FIN de esta posible solución del examen (hay muchas otras formas de resolverlo)

# De aquí en adelante no es parte del examen
import numpy as np # Esto no he utilizado en la solución en sí del examen
from matplotlib import pyplot as plt # Esto no he utilizado en la solución en sí del examen
xs = np.linspace(a, b, 100)
ys = [seno(2*i+1)-3*i/5+1 for i in xs]
ys = np.array(ys)

plt.figure(figsize=(4,3))
plt.plot(xs, ys, label='$f(x)$', lw=2)
plt.scatter([1.21], [0], label='raíz', color='k')
plt.axhline(0, color='gray')
plt.axvline(0, color='gray')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.show()

No hay comentarios:

Publicar un comentario

Comentarios