scipy 优化:如何使其与仅具有可选参数的函数一起工作?

问题描述 投票:0回答:1

假设我有以下功能(非常简化,以解释问题的要点):

def func(a=None, b=None, c=None):    
    return 100-(a+b*c)

这个函数的目的最终是求根,即在已知另外两个参数的情况下,求解一个参数,比如结果等于0。

如果我想使用 scipy 的 fsolve 函数来求解

a
,当
b
c
已知时,这不是问题:

>>> from scipy import optimize
>>> dat = {"b":1, "c":2}
>>> optimize.fsolve(lambda x: func(x, **dat), x0=0)

array([98.])

如果我想求解任何不在第一个位置的参数(例如

c
),它就会成为一个问题:

>>> dat = {"a":1, "b":2}
>>> optimize.fsolve(lambda x: func(x, **dat), x0=0)

TypeError: func() got multiple values for argument 'a'

我猜解决方案是将具有

None
值的参数设置为固定的“第一位置”参数,但我不知道如何做到这一点,或者是否可能。

当然,“愚蠢”的解决方案是创建三个不同的函数来考虑所有可能的用例(当

a
未知时、当
b
未知时以及当
c
未知时),但它对我来说这似乎不是一个非常有效的方法。此外,我将来可能会遇到类似的问题,因为函数的参数比这多得多。

当然,单个参数可以设置为

None
,但我单独处理这个问题,所以我们可以假设总是有一个未知值——唯一的问题是这个未知值的参数可以是任何参数之一。我希望能够“告诉”scipy 求解这个
None
值,无论其参数的位置如何。

python scipy scipy-optimize named-parameters fsolve
1个回答
1
投票

我们将定义一个名为

get_partial
的函数,它接受一个函数和一个您想要冻结的关键字参数的字典。然后它将返回一个新函数,该函数将剩余的关键字参数作为位置参数。

functools.partial
在这里并不能完全完成工作:它确实允许您冻结除一个之外的所有关键字参数,但它不会将最后一个关键字参数转换为位置参数。

import inspect
from scipy import optimize

def get_partial(f, fixed_kwargs):
    all_kwargs = inspect.signature(f).parameters.keys()
    bound_kwargs = fixed_kwargs.keys()
    free_kwarg = (all_kwargs - bound_kwargs).pop()
    return lambda x: f(**(fixed_kwargs | {free_kwarg: x}))

def func(a=None, b=None, c=None):
    return 100 - (a + b * c)

dat = {"a": 1, "b": 2}

optimize.fsolve(get_partial(func, dat), x0=0)
© www.soinside.com 2019 - 2024. All rights reserved.