在mpmath.findroot中如何使用**kwargs参数?

3

我正在尝试使用 mpmath 中的 findroot 寻找具有许多参数的函数的根,但在这个问题中,我将使用一个简单的函数。

from mpmath import mp


def func(x, **parameters):

 return parameters["a"]*x*x + 1
   

solution = mp.findroot(f = func, x0 = 0.955j, solver = 'muller', **kwargs = (a = 1))

输出:

SyntaxError: invalid syntax

代码中的func函数根据给定的$a$值,返回$f(x) = ax^2 + 1$在$x$处的函数值。例如,当$a=1$时,$f(1)$的值为2。为了找到$f$的根,我使用了findroot。由于我的函数有参数,所以我需要在findroot中使用**kwargs。然而,我一直在努力使用它,但却遇到了语法错误。请注意保留HTML标签。

提醒一下,很遗憾在 Stack Overflow 上无法渲染 LaTeX。 - ddejohn
**kwargs** 只是 verbose 后面的其他可选参数的简写。例如 verifysolver 等等。请参阅 https://mpmath.org/doc/current/calculus/optimization.html 的 arguments 列表。 - hpaulj
1个回答

3

语法错误

语法错误出现在赋值语句**kwargs = 中。变量kwargs是一个字典,而**会将该字典解包。**kwargs = (a = 1)这个表达式实际上是试图在解包字典的同时将该字典分配给另一个变量

关键字参数

函数的**kwargs参数允许你传递任意数量的额外关键字参数。参数a=1本身就是一个关键字参数。而kwargs则是一组希望“打包在一起”的关键字参数。

下面是一个快速演示:

In [1]: def print_kwargs(**kwargs):
   ...:     for key, value in kwargs.items():
   ...:         print(key, value)
   ...:

In [2]: print_kwargs(a=1, b=2, c=3)
a 1
b 2
c 3

In [3]: params = dict(a=1, b=2, c=3)

In [4]: print_kwargs(**params)
a 1
b 2
c 3

实际问题

从文档来看,solver允许接受你传递的任何kwargs。换句话说,kwargs不会传递给你的函数 func,而是传递给了求解器'muller'

文档很糟糕,就我所看到的,mpmath.calculus.optimization.Muller使用的kwargs没有任何说明,因此我不知道它如何处理关键字参数,但重点是kwargs未被像您预期的那样传递给您的函数。

不幸的是,如果您希望函数func成为可以接受其参数的动态多项式,则需要进行更多工作。

解决方案

以下是您可以采取的措施:

def function_builder(**params):
    def func(x):
        return params["a"] * x**2 + 1  # or whatever function
    return func

然后你需要执行:

>>> params = dict(a=1)
>>> func = function_builder(**params)
>>> mp.findroot(f=func, x0=0.955j, solver='muller')
mpc(real='0.0', imag='1.0')

您可以这样实现 function_builder():返回一个仅针对 x 的新函数对象。然后,当您想要找到特定多项式的根时,可以使用任何参数调用 function_builder(),它将返回所需的函数,mp.findroot 然后可以使用它。

注释

以下是如何实现通用二次方程构建器的示例:

def quadratic_builder(**params):
    a, b, c = params["a"], params["b"], params["c"]
    def f(x):
        return a * x**2 + b * x + c
    return f

当然,对于像二次方程这样具体的东西,最好明确地调用关键字参数:
def quadratic_builder(*, a, b, c):
    def f(x):
        return a * x**2 + b * x + c
    return f

然后,您可以将系数的“集合”打包在一起:

coefs_1 = dict(a=1, b=3, c=-5)
coefs_2 = dict(a=-2, b=1, c=0)
coefs_3 = dict(a=-6, b=8, c=3)

f1 = quadratic_builder(**coefs_1)
f2 = quardatic_builder(**coefs_2)
f3 = quardatic_builder(**coefs_3)

Etc.


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接