scipy 优化:如何让它与只有可选参数的函数一起工作?

scipy optimize: how to make it work with a function that has only optional arguments?

提问人:J-J-J 提问时间:10/10/2023 最后编辑:J-J-J 更新时间:10/10/2023 访问量:53

问:

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

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

此函数的目的是最终找到根,即求解一个参数,而其他两个参数是已知的,例如结果等于 0。

如果我想使用 scipy 的 fsolve 函数来求解 , when 和 are known,这不是问题:abc

>>> 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

当然,“愚蠢”的解决方案是创建三个不同的函数来考虑所有可能的用例(何时未知、何时未知以及何时未知),但对我来说,这似乎不是一个非常有效的方法。此外,我将来可能会遇到类似的问题,因为函数的参数比这多得多。abc

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

python scipy scipy-optimize 命名参数 fsolve

评论


答:

2赞 Seon 10/10/2023 #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)

评论

0赞 J-J-J 10/10/2023
感谢您抽出宝贵时间回答。我不确定 in 来自哪里,它会抛出“名称'f'未定义”错误。如果我用 替换它,我会得到与之前相同的错误(“func() 为参数 'a' 获得了多个值”)。值得一提的是,我使用 Python 3.10.2 和 scipy 1.10.1。fpartial(f, **dat)func
1赞 Seon 10/10/2023
我最初的答案根本不起作用,我已经完全重写了它。
0赞 J-J-J 10/10/2023
太棒了,感谢您抽出宝贵时间对此进行调查!