Exemplo n.º 1
0
def integrar(f=funcion.Funcion(), a=0, b=1, toler=0.5):
    """Función que obtiene la integral mediante la aplicación iterativa del método de trapecios"""
    log.debug(
        "función integrar(f={0} tipo={1}, a={2} tipo={3}, b={4} tipo={5}, toler={6} tipo={7}".format(f, type(f), a,
                                                                                                     type(a), b,
                                                                                                     type(b), toler,
                                                                                                     type(toler)))
    error = toler * 2
    n = 1
    area_calc = 0
    F = f.integrar()  # primitiva del polinomio
    log.debug("Primitiva: F={0} tipo={1}".format(F, type(F)))
    area_real = F.evaluar(b) - F.evaluar(a)
    log.debug("Valor real integral: {0}".format(area_real))
    while error > toler:
        area_calc = trapecios(f, n, a, b)
        if area_real == area_calc:
            break
        if area_real == 0:
            area_real += toler / 10
        error = 100 * abs(area_real - area_calc) / area_real
        n += 1
        # if log.level
        if n % 100 == 0:
            log.debug("Valor calculado: {0}".format(area_calc))
    return area_real, area_calc, n, error
Exemplo n.º 2
0
def graficar(
    f=funcion.Funcion(), n=2, a=0, b=1, puntos_ex=(), M=100, puntos_frac=()):
    """Método que grafica la función. Requiere puntos que luego une con rectas,
    mientras más puntos mejor la aproximación a la curva.
    """
    # ToDo: lo mismo de los otros programas de integración
    log.debug("graficar(puntos_ex={0}, puntos_frac={1}, n={2}".format(
        len(puntos_ex), len(puntos_frac), n))
    input("Presione <Enter> para mostrar la gráfica")
    if plot is None:
        print_lib_missing()
    else:
        if n > 1000:  # evita que la gráfica tarde mucho en procesarse
            proporcion_ex = len(puntos_ex) / n
            puntos_ex = puntos_ex[:int(1000 * proporcion_ex)]
            puntos_frac = puntos_frac[:1000 - len(puntos_ex)]
            n = 1000  # el número de puntos sobre el polinomio se calculan en función del numero de puntos
        log.debug(
            "graficando {0} puntos de exito, {1} puntos de fracaso".format(
                len(puntos_ex), len(puntos_frac)))
        intervalo = abs(b - a)
        trape_b = intervalo / n  # FixMe
        x_0 = a - intervalo * 0.2
        x_f = b + intervalo * 0.2
        ancho_tot = x_f - x_0
        delta_x = trape_b / 4  # los puntos sobre el polinomio son el cuadruple de los N puntos del método
        # asegura que el poligono que representa al polinomio tiene una resolución (curvatura aparente) aceptable
        x_vals = [
            x_0 + delta_x * i for i in range(int(ancho_tot / delta_x) + 1)
        ]
        y_vals = [f.evaluar(x) for x in x_vals]
        max_y = max(y_vals)
        min_y = min(y_vals)
        log.debug(
            "graficando {0} puntos (x,f(x)) sobre la función\nx0 = {1}\nxf = {2}\nmin_y = {3}\nmax_y={4}"
            .format(len(x_vals), x_0, x_f, min_y, max_y))
        x_ax_pos = 0
        y_ax_pos = 0
        if not x_0 < 0 < x_f:
            if x_f < 0:
                y_ax_pos = x_f - intervalo * 0.05
            elif x_0 > 0:
                y_ax_pos = x_0 + intervalo * 0.05
        fig, ax = plot.subplots(1)
        ax.axhline(x_ax_pos, color='black')
        ax.axvline(y_ax_pos, color='black')
        ax.plot(x_vals, y_vals, color="magenta")
        ax.plot([x_0, x_f], [M, M], color="orange")
        ax.plot([a, a], [0, M], color="blue", linestyle="--")
        ax.plot([b, b], [0, M], color="blue", linestyle="--")
        for punto in puntos_ex:
            ax.scatter([punto[0]], [punto[1]], color="blue")
        for punto in puntos_frac:
            ax.scatter([punto[0]], [punto[1]], color="red")
        plot.show()
        log.debug("Grficación completa")
Exemplo n.º 3
0
def riemann(f=funcion.Funcion(), n=2, a=0, b=1):
    """Función que implementa sumas de Riemann en el centro del subintervalo"""
    delta_x = abs(b - a) / n
    area = 0
    for i in range(n):
        area += f.evaluar(
            a + delta_x * i +
            delta_x / 2)  # evalua en el punto medio del intervalo
        # ToDo: asignar delta_x / 2 a una variable para no calcularla en cada ciclo
    return area * delta_x
