How can we find the decision boundary for two overlapping continuous uniform distribution? Say I have $X \sim \text{CUnif}(a, b)$ and $Y \sim \text{CUnif}(c, d)$. The parameters of $X$ and $Y$ overlap i.e., $a < c < b < d$. 
How can I find a decision boundary in such case? 
I am thinking of taking an arbitrary point (say $x_o$)  as a decision boundary in between $b$ and $c$ and then find the probability of miss classification and then minimizing it. 
 A: If your datum $\alpha$ is $X$ or $Y$ with
probabilities $\pi_X$ and $\pi_Y = 1 - \pi_X$
respectively, and the probability of mis-classification involves $\pi_X$ and $\pi_Y$, then you are a Bayesian and all you need to do is compare the likelihood
ratio $\displaystyle \frac{p_X(\alpha)}{p_Y(\alpha)}$ (which takes on values 
$0,  \frac{d-c}{b-a}, \infty$ depending on the value of 
$\alpha \in [a,d]$ to an appropriate threshold (which I will leave you to
determine), and this can be reduced to a threshold test on the value of
the datum $\alpha$.
A: I would propose Otsu (1979) or NG's (2006) threshold detection algorithms.  They were initially implemented to detect manufacturing defects by testing for significant thresholds in greyscale image pixel intensities however they are decent at detecting thresholds in any histogram.  They do so by identifying the threshold(s) that maximize the across class variance or minimize the within class variance of the data. Both papers are attached here.
NG's approach is a simple extension that adds what the author describes as a valley finding modification.  It simply multiplies the across class variance of any possible threshold by 1 minus the probability of an observation at the threshold. 
The R function below will return the threshold calculated by each method and will produce a histogram like the one displayed showing the threshold if passed a single column data frame.  
###
### NG and OTSU Thresholding of image intensity pixels.
###

threshold <- function(observations, plot=TRUE, otsu=TRUE){
  # Ensure that observations is a data frame.
  observations        <- as.data.frame(observations)
  names(observations) <- c("obs")
  attach(observations)

  # Convert Observation List to Integer then back to Numeric (for histogram)   
  print("Starting Thresholding Algorithm...")

  observations$obs <- as.integer(observations$obs)                            
  observations$obs <- as.numeric(observations$obs)                            
  attach(observations)

  # Produce some image summary variables.
  # Distinct grey scale levels in image.
  levels <- max(obs) - min(obs)
  print(paste("Distribution has", levels," levels..."))

  # Min and Max grey scale values in image.
  minThreshold <- min(obs)
  maxThreshold <- max(obs)-1

  # Number of pixels/voxels in image
  print("Extracting frequencies for each level...")
  obsCount                  <- nrow(obs)
  frequencies               <- hist(obs, breaks=levels, plot=FALSE)
  densityVector             <- as.data.frame(frequencies$density)             #$
  intensity                 <- (minThreshold:maxThreshold)
  intensityFrequency        <- cbind(intensity, densityVector, 1-densityVector)
  names(intensityFrequency) <- c("intensity", "probability", "weight")
  outputArray               <- NULL
  outputArray               <- as.data.frame(outputArray)

  # For every possible threshold value... 
  # Calculate two means, two variances.  
  # IntraClass Variance. And Spit out to an array with Intensity, 
  # and Probability of that intensity
  print(paste("Testing all possible threshold values..."))
  for(i in minThreshold:maxThreshold){
    lowerClassArray <- intensityFrequency[ which(intensity <= i),]
    upperClassArray <- intensityFrequency[ which(intensity > i),]
    lowerClassProb  <- sum(lowerClassArray$probability)                       #$
    upperClassProb  <- sum(upperClassArray$probability)                       #$
    lowerClassArray <- as.data.frame(lowerClassArray)
    upperClassArray <- as.data.frame(upperClassArray)
    lowerClassArray$product <- lowerClassArray$intensity *                    
                               lowerClassArray$probability / lowerClassProb   #$
    upperClassArray$product <- upperClassArray$intensity *                    
                               upperClassArray$probability / upperClassProb   #$
    lowerMu             <- sum(lowerClassArray$product)                       #$
    upperMu             <- sum(upperClassArray$product)                       #$
    lowerWithinClassVar <- lowerClassProb*(lowerMu^2)
    upperWithinClassVar <- upperClassProb*(upperMu^2)
    betweenClassVar     <- lowerWithinClassVar + upperWithinClassVar
    outputBuffer        <- list(i, lowerClassProb, upperClassProb, lowerMu, 
                                upperMu, lowerWithinClassVar, upperWithinClassVar)
    print(paste("Testing Threshold:", i))

    outputArray <- rbind(outputArray, outputBuffer)
  }
  names(outputArray)         <- c("intensity", "lowerClassProb", "upperClassProb",
                                  "lowerMu", "upperMu", "lowerWithinClassVar",
                                  "upperWithinClassVar")
  outputArray$withinClassVar <- outputArray$lowerWithinClassVar +             
                                outputArray$upperWithinClassVar               #$
  outputArray <- merge(outputArray, intensityFrequency, by=c("intensity"))
  print(paste("Calculating inter and intra-class variances..."))
  outputArray$ngParam <- outputArray$weight*outputArray$withinClassVar        #$
  attach(outputArray)
  sortedOutputNg      <- outputArray[ order(-ngParam),]
  sortedOutputOtsu    <- outputArray[ order(-withinClassVar),]
  paramNG             <- sortedOutputNg[1,]
  paramOTSU           <- sortedOutputOtsu[1,]
  paramNG             <- as.integer(paramNG[1])
  paramOTSU           <- as.integer(paramOTSU[1])
  print(paste("Ng threshold:", paramNG))

  if(otsu==TRUE){
    print(paste("Otsu threshold:", paramOTSU))  
  }

  if(plot==TRUE){
    #Histogram of pixel intensities.
    hist(observations$obs, xlab="Score", breaks = levels, 
         main="Histogram of disease severity score frequencies")

    #Throw on a vertical line to show what a threshold looks like...
    abline(v=paramNG, col='red', lty=4)
    print("Ng threshold is represented by red line, Otsu by blue.")
    if(otsu==TRUE){
      abline(v=paramOTSU, col='blue', lty=3)
    }
  }
  resultArray <- c(paramNG, paramOTSU)
  return(resultArray)
  detach(outputArray)
}


