这是我的最小工作示例。这很简单,我基本上得到了一个密度值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)
这会引发以下错误
类型错误:fsolve:'func'参数'func`的输入和输出形状不匹配。形状应该是(2,(,但它是(1,(。
root
的文档表明,fun
是
一个向量函数,用于查找的根。
我想他们的意思是有趣的是来自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)
此外,我建议使用另一个初始猜测。在我看来,你的例子有很多可能的解决方案,所以要注意这一点。