Exemplo n.º 4
0
def trapecios(f=funcion.Funcion(), n=2, a=0, b=1):
    """Función que implementa el metodo de los trapecios"""
    delta_x = abs(b - a) / n
    area = 0
    area += f.evaluar(a)
    area += f.evaluar(b)
    area /= 2
    for i in range(1, n):
        area += f.evaluar(a + delta_x * i)
    return area * delta_x
Exemplo n.º 5
0
def graficar(f=funcion.Funcion(), n=2, a=0, b=1):  # ToDo: definir método graficar()
    """Método que grafica la función. Requiere puntos que luego une con rectas,
    mientras más puntos mejor la aproximación a la curva.
    """
    input("Presione <Enter> para mostrar la gráfica")
    if plot is None or Polygon is None or PatchCollection is None:
        print_lib_missing()
    else:
        intervalo = abs(b - a)
        trape_b = intervalo / n  # base de los trapecios
        # ToDo: modificar orden de las instrucciones para que todo quede en terminos de delta_x
        x_0 = a - intervalo * 0.2
        x_f = b + intervalo * 0.2
        ancho_tot = x_f - x_0
        delta_x = trape_b / 4
        #  puntos sobre el polinomio
        # asegura que el poligono que representa al polinomio tiene una resolución (curvatura aparente) aceptable
        x_vals = [x_0 + delta_x * i for i in range(int(ancho_tot / delta_x) + 1)]
        y_vals = [f.evaluar(x) for x in x_vals]
        max_y = max(y_vals)
        min_y = min(y_vals)
        log.debug(
            "graficando {0}puntos (x,f(x))\nx0 = {1}\nxf = {2}\nmin_y = {3}\nmax_y={4}".format(len(x_vals), x_0, x_f,
                                                                                               min_y, max_y))
        x_ax_pos = 0
        y_ax_pos = 0
        if not x_0 < 0 < x_f:
            if x_f < 0:
                y_ax_pos = x_f - intervalo * 0.05
            elif x_0 > 0:
                y_ax_pos = x_0 + intervalo * 0.05
        trape_coord = []  # coordenadas de todos los tapecios
        trape_coord.append([[a, 0], [a + trape_b, 0], [a + trape_b, f.evaluar(a + trape_b)], [a, f.evaluar(a)]])
        # primer trapecio
        t = None
        for coord in range(1, n):
            # se evita evaluar la función más veces de las necesarias definiendo los puntos
            # a partir de los ya definidos en el arreglo
            t = trape_coord[coord-1]
            trape_coord.append([[t[1][0], 0], [t[1][0] + trape_b, 0], [t[1][0] + trape_b, f.evaluar(t[1][0] + trape_b)], [t[2][0], t[2][1]]])
        trape = []
        for coord in trape_coord:
            trape.append(Polygon(coord, True))
        trape_colecc = PatchCollection(trape, facecolor='b', alpha=0.5, edgecolor="b")
        fig, ax = plot.subplots(1)
        ax.axhline(x_ax_pos, color='black')
        ax.axvline(y_ax_pos, color='black')
        ax.add_collection(trape_colecc)
        ax.plot(x_vals, y_vals, color="magenta")
        plot.show()
        log.debug("Grficación completa")
Exemplo n.º 6
0
def montecarlo(f=funcion.Funcion(), n=100, a=0, b=1, M=100):
    """Función que calcula n puntos, y los separa en exitos y fracasos
    media implementación del método Montecarlo, de esta forma se puede aumentar la eficiencia reduciendo el tiempo"""
    longitud = abs(b - a)
    puntos_ex = []
    puntos_frac = []
    for i in range(n):
        x_i = a + (rnd() * longitud)
        y_i = M * rnd()
        if y_i <= f.evaluar(x_i):
            puntos_ex.append([x_i, y_i])
        else:
            puntos_frac.append([x_i, y_i])
    return puntos_ex, puntos_frac
Exemplo n.º 7
0
def simpson(f=funcion.Funcion(), n=2, a=0, b=1):
    """Función que implementa el método de Simpson"""
    if n % 2 != 0:
        raise ValueError
    delta_x = abs(b - a) / n
    area = 0
    pares = 0
    impares = 0
    for i in range(1, n):
        if i % 2 != 0:
            impares += f.evaluar(a + delta_x * i)
        else:
            pares += f.evaluar(a + delta_x * i)
    area += f.evaluar(a)
    area += f.evaluar(b)
    area += 4 * impares
    area += 2 * pares
    return area * delta_x / 3
