说我有以下代码
def myfunc(x):
return monsterMathExpressionOf(x)
我希望在数字上找到myfunc(x) == y
对y
的不同值的解决方案。如果y == 0
那么有很多根查找程序可用,例如从scipy。但是,如果我想找到解决方案,例如y==1
似乎我必须定义一个新函数
def myfunc1(x):
return myfunc(x) - 1
然后使用可用的程序找到它的root。这种方式对我不起作用,因为我需要通过运行循环找到很多解决方案,而且我不想在循环的每个步骤中重新定义函数。有更整洁的解决方案吗?
答案 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)