Hay dos formas de abordar este problema: numérica y simbólicamente.
Para resolverlo numéricamente, primero tiene que codificarlo como una función "ejecutable" - insertar un valor, obtener un valor. Por ejemplo,
def my_function(x):
return 2*x + 6
Es muy posible analizar una cadena para crear automáticamente dicha función; digamos que analiza el 2x + 6
en una lista, [6, 2]
(donde el índice de la lista corresponde a la potencia de x - entonces 6 * x^0 + 2 * x^1).Entonces:
def makePoly(arr):
def fn(x):
return sum(c*x**p for p,c in enumerate(arr))
return fn
my_func = makePoly([6, 2])
my_func(3) # returns 12
este caso es necesario otra función que se conecta repetidamente un valor de x en su función, mira a la diferencia entre el resultado y lo que quiere encontrar, y pellizca su valor x que (esperemos) minimizar la diferencia.
def dx(fn, x, delta=0.001):
return (fn(x+delta) - fn(x))/delta
def solve(fn, value, x=0.5, maxtries=1000, maxerr=0.00001):
for tries in xrange(maxtries):
err = fn(x) - value
if abs(err) < maxerr:
return x
slope = dx(fn, x)
x -= err/slope
raise ValueError('no solution found')
Hay un montón de posibles problemas aquí - la búsqueda de una partida buena valor de x, suponiendo que la función tiene en realidad una solución (es decir, no hay respuestas de valor real a x^2 + 2 = 0), golpear los límites de la precisión de cálculo, etc, pero en este caso, la función de minimización de errores es adecuado y conseguir un buen resultado:
solve(my_func, 16) # returns (x =) 5.000000000000496
Tenga en cuenta que esta solución no es absolutamente , exactamente correcta. Si necesita que sea perfecto, o si quiere intentar resolver familias de ecuaciones analíticamente, debe recurrir a una bestia más complicada: un solucionador simbólico.
Un solucionador simbólico, como Mathematica o Maple, es un sistema experto con muchas reglas incorporadas ("conocimiento") sobre álgebra, cálculo, etc. "sabe" que la derivada de sin es cos, que la derivada de kx^p es kpx^(p-1), y así sucesivamente. Cuando le das una ecuación, trata de encontrar una ruta, un conjunto de aplicaciones de reglas, desde donde está (la ecuación) hasta donde quieres estar (la forma más simple posible de la ecuación, que es la solución) .
Su ecuación de ejemplo es bastante simple; una solución simbólica podría ser:
=> LHS([6, 2]) RHS([16])
# rule: pull all coefficients into LHS
LHS, RHS = [lh-rh for lh,rh in izip_longest(LHS, RHS, 0)], [0]
=> LHS([-10,2]) RHS([0])
# rule: solve first-degree poly
if RHS==[0] and len(LHS)==2:
LHS, RHS = [0,1], [-LHS[0]/LHS[1]]
=> LHS([0,1]) RHS([5])
y no es la solución: x = 5.
espero que esto le da el sabor de la idea; los detalles de la implementación (encontrar un conjunto bueno y completo de reglas y decidir cuándo se debe aplicar cada regla) pueden consumir fácilmente muchos años-hombre de esfuerzo.
Quiero un automóvil que tenga de 0 a 60 en 4.5 segundos y obtenga 45 MPG. Tal vez podrías considerar eliminar el requisito de Python simple y usar librerías externas –
. Si quieres resolver cualquier ecuación, tendrás que construir tu propia biblioteca. Además, 4.5 segundos no es lo suficientemente rápido para este ejemplo: D – jamylak
¿Los problemas siempre se verán como 'resolver y = mx + c para x'? –