我有一个二维高斯函数f(x,y).我知道函数的峰值g₀所在的值x₀y₀.但是我想找出xₑyₑ的值.我知道有多种解决方案,但至少有一个就足够了.

到目前为止,我已经

def f(x, y, g0,x0,y0,sigma_x,sigma_y,offset):
    return offset + g0* np.exp(-(((x-x0)**(2)/(2*sigma_x**(2))) + ((y-y0)**(2)/(2*sigma_y**(2)))))

All variables taken as parameters are known个,因为它们是从曲线拟合中提取出来的.

我明白,取x的导数,设置f() = 0,类似地,取y的导数,得到(x,y)的可解线性系统,但这似乎有点过分,手动实现,一定有一些库或工具可以实现我正在try 实现的目标?

推荐答案

有无限多的可能性(或者可能是1个微不足道的可能性,或者在关于值g0的特殊情况下没有).使用直接方法,解决方案可以是computed analytically in constant time.不需要近似或迭代方法来寻找给定函数的根.这只是一个纯粹的数学问题.

高斯核有有趣的symmetries.其中之一是峰值平移到(0,0)时的旋转不变性.另一个原因是,二维高斯曲面的一维截面是一条高斯曲线.

让我们暂时忽略offset:它并没有真正改变问题(它只是一个Z轴平移),并为分辨率添加了额外的无用术语.

IS问题的几何解是ellipse,因此解(xe, ye)遵循conic expression:(xe-x0)² / a² + (ye-y0)² / b² = 1.如果为sigma_x = sigma_y,则解决方案更简单:这是一个具有表达式(xe-x0)² + (ye-y0)² = r的圆.注意,abr依赖于搜索值和核参数(例如,sigma_x).改变sigma_xsigma_y就像拉长了空间,所以解决方案也是一样的.改变x0y0就像是转换空间,所以解决方案也是如此.

事实上,我们可以解决更简单的情况,即x0=0y0=0sigma_x=1sigma_y=1.然后我们可以应用平移,然后使用变换矩阵进行线性变换.基本的乘法4x4矩阵就可以做到这一点.由于需要考虑的参数较少,因此解决较简单的情况要容易得多.实际上,g0offset也可以从f中go 掉一部分,因为它在表达式的两边,我们只需要解线性方程offset + g0 * h(xe,ye) = g0 / e,所以h(x,y) = 1 / e - offset / g0,其中h(xe, ye) = exp(-(xe² + ye²)/2).假设我们暂时忘记平移和线性变换,这个问题就可以很容易地解决:

h(xe, ye) = 1 / e - offset / g0
exp(-(xe² + ye²)/2) = 1 / e - offset / g0
-(xe² + ye²)/2 = ln(1 / e - offset / g0)
xe² + ye² = -2 * ln(1 / e - offset / g0)

就这样!我们得到了半径r-2*ln(1 / e - offset / g0)的圆的表达式!请注意,表达式中的ln基本上是自然对数.

现在我们可以试着找出4x4矩阵系数,或者实际上试着直接求解完整的表达式,这最终不是那么困难.

offset + g0 * exp(-((x-x0)²/(2*sigma_x²) + (y-y0)²/(2*sigma_y²))) = g0 / e
exp(-((x-x0)²/(2*sigma_x²) + (y-y0)²/(2*sigma_y²))) = 1 / e - offset / g0
-((x-x0)²/(2*sigma_x²) + (y-y0)²/(2*sigma_y²)) = ln(1 / e - offset / g0)
((x-x0)²/sigma_x² + (y-y0)²/sigma_y²)/2 = -ln(1 / e - offset / g0)
(x-x0)²/sigma_x² + (y-y0)²/sigma_y² = -2 * ln(1 / e - offset / g0)

就这样!我们得到了二次曲线表达式,其中r = -2 * ln(1 / e - offset / g0)是一个常数,a = sigma_xb = sigma_y是上面表达式中的未知参数.它可以用a = sigma_x/sqrt(r)b = sigma_y/sqrt(r)来归一化,所以右边是1,正好符合上面的表达式,但这只是一些数学细节.

你可以很容易地找到椭圆的一点,因为你知道椭圆(x0, y0)的中心,并且在y=y0直线和上面的圆锥表达式的交点处至少有一个点.让我们找到它:

(x-x0)²/sigma_x² + (y0-y0)²/sigma_y² = -2 * ln(1 / e - offset / g0)
(x-x0)²/sigma_x² = -2 * ln(1 / e - offset / g0)
(x-x0)² = -2 * ln(1 / e - offset / g0) * sigma_x²
x = sqrt(-2 * ln(1 / e - offset / g0) * sigma_x²) + x0

请注意,有两个解决方案(-sqrt(...) + x0),但您只需要其中一个.我希望我在计算中没有犯任何错误(至少细节应该足以很容易地找到它),在您的情况下,解决方案不是一个复数.这个解决方案的好处是它是very very fast to compute.

The final solution is:
(xe, ye) = (sqrt(-2*ln(1/e-offset/g0)*sigma_x²)+x0, y0)

Python相关问答推荐

Odoo 14 hr. emergency.public内的二进制字段

抓取rotowire MLB球员新闻并使用Python形成表格

Pandas 有条件轮班操作

海运图:调整行和列标签

为什么这个带有List输入的简单numba函数这么慢

如何在turtle中不使用write()来绘制填充字母(例如OEG)

Django—cte给出:QuerySet对象没有属性with_cte''''

解决调用嵌入式函数的XSLT中表达式的语法移位/归约冲突

matplotlib + python foor loop

如何在Python 3.9.6和MacOS Sonoma 14.3.1下安装Pyregion

一个telegram 机器人应该发送一个测验如何做?""

Python OPCUA,modbus通信代码运行3小时后出现RuntimeError

为什么我只用exec()函数运行了一次文件,而Python却运行了两次?

我如何处理超类和子类的情况

Match-Case构造中的对象可调用性测试

来自任务调度程序的作为系统的Python文件

如何在不遇到IndexError的情况下将基数10的整数转换为基数80?

使用Django标签显示信息

401使用有效的OAuth令牌向Google Apps脚本Web App发出POST请求时出现未经授权的错误(";

保存由PYTHON在EXCEL中所做更改的问题