Me lo contaron y lo olvidé, lo leí y lo entendí, lo hice y lo aprendí.





domingo, 18 de marzo de 2012

Método gráfico, bisección y falsa posición en python [métodos numéricos]

He aquí unos programas que sirven para resolver ecuaciones mediante los métodos numéricos de:
-Método gráfico
-Bisección
-Falsa Posición.

El funcionamiento es sencillo:
Se introduce la función en el main así como el rango de la tabulación y graficación. Se tabulan los resultados y se muestra la gráfica, de allí se sacan rangos de aproximación a 0 (en caso de que existan) y se mandan como parámetros a los 2 siguientes métodos.
Al final se despliega la gráfica y los resultados de ambos métodos para cada uno de los rangos.

Para el funcionamiento del programa se necesitan los módulos:
SciTools
Pylab.

Bueno, he aquí los códigos:

Main.py:

# -*- coding: cp1252 -*-
import MetodoGrafico
import biseccion
import falsaPosicion
from scitools.StringFunction import StringFunction
def getRangos(*tabla):
    rangos=[]
    tabla2=[]
    for elemento in tabla:
        for cosa in elemento:
            tabla2.append(cosa)
    i=0
    while i<len(tabla2):
        if i>0:
            if tabla2[i]>0.0 and tabla2[i-1]<0.0:
                rangos.append([tabla2[i-1],tabla2[i]])
            if tabla2[i]<0.0 and tabla2[i-1]>0.0:
                rangos.append([tabla2[i-1],tabla2[i]])
            if (tabla2[i]==0.0):
                rangos.append([tabla2[i-1],tabla2[i]])
        i=i+1
    return rangos


funcion = raw_input("""Escribe la función a evaliar de la forma
N*x
N*(a+b)
fx= """)
funcion=funcion.replace("^","**")
inferior=raw_input("\nIntriduce el valor inferior de la tabulacion: ")
superior=raw_input("\nIntriduce el valor superior de la tabulacion: ")
incremento=raw_input("\nIntriduce incremento en la tabulacion: ")
ea=raw_input("\nIntroduce el valor del error aproximado: ")
ea=eval(ea)
tabla=MetodoGrafico.getTabla(funcion,inferior=inferior,superior=superior,incremento=incremento)
rangos=getRangos(tabla)
print "\nRangos:\n"
print rangos
print "\n"
print "\nmetodo de biseccion: \n"
for rango in rangos:
    biseccion.biseccion(xl=rango[0],xu=rango[1],ea=ea,funcion=funcion)


print "\n\nMetodo Falsa posicion\n"
for rango in rangos:
    falsaPosicion.falsaPosicion(xl=rango[0],xu=rango[1],ea=ea,funcion=funcion)


metodoGrafico.py:
# -*- coding: cp1252 -*-
import os
from scitools.StringFunction import StringFunction
from math import *
from funcion import *
def getTabla(funcion,superior,inferior,incremento):
archivo=open("grafica.py","w")
archivo.write("from pylab import *\n")
archivo.write("x=arange("+inferior+","+superior+"+"+incremento+","+incremento+")\n")
archivo.write("fx="+funcion+"\n")
archivo.write("plot(x,fx)\n")
archivo.write("show()\n")
archivo.close()
funcion = funcion.replace("e",str(e))
fx=StringFunction(funcion,independent_variable='x')
i=float(eval(inferior))
tabla = []
while i<=float(eval(superior)):
tabla.append(getValue(funcion,i))
i=i+float(eval(incremento))
os.startfile("grafica.py")
return tabla

biseccion.py:
# -*- coding: cp1252 -*-
from math import *
from scitools.StringFunction import StringFunction
from funcion import *
def biseccion(xl,xu,ea,funcion):
def getxr(xl,xu):
return ((xl+xu)/2)

fx=StringFunction(funcion,independent_variable='x')
i=0
lista=[]
er=[]
xr=0.0
while True:
xr=getxr(xl,xu)
er.append(xr)
lista.append(getValue(funcion,xr))
fxl=getValue(funcion,xl)
fxu=getValue(funcion,xu)
fxr=getValue(funcion,xr)
if i>0:
                        try:
                                es=((er[i]-er[i-1])/er[i])*100
                        except ZeroDivisionError:
                                print "Ha ocurrido una division sobre 0, el programa debe de cerrarse"
                                break
if abs(es)<ea:
break
if fxl<0 and fxr<0:
xl=xr
elif fxl>0 and fxr>0:
xl=xr
elif fxu<0 and fxr<0:
xu = xr
elif fxu>0 and fxr>0:
xu = xr
i=i+1
print """Del rango"""+str(xl)+"-"+str(xu)+"""el valor xr es
"""
print xr

falsaPosicion.py:
# -*- coding: cp1252 -*-
from math import *
from scitools.StringFunction import StringFunction
from funcion import *
def falsaPosicion(funcion,xl,xu,ea):
def getxr(xl,xu):
return xu-((getValue(funcion,xu)*(xl-xu))/(getValue(funcion,xl)-fx(xu)))

fx=StringFunction(funcion,independent_variable='x')
i=0
lista=[]
er=[]
xr=0.0
while True:
xr=getxr(xl,xu)
er.append(xr)
lista.append(getValue(funcion,xr))
fxl=getValue(funcion,xl)
fxu=getValue(funcion,xu)
fxr=getValue(funcion,xr)
if i>0:
                        try:
                                es=((er[i]-er[i-1])/er[i])*100
                        except:
                                es=0
if abs(es)<ea:
break
if fxl<0 and fxr<0:
xl=xr
elif fxl>0 and fxr>0:
xl=xr
elif fxu<0 and fxr<0:
xu = xr
elif fxu>0 and fxr>0:
xu = xr
i=i+1

print "Del rango "+str(xl)+"-"+str(xu)+" xr ="
print xr


funcion.py:

from math import *
def getValue(fx,x):
    y = fx.replace("x",str(x))
    return eval(y)




Una vez más eso es todo; como se han de imaginar todo funciona ejecutando el main.py.

No hay comentarios:

Publicar un comentario