fsolve всегда возвращает предположение / оценку - PullRequest
5 голосов
/ 19 декабря 2011

Я впервые использую функцию scipy optimize.fsolve, чтобы найти корни уравнения.Проблема в том, что любое число, которое я использую в качестве значения догадки / оценки, является тем, что я получаю в качестве ответа (с точностью до 8 знаков после запятой).При использовании full_output = True я получаю флаг выхода равным 1, что должно означать, что «решение сходится», что, насколько я понимаю, должно означать, что результат действительно является корнем уравнения.

Я знаю, что существует конечное число различных корней (которые разнесены), как, когда я строю график уравнения, я могу их видеть.Кроме того, fsolve завершается с ошибкой (выдает ошибки с флагами выхода), когда я ввожу начальную точку в диапазон, который должен возвращать неопределенные значения (делим на ноль, квадратный корень из отрицательного значения).Но помимо этого он всегда возвращает начальную точку как корень.

Я протестировал fsolve с очень простым уравнением, и оно работало нормально, поэтому я знаю, что импортирую все, что мне нужно, и должен правильно использовать fsolve.Я также попытался возиться с некоторыми входными аргументами, но я не очень хорошо понимаю их, и, похоже, ничего не изменилось).

Ниже приведен соответствующий код (E - единственная переменная, все остальное имеетненулевое значение):

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)

, который просто выводит «3» и говорит «Решение сходится», даже если ближайшие решения должны быть на уровне около 2,8 и 4,7.

Кто-нибудь есть идеи, как это исправить и получить правильный ответ (с помощью fsolve)?

Ответы [ 2 ]

6 голосов
/ 19 декабря 2011

Я думаю, что ваше уравнение не делает то, что вы думаете, что оно делает.Во-первых, когда я пробую это, это не возвращает предположение;он возвращает число близко к предположению.Это очень нестабильно, и это, кажется, сбивает с толку fsolve.Например:

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

Это не 5. Это даже не 5 в точности станка.Это также не корень уравнения:

>>> func(5.00000079)
2114979.3239706755

Но поведение уравнения в любом случае довольно непредсказуемо:

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

Так что, очевидно, где-то там проходит пересечение нуля.Я бы сказал, внимательно посмотрите на ваше уравнение.Убедитесь, что вы указали аргумент tan в радианах, например.

1 голос
/ 19 декабря 2011

Вы пытались изменить свою функцию на что-то действительно тривиальное? Как это:

#!/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)

Для меня приведенный выше код сходится туда, где и должен.

Кроме того, в предоставленном вами коде --- что такое c_str и V_0? Если на самом деле ваша функция зависит от нескольких переменных и вы рассматриваете все из них, кроме одной, как постоянные параметры, то используйте аргумент args в fsolve, например:

#!/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) 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...