0

I'm having a hard time finding an R function that does what I want. Suppose I have two uniform distributions, A~U[alow,ahigh] and B~U(blow,bhigh).

There's a random variable Z=A-B, the difference between these two uniform distributions. I need a function CDF function for the distribution of Z.

I'd give this function a cutoff value x, and it would return the probability that Z was below the cutoff.

I'm in R, and the function call would ideally look something like this:

UniformDiffCDC(alow,ahigh,blow,bhigh,cutoff)

Unfortunately I don't know where to begin, or whether this has already been implemented in R somewhere. Help!

ABC
  • 133
  • 5

2 Answers2

2

The basic idea is that the probability density function will form a trepezoid. I don't know of any built in functions for this because it's not a very common distribution, but using a bit of geometry you can solve for the values exactly.

UniformDiffCDF <- Vectorize(function(alow,ahigh,blow,bhigh,cutoff) {
  breaks <- c(alow-bhigh, ahigh-bhigh, alow-blow, ahigh-blow)
  height <- 2/sum(breaks * c(-1, -1, 1, 1))
  if (cutoff > breaks[4]) return(1) 
  prob <- 0
  if (cutoff < breaks[1]) return(prob) 
  if (cutoff < breaks[2]) {
    prob <- prob + 1/2 * (cutoff - breaks[1]) * approx(breaks[1:2], c(0, height), cutoff)$y
    return(prob)
  } else {
    prob <- prob + 1/2 * (breaks[2]-breaks[1]) * height
  }
  if (cutoff < breaks[3]) {
    prob <- prob + (cutoff-breaks[2])*height
    return(prob)
  } else {
    prob <- prob + (breaks[3]-breaks[2])*height
  }
  tri <- 1/2 * (breaks[4]-breaks[3]) * height
  prob <- prob + tri - 1/2 * (breaks[4]- cutoff) * approx(breaks[4:3], c(0,height), cutoff)$y
  return(prob)  
}, vectorize.args="cutoff")

So for example

curve(UniformDiffCDF(5,7,2,6, x), from=-2, to=6)

different of uniforms CDF

The corresponding PDF would be

UniformDiffPDF <- Vectorize(function(alow,ahigh,blow,bhigh,cutoff) {
  breaks <- c(alow-bhigh, ahigh-bhigh, alow-blow, ahigh-blow)
  height <- 2/sum(breaks * c(-1, -1, 1, 1))
  if (cutoff > breaks[4]) return(0)
  if (cutoff < breaks[1]) return(0) 
  if (cutoff < breaks[2]) {
    return(approx(breaks[1:2], c(0, height), cutoff)$y)
  }
  if (cutoff < breaks[3]) {
    return(height)
  }
  return(approx(breaks[4:3], c(0,height), cutoff)$y)
}, vectorize.args="cutoff")

difference of uniforms PDF

MrFlick
  • 195,160
  • 17
  • 277
  • 295
  • This is great. However, I'm surprised to see this has any curvature since the PDF is all lines! Should I not be surprised for some reason? – ABC Mar 03 '21 at 00:25
  • Well, consider the straight line `y=2x` like it's a PDF, when in integrate that function to get the area under the curve you get `x^2+c` So you get curves when you integrate a under a straight line. Hopefully this isn't too surprising. This is just basic calculus stuff. – MrFlick Mar 03 '21 at 00:32
  • HAH. Yes, you're right and I should have thought about that. – ABC Mar 03 '21 at 00:38
1

Something like this?

   UniformDiffCDF <- function(alow,ahigh,blow,bhigh,cutoff,n=10000){
        a = runif(n,min=alow,max=ahigh)
        b = runif(n,min=blow,max=bhigh)
        z = (a-b)
        p = sum(z < cutoff)/n
        return(p)
}
jsv
  • 740
  • 3
  • 5
  • 1
    Given that this problem has a relatively straightforward exact solution, it seems like approximation isn't needed. However this could be a good way to help verify an exact solution. – Robert Dodier Mar 02 '21 at 20:57