# How to detect whether a signal is unimodal or bimodal?

I have to kinds of signals. The first type of signals are such that their histograms are unimodal (one-peaked). The second type of signals are such that their histograms are bimodal (two-peaked). How I can best detect whether a signal is unimodal or bimodal? In some signals there is a lot of noise so the detection is going to be difficult I guess. Any ideas on how to measure "bimodalism"?

There are a few answers to a similar question over on Cross Validated.SE.

One suggested answer is to use Hartigan's dip test. Another is to use the mixtools package.

I've simulated some example data in R and used the diptest package and the mixtools package. The diagram below shows the raw data in the top to graphs, and the estimated underlying distributions according to mixtools.

The diptest results are:

data: one_mode D = 0.0219, p-value = 0.9915

data: two_mode D = 0.0628, p-value = 0.004434

So diptest is saying the first (unimodal) data set has a 99.15% chance of being unimodal and the second (bimodal) data set has a 0.44% chance of being unimodal.

R Code Below # Q26358

one_mode <- rnorm(100, 0, 1)
two_mode <- c(rnorm(50, -2, 1), rnorm(50, +2, 1))

plot(1:100,one_mode,pch=16, col="green")
lines(1:100,two_mode, pch=16, col="red")

library(mixtools)

par(mfrow=c(2,2))
plot(1:100,one_mode,pch=16, col="green")
plot(1:100,two_mode, pch=16, col="red")

mixmdl = normalmixEM(one_mode)
plot(mixmdl,which=2)
lines(density(one_mode), lty=2, lwd=2)

mixmdl_two = normalmixEM(two_mode)
plot(mixmdl_two,which=2)
lines(density(two_mode), lty=2, lwd=2)

library(diptest)
dip.test(one_mode)
dip.test(two_mode)