Как использовать функцию Ньютона для поиска корня пакета оптимизации Scipy - PullRequest
0 голосов
/ 08 февраля 2012

Я хочу использовать функцию newton, загруженную как

from scipy.optimize import newton

, чтобы найти нули функции, введенной пользователем.Я пишу сценарий, который сначала просит пользователя указать функцию вместе с ее первой производной, а также отправную точку алгоритма.Прежде всего, набрав help(newton) Я увидел, какие параметры принимают функцию и относительное объяснение:

newton(func, x0, fprime=None, args=(), tol=1.48e-08, maxiter=50)

func : function
    The function whose zero is wanted. It must be a function of a
    single variable of the form f(x,a,b,c...), where a,b,c... are extra
    arguments that can be passed in the `args` parameter.

Каким образом я должен передать свою функцию?Если я использую для func, например, x**3 (и его первой производной), ответ будет NameError: name 'x' is not defined.В интернете я обнаружил, что сначала я должен определить свою функцию и ее первую производную и передать имена в качестве параметров.Таким образом, я сделал следующее

fie = raw_input('Enter function in terms of x (e.g. x**2 - 2*x). F= ')
dfie = raw_input('Enter first derivative of function above DF = ')
x0 = input('Enter starting point x0 = ')

def F(x,fie):
    y = eval(fie)
    return y 

def DF(x, dfie):
    dy = eval(dfie)
    return dy

print newton(F,x0,DF)

Но я получаю вывод

    102         for iter in range(maxiter):
    103             myargs = (p0,) + args
--> 104             fder = fprime(*myargs)
    105             if fder == 0:
    106                 msg = "derivative was zero."

TypeError: DF() takes exactly 2 arguments (1 given)

и ту же проблему для F, если опустить DF.Глядя на код в /usr/local/share/src/scipy/scipy/optimize/zeros.py, я вижу, что он оценивает первую производную с fder=fprime(*myargs), поэтому, возможно, мне придется вставить в args что-то, что заставит его работать.Я думал об этом, но решение не приходит ко мне.

1 Ответ

1 голос
/ 08 февраля 2012

Во-первых, имейте в виду, что использование eval делает вашу программу уязвимой для злонамеренных пользователей. Если это не относится, вы можете создать F и DF следующим образом:

F = eval('lambda x :'+fie)
DF = eval('lambda x :'+dfie)

Тогда обе функции ожидают только один аргумент, и вы можете оставить аргумент args пустым.

EDIT. Если вы действительно хотите придерживаться своего кода как можно ближе, это также должно сработать, но мне это не очень приятно. newton отправит одинаковые args обеим функциям.

def F(x,fie,dfie):
    y = eval(fie)
    return y 

def DF(x,fie,dfie):
    dy = eval(dfie)
    return dy

print newton(F,x0,DF,(fie,dfie))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...