2011-12-19 16 views
5

Estoy usando la función scipy's optimize.fsolve por primera vez para encontrar las raíces de una ecuación. El problema es que sea cual sea el número que uso como el valor de adivinar/estimar es lo que obtengo como respuesta (dentro de aproximadamente 8 decimales). Cuando uso full_output = True, obtengo que exitflag sea '1', lo que se supone significa que 'La solución convergió', lo que a mi entender debería significar que la salida es de hecho una raíz de la ecuación.fsolve siempre devolviendo la conjetura/estimación

Sé que hay un número finito de raíces distintas (que están espaciadas), ya que cuando grafico la ecuación puedo verlas. Además, fsolve falla (da error exitflags) cuando ingreso el punto de inicio para estar en un rango que debe devolver valores indefinidos (dividir por cero, raíz cuadrada de un valor negativo). Pero además de eso, siempre devuelve el punto de partida como raíz.

Probé fsolve con una ecuación muy simple y funcionó bien, así que sé que estoy importando todo lo que necesito y debería estar usando fsolve correctamente. También intenté meterme con algunos de los argumentos de entrada, pero no los entiendo muy bien y nada pareció cambiar).

A continuación se muestra el código correspondiente (E es la única variable, todo lo demás tiene un valor distinto de cero):

def func(E): 
    s = sqrt(c_sqr * (1 - E/V_0)) 
    f = s/tan(s) + sqrt(c_sqr - s**2) 
    return f 

guess = 3 
fsolve(func, guess) 

que acaba da salida a '3' y dice que, a pesar de que 'La solución convergente. las soluciones más cercanas deberían estar en alrededor de 2.8 y 4.7.

¿Alguien tiene alguna idea de cómo solucionar esto y obtener una respuesta correcta (usando fsolve)?

+3

Quizás solo sea un buen adivino. –

+0

¿Cuál es el valor de 'V_0'? –

+3

¿Puede proporcionar los valores para 'V_0' y' c_sqr'?Intenté poner 'c_sqr = 100' y' V_0 = 10', y converge correctamente a la raíz 2.90496355. –

Respuesta

6

Creo que su ecuación doesn No hagas lo que crees que hace. Por un lado, cuando lo intento, no devuelve la conjetura; devuelve un número cerrar a la conjetura. Es muy inestable y parece ser confuso fsolve. Por ejemplo:

>>> V_0 = 100 
>>> c_sqr = 3e8 ** 2 
>>> guess = 5 
>>> fsolve(func, guess) 
array([ 5.00000079]) 

Esto no es 5. No es incluso 5 dentro de la precisión de la máquina. Tampoco es una raíz de la ecuación:

>>> func(5.00000079) 
2114979.3239706755 

Pero el comportamiento de la ecuación es bastante impredecible de todos modos:

>>> func(5.0000008) 
6821403.0196130127 
>>> func(5.0000006) 
-96874198.203683496 

Así que, obviamente hay un cruce por cero en algún lugar allí. Yo diría que eche un buen vistazo a su ecuación. Asegúrese de especificar el argumento de tan en radianes, por ejemplo.

+2

gracias, olvidé poner el argumento de bronceado en radianes. – scaevity

1

¿Intentó cambiar su función a algo realmente trivial? De esta manera:

#!/usr/bin/python 
from scipy.optimize import fsolve 

def func(E): 
# s = sqrt(c_sqr * (1 - E/V_0)) 
# f = s/tan(s) + sqrt(c_sqr - s**2) 
    f = E**2 -3. 
    return f 

guess = 9 

sol=fsolve(func, guess) 
print sol, func(sol) 

Para mí el código anterior converge a donde debe.

Además, en el código que ha proporcionado --- ¿qué son c_str y V_0? Si, de hecho, su función depende de más de una variable, y que está tratando a todos ellos excepto uno, como parámetros constantes, a continuación, utilizar el argumento de la args fsolve, así:

#!/usr/bin/python 
from scipy.optimize import fsolve 
from numpy import sqrt 

def func(E,V_0): 
    #s = sqrt(c_sqr * (1 - E/V_0)) 
    #f = s/tan(s) + sqrt(c_sqr - s**2) 
    f = E**2 -V_0 
    return f 

VV=4. 
guess = 9 
sol=fsolve(func, guess, args=(VV)) 

print sol, func(sol,VV)