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

How do you use the **kwargs argument in mpmath.findroot?

我试图在 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 函数 returns $f(x) = ax^2 + 1$ 在 $x$ 值处的值,给定 $a$ 的值.例如,对于 $a = 1$,$f(1)$ 的值为 2。为了求 $f$ 的根,我使用了 findroot。因为我的函数有参数,所以我需要在 findroot 中使用 **kwargs。但是,我正在努力使用它。我不断收到语法错误。

语法错误

分配 **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

实际问题

查看文档,似乎 求解器 可以接受您传递的任何 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')

您可以通过 return 一个新的函数对象 来实现 function_builder(),它只是 x 的一个函数。然后当你想找到一个特定多项式的根时,你可以用你想要的任何参数调用 function_builder(),它会 return 你想要的函数,然后 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)

等等