Exemplo n.º 8
0
def integrar(f=funcion.Funcion(), a=0, b=1, toler=0.5, M=100, delta_n=100):
    """Función que obtiene la integral aplicando iterativamante el método Montecarlo.
    Está función implementa la mitad del método. En vez de pedir N + delta_N puntos
    en cada ciclo pide deltaN puntos y los agrega a los calculados en la interación anterior"""
    log.debug(
        "función integrar(f={0} tipo={1}, a={2} tipo={3}, b={4} tipo={5}, toler={6} tipo={7}"
        .format(f, type(f), a, type(a), b, type(b), toler, type(toler)))
    error = toler * 2
    n = 100
    area_calc = 0
    F = f.integrar()
    log.debug("Primitiva: F={0} tipo={1}".format(F, type(F)))
    area_real = F.evaluar(b) - F.evaluar(a)
    log.debug("Valor real integral: {0}".format(area_real))
    puntos_ex = []
    puntos_frac = []
    area_rect = M * abs(b - a)
    bandera = True
    while error > toler:
        if bandera:  # primera iteración, se calculan n puntos
            puntos_ex, puntos_frac = montecarlo(f, n, a, b, M)
            bandera = False
        else:  # i-ésima iteración, se calculan deltaN puntos y se añaden a los calculados en interaciones anteriores
            p_e, p_f = montecarlo(f, delta_n, a, b, M)
            puntos_ex += p_e
            puntos_frac += p_f
        # las siguientes dos lineas se trasladarón de la función montecarlo() a aquí
        proporcion = len(puntos_ex) / n
        area_calc = area_rect * proporcion
        if area_real == area_calc:
            break
        if area_real == 0:
            area_real += toler / 10
        error = 100 * abs(area_real - area_calc) / area_real
        n += delta_n
        # if log.level
        if n % 100 == 0:
            log.debug("Valor calculado: {0}".format(area_calc))
    return area_real, area_calc, n, error, puntos_ex, puntos_frac  # devuelve los arrays con todos los puntos
Exemplo n.º 9
0
def graficar(
    f=funcion.Funcion(), n=2,
    a=0,
    b=1
):  # ToDo: renombrar las variables delta_x y rect_b para que coincidan con el cambio en x para graficar la curva y el ancho del rectangulo respectivamente
    """Método que grafica la función. Requiere puntos que luego une con rectas,
    mientras más puntos mejor la aproximación a la curva.
    """
    input("Presione <Enter> para mostrar la gráfica")
    if plot is None or Rectangle is None or PatchCollection is None:
        print_lib_missing()
    else:
        intervalo = abs(b - a)
        rectang_b = intervalo / n  # base del rectangulo
        # ToDo: modificar el orden de las sentencias para que todo quede en terminos de delta_x
        x_0 = a - intervalo * 0.2
        x_f = b + intervalo * 0.2
        ancho = x_f - x_0
        delta_x = rectang_b / 4
        # el polinomio se grafica como un poligono de el cuadruple de rectangulos
        # asegura que el poligono que representa al polinomio tiene una resolución (curvatura aparente) aceptable
        x_vals = [x_0 + delta_x * i for i in range(int(ancho / delta_x) + 1)
                  ]  # absicsas de puntos sobre el polinomio
        y_vals = [f.evaluar(x)
                  for x in x_vals]  # ordenadas de puntos sobre el polinomio
        max_y = max(y_vals)
        min_y = min(y_vals)
        log.debug(
            "graficando {0}puntos (x,f(x))\nx0 = {1}\nxf = {2}\nmin_y = {3}\nmax_y={4}"
            .format(len(x_vals), x_0, x_f, min_y, max_y))
        x_ax_pos = 0
        y_ax_pos = 0
        if not x_0 < 0 < x_f:
            if x_f < 0:
                y_ax_pos = x_f - intervalo * 0.05
            elif x_0 > 0:
                y_ax_pos = x_0 + intervalo * 0.05
        rectang_pb_x = []  # puntos base de los rectangulos
        rectang_h = []  # altura del rectangulo, f evaluada en el punto medio
        rectang = []
        for i in range(n):
            rectang_pb_x.append(a + rectang_b * i)
            rectang_h.append(
                f.evaluar(rectang_pb_x[i] + rectang_b /
                          2))  # f evaluada en el punto medio del subintervalo
            rectang.append(
                Rectangle((rectang_pb_x[i], 0),
                          rectang_b,
                          rectang_h[i],
                          angle=0.0))
        fig, ax = plot.subplots(1)
        rectang_colecc = PatchCollection(rectang,
                                         facecolor='b',
                                         alpha=0.5,
                                         edgecolor="b")
        ax.axhline(x_ax_pos, color='black')
        ax.axvline(y_ax_pos, color='black')
        ax.add_collection(rectang_colecc)
        ax.plot(x_vals, y_vals, color="magenta")
        plot.show()
        log.debug("Grficación completa")
