matlab - 寻找高斯分布的交点
解决方案
您问题的一般类别是找到两条曲线的交点,这是一项易于管理但并非微不足道的任务(最难的部分是确保您抓住所有交点)。
但是您的问题非常具体:您正在寻找两个高斯的交集。这非常好:我们都为您的函数提供了一个解析公式,并且可以保证只有两个交点,除非您的某些参数相同。*
让我们假设您的分布以均值mu1
和mu2
尺度sigma1
为特征sigma2
。然后你的高斯位置x
由函数定义
1/sqrt(2*pi*sigma^2) * exp(-(x-mu)^2/2/sigma^2)
事实证明,我们可以x
在纸上完全解决这个方程:
1/sqrt(2*pi*sigma1^2)*exp(-(x-mu1)^2/2/sigma1^2) == 1/sqrt(2*pi*sigma2^2)*exp(-(x-mu2)^2/2/sigma2^2)
sigma2/sigma1 == exp((x-mu1)^2/2/sigma1^2) * exp(-(x-mu2)^2/2/sigma2^2)
log(sigma2/sigma1) == (x-mu1)^2/2/sigma1^2) - (x-mu2)^2/2/sigma2^2
ax^2 + bx + c == 0
这导致抛物线方程
a = 1/(2*sigma1^2) - 1/(2*sigma2^2);
b = mu2/(sigma2^2) - mu1/(sigma1^2);
c = mu1^2/(2*sigma1^2) - mu2^2/(2*sigma2^2) - log(sigma2/sigma1);
很容易证明D = b^2 - 4 a c
判别式是非负的,所以当参数不退化时,方程确实有两个实根。所以这两个交点是,具有上述定义,
D = b^2 - 4 * a * c;
x1 = (-b + sqrt(D))/(2*a);
x2 = (-b - sqrt(D))/(2*a);
使用两个具有伪随机参数的高斯函数:
% define parameters and Gaussian
mu1=1; sigma1=3; mu2=2; sigma2=4;
% intersections
a = 1/(2*sigma1^2) - 1/(2*sigma2^2);
b = mu2/(sigma2^2) - mu1/(sigma1^2);
c = mu1^2/(2*sigma1^2) - mu2^2/(2*sigma2^2) - log(sigma2/sigma1)
D = b^2 - 4 * a * c;
x1 = (-b + sqrt(D))/(2*a);
x2 = (-b - sqrt(D))/(2*a);
只是为了证明上面的交点是正确的:
>> f = @(x,mu,sigma) 1/sqrt(2*pi*sigma^2) * exp(-(x-mu).^2/2/sigma^2);
>> f(x1,mu1,sigma1) - f(x1,mu2,sigma2)
ans =
2.7756e-17
>> f(x2,mu1,sigma1) - f(x2,mu2,sigma2)
ans =
1.0408e-17
以上意味着两个高斯在点x1
和x2
在机器精度范围内彼此相等,这与任何数字答案一样好。
*我最初声称只要高斯不完全相同,我们总是有两个交点。显然,如果均值和方差都相同,我们就会有两条退化曲线,并且交点变得毫无意义。但正如Cris Luengo 在评论中指出的那样,可能只有一个交集:当方差相同且均值不同时(即我们有两条形状完全相同的曲线沿移动x
)。在这种情况下a=0
,相应的方程是b*x + c == 0
,给出了我们x0 = -c/b
的交集。所以一个更准确(但有点伪代码)的答案(给定和a
)是b
c
if a == 0 % or allow some tolerance... <=> sigma1 == sigma2
if b == 0 % or allow some tolerance... <=> mu1 == mu2
% degenerate curves: a == b == c == 0, f1(x)==f2(x) for all x
disp('curves are degenerate...')
else
% single intersection: mu1 ~= mu2
x1 = -c/b;
end
else
% two intersections; both parameters are different
D = b^2 - 4 * a * c;
x1 = (-b + sqrt(D))/(2*a);
x2 = (-b - sqrt(D))/(2*a);
推荐阅读
- java - 带有静态内部类的 Java 新关键字
- css - 通过 CSS 相对于自身缩放图像,但保持周围元素的流动?
- c# - 在 cygwin 终端上使用 c# 代码调用时,Shellscript 未在生产服务器上执行
- svg - 如何使用 CoreGraphics 渲染到 MTLTexture
- debugging - 如何在使用 IDA pro 通过 rundll32 调试 DLL 时指定导出函数的参数?
- docker - 错误:服务“大型机”未能构建:ibmcom/db2express-c 的拉取访问被拒绝,存储库不存在或可能需要“docker 登录”
- c - 用于更改 git credential-osxkeychain 的 Zsh 别名
- cuda - __host__ __device__ 函数调用重载函数
- regex - 如何在重复捕获组中捕获每个组的组号
- activemq-artemis - ActiveMQ Artemis + JGroups + 出现 OutOfMemory 错误