查找高斯分布的交集

时间:2018-08-25 21:36:39

标签: matlab gaussian

如何在MATLAB中找到高斯混合分布相交的所有点? enter image description here

1 个答案:

答案 0 :(得分:2)

您问题的一般类别是找到两条曲线的交点,这是一项可管理但不平凡的任务(最困难的部分是确保捕获所有交点)。

但是您的问题是非常特定的:您正在寻找两个高斯的交集。这非常好:我们都有一个用于您的函数的解析公式,并且可以确保只有两个交集,除非您的某些参数相同。*

让我们假设您的分布以mu1mu2和规模sigma1sigma2为特征。然后由函数定义您在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

上面的意思是两个高斯在点x1x2的值在机器精度内彼此相等,这与任何数值答案都一样好。


*我最初声称,只要高斯不完全相同,我们总是有两个交点。显然,如果均值和方差相同,则我们有两条简并曲线,交点变得毫无意义。但是,与Cris Luengo pointed out in a comment一样,可能只有一个交叉点:当方差相同且均值不同时(即,我们有两条形状完全相同的曲线沿x移动)。在这种情况下,a=0的对应方程为b*x + c == 0,从而使我们得到x0 = -c/b的交点。因此,更精确(但有点伪编码)的答案(给定abc)是

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);