Exemplo n.º 10
0
def graficar(f=funcion.Funcion(), n=2, a=0,
             b=1):  # ToDo: definir método graficar()
    """Método que grafica la función. Requiere puntos que luego une con rectas,
    mientras más puntos mejor la aproximación a la curva.
    Las tapas de las figuras se grafican resolviendo el SEL asociado a los tres puntos por los que pasa la parabola
    """
    input("Presione <Enter> para mostrar la gráfica")
    if plot is None or Polygon is None or PatchCollection is None:
        print_lib_missing()
    else:
        intervalo = abs(b - a)
        fig_b = intervalo / n
        x_0 = a - intervalo * 0.2
        x_f = b + intervalo * 0.2
        ancho_tot = x_f - x_0
        delta_x = fig_b / 4  # FixMe: tal vez es necesario un valor mayor que 4 por las pocas figuras que requiere simpson
        # asegura que el poligono que representa al polinomio tiene una resolución (curvatura aparente) aceptable
        x_vals = [
            x_0 + delta_x * i for i in range(int(ancho_tot / delta_x) + 1)
        ]
        y_vals = [f.evaluar(x) for x in x_vals]
        max_y = max(y_vals)
        min_y = min(y_vals)
        log.debug(
            "graficando {0}puntos (x,f(x))\nx0 = {1}\nxf = {2}\nmin_y = {3}\nmax_y={4}"
            .format(len(x_vals), x_0, x_f, min_y, max_y))
        x_ax_pos = 0
        y_ax_pos = 0
        if not x_0 < 0 < x_f:
            if x_f < 0:
                y_ax_pos = x_f - intervalo * 0.05
            elif x_0 > 0:
                y_ax_pos = x_0 + intervalo * 0.05
        base_coord = []
        base_coord.append([[a, f.evaluar(a)], [a, 0], [a + fig_b * 2, 0],
                           [a + fig_b * 2,
                            f.evaluar(a + fig_b * 2)]])
        cont = 0
        for i in range(2, n, 2):
            b_ant = base_coord[cont - 1]
            x_i = a + fig_b * i
            base_coord.append([[b_ant[3][0], b_ant[3][1]], [b_ant[2][0], 0],
                               [x_i + fig_b * 2, 0],
                               [x_i + fig_b * 2,
                                f.evaluar(x_i + fig_b * 2)]])
            cont += 1
        tapa_coord = []
        for i in range(0, n, 2):
            reng = []
            m_b = []
            for j in range(i, i + 3):
                x_i = a + fig_b * j
                reng.append(Renglon((x_i**2, x_i, 1)))
                m_b.append(Renglon((f.evaluar(x_i), )))
            m_b = Matriz(m_b)
            log.debug("m_b={0}".format(m_b))
            m_a = Matriz(reng)
            log.debug("m_a={0}".format(repr(m_a)))
            m_a_inv = m_a.inversa()
            log.debug("m_a_inv = {0}".format(repr(m_a_inv)))
            m_x = m_a_inv * m_b  # resolución del SEL de los puntos por los que pasa la parabola
            log.debug("m_x={0}".format(repr(m_x)))
            p = funcion.Polinomio(coeficientes=(m_x[0][0], m_x[1][0],
                                                m_x[2][0]),
                                  exponentes=(2, 1, 0))
            log.debug("Tapa: p={0}".format(p))
            delta_x = fig_b / 20
            tapa = []
            for j in range(40):
                x_i = a + fig_b * i + delta_x * j
                tapa.append([x_i, p.evaluar(x_i)])
            tapa_coord.append(tapa)
        fig_coord = []
        for i in range(len(base_coord)):
            fig_coord.append(base_coord[i] + tapa_coord[i][::-1])
        log.debug("fig_coord={0}".format(fig_coord))
        figuras = []
        for coord in fig_coord:
            figuras.append(Polygon(coord, True))
        figuras_colecc = PatchCollection(figuras,
                                         facecolor='b',
                                         alpha=0.5,
                                         edgecolor="b")
        fig, ax = plot.subplots(1)
        for i in range(1, n, 2):
            x_i = a + fig_b * i
            ax.plot([x_i, x_i], [0, f.evaluar(x_i)], color="b", linestyle=":")
        ax.axhline(x_ax_pos, color='black')
        ax.axvline(y_ax_pos, color='black')
        ax.add_collection(figuras_colecc)
        ax.plot(x_vals, y_vals, color="magenta")
        plot.show()
        log.debug("Grficación completa")