Python找到非零级别的根

时间:2015-01-26 13:09:34

标签: python numpy scipy solver

说我有以下代码

def myfunc(x):
    return monsterMathExpressionOf(x)

我希望在数字上找到myfunc(x) == yy的不同值的解决方案。如果y == 0那么有很多根查找程序可用,例如从scipy。但是,如果我想找到解决方案,例如y==1似乎我必须定义一个新函数

def myfunc1(x):
    return myfunc(x) - 1

然后使用可用的程序找到它的root。这种方式对我不起作用,因为我需要通过运行循环找到很多解决方案,而且我不想在循环的每个步骤中重新定义函数。有更整洁的解决方案吗?

2 个答案:

答案 0 :(得分:2)

您不必为y的每个值重新定义函数:只需定义y的单个函数,该函数返回x的函数,并使用该函数在你的循环中:

def wrapper(y):
    def myfunc(x):
        return monsterMathExpressionOf(x) - y
    return myfunc

for y in y_values:
    f = wrapper(y)
    find_root(f, starting_point, ...)

您也可以使用functools.partial,这可能更符合您的喜好:

def f(x, y):
    return monsterMathExpressionOf(x) - y

for y in y_values:
    g = partial(f, y=y)
    find_root(g, starting_point, ...)

阅读文档,了解partial如何在幕后粗略实施;您会发现与第一个wrapper实施相比,它可能没有太大差异。

答案 1 :(得分:1)

@Evert的回答显示了如何使用closure或使用functools.partial来完成此操作,这两者都是很好的解决方案。

许多数值求解器提供了另一种替代方案。例如,考虑scipy.optimize.fsolve。该函数提供args参数,允许您将其他固定参数传递给要解决的函数。

例如,假设myfunc是x ** 3 + x

def myfunc(x):
    return x**3 + x

定义一个包含参数y作为参数的附加函数:

def myfunc2(x, y):
    return myfunc(x) - y

要解决,比如myfunc(x) = 3,你可以这样做:

from scipy.optimize import fsolve

x0 = 1.0  # Initial guess

sol = fsolve(myfunc2, x0, args=(3,))

您可以使用匿名函数作为myfunc2的第一个参数,而不是定义fsolve

sol = fsolve(lambda x, y: myfunc(x) - y, x0, args=(3,))

但是你可以用

完成同样的事情
sol = fsolve(lambda x: myfunc(x) - 3, x0)