Scipy: 用向量输入和标量输出求函数的根

Scipy: Find root of function with vector input and scalar output

这是我的最小工作示例。这很简单,我基本上得到了一个密度值 z,我想找到该轮廓上的任何点。我通过查找根来做到这一点。

import numpy as np
from scipy.stats import multivariate_normal
from scipy.optimize import root

# Define the density
mu = np.zeros(2)
Sigma = np.eye(2)
target = multivariate_normal(mu, Sigma)

# Contour value
z = target.pdf(target.rvs())

# Find a point on its contour
def func(x):
    return target.pdf(x) - z
root(func, mu)

这将引发以下错误

TypeError: fsolve: there is a mismatch between the input and output shape of the 'func' argument 'func'.Shape should be (2,) but it is (1,).

root 的文档说,fun

A vector function to find a root of.

我猜他们的意思是有趣的是从 nDim -> nDim 而不是从 nDim -> 1 的映射。

所以一个选择是两个人为地破坏你的功能来满足这个要求。

def func(x):
    y = target.pdf(x) - z
    return [y] * len(x)

另一种选择是使用 minimize 而不是 root


import numpy as np
from scipy.stats import multivariate_normal
from scipy.optimize import root, minimize

target = multivariate_normal(np.zeros(2), np.eye(2))
z = target.pdf(target.rvs())


def fun_root(x):
    return [target.pdf(x) - z]*2


def fun_minimize(x):
    return (target.pdf(x) - z)**2


x0 = np.random.uniform(low=-1, high=+1, size=2)

res_root = root(fun=fun_root, x0=x0)
print('root')
print(res_root.x)
print(res_root.fun)

print('minimize')
res_min = minimize(fun=fun_minimize, x0=x0, tol=1e-10)
print(res_min.x)
print(res_min.fun)

此外,我建议使用另一个初始猜测。在我看来,您的示例有很多可能的解决方案,因此请注意这一点。