point of intersection 2 normal curves

落花浮王杯 提交于 2019-12-09 04:58:58

问题


Although I think this is a basic question, I can't seem to find out how to calculate this in R:

the point of intersection (I need the x-value) of 2 or more normal distributions (fitted on a histogram) which have for example the following parameters:

d=data.frame(mod=c(1,2),mean=c(14,16),sd=c(0.9,0.6),prop=c(0.6,0.4))

With the mean and standard deviation of my 2 curves, and prop the proportions of contribution of each mod to the distribution.


回答1:


You can use uniroot:

f <- function(x) dnorm(x, m=14, sd=0.9) * .6 - dnorm(x, m=16, sd=0.6) * .4

uniroot(f, interval=c(12, 16))

$root
[1] 15.19999

$f.root
[1] 2.557858e-06

$iter
[1] 5

$estim.prec
[1] 6.103516e-05


ETA some exposition:

uniroot is a univariate root finder, ie given a function f of one variable x, it finds the value of x that solves the equation f(x) = 0.

To use it, you supply the function f, along with an interval within which the solution value is assumed to lie. In this case, f is just the difference between the two densities; the point where they intersect will be where f is zero. I got the interval (12, 16) in this example by making a plot and seeing that they intersected around x=15.




回答2:


Sorry, but the accepted answer is not good. See also: intersection of two curves in matlab

You can get both roots using a function like this:

intersect <- function(m1, s1, m2, s2, prop1, prop2){

B <- (m1/s1^2 - m2/s2^2)
A <- 0.5*(1/s2^2 - 1/s1^2)
C <- 0.5*(m2^2/s2^2 - m1^2/s1^2) - log((s1/s2)*(prop2/prop1))

(-B + c(1,-1)*sqrt(B^2 - 4*A*C))/(2*A)
}

in your case:

> intersect(14,0.9,16,0.6,0.6,0.4)
[1] 20.0 15.2



回答3:


I agree with @Flounderer that you should calculate both roots, but the offered function is incomplete. When s1 = s2, A becomes zero and Inf and NaN are produced.

A slight modification completes the function:

intersect <- function(m1, sd1, m2, sd2, p1, p2){

  B <- (m1/sd1^2 - m2/sd2^2)
  A <- 0.5*(1/sd2^2 - 1/sd1^2)
  C <- 0.5*(m2^2/sd2^2 - m1^2/sd1^2) - log((sd1/sd2)*(p2/p1))

  if (A!=0){
    (-B + c(1,-1)*sqrt(B^2 - 4*A*C))/(2*A)
  } else {-C/B}
} 
m1=0; sd1=2; m2=2.5; sd2=2; p1=.8; p2=.2
(is=intersect(m1,sd1,m2,sd2,p1,p2))

xs = seq(-6, 6, by=.01)
plot(xs, p1*dnorm(xs, m1, sd1), type= 'l')
lines(xs, .2*dnorm(xs, m2,sd2))
abline(v=is)

A general solution is also found using uniroot.all:

library(rootSolve)
f <- function(x, m1, sd1, m2, sd2, p1, p2){
  dnorm(x, m1, sd1) * p1 - dnorm(x, m2, sd2) * p2 }
uniroot.all(f, lower=-6, upper=6, m1=m1, sd1=sd1, m2=m2, sd2=sd2, p1=p1, p2=p2)


来源:https://stackoverflow.com/questions/16982146/point-of-intersection-2-normal-curves

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!