In trying to understand the properties of random matrices in the book "Plane Answers to Complex Questions" by R.Christensen, I came across the Semi-Circle Law, and tried to reproduce it with R.

The idea is that in random matrices, such as: n <- 10000; M <- matrix(rnorm(n),nrow=100) the eigenvalues of $\frac{1}{2n}(M + M^{T})$ would follow a semi-circle distribution of the form: $p(x) = \frac{1}{2\pi}\sqrt{4 - x^2}$. Nothing normal or gaussian...

To recreate the semi-circle law, I ran a loop through multiple set.seed() options adding to the plot the density line for every pass.

The issue is that regardless of the smoothing kernel utilized (kernel = c("gaussian", "epanechnikov", "rectangular", "triangular", "biweight","cosine", "optcosine")) there remained tails in the eigenvalues distribution, resembling still a gaussian curve:

enter image description here

The multiple loop outputs are color coded, and parallel the ideal "semi-circle" (in magenta) in the center, but flare out at the extremes.

The question is, Is there a way to prevent this flaring out or "bell-shape" asymptotic behavior of the function density() so as to trace more faithfully the underlying histogram of eigenvalues? Can I use a different plotting method?


You do not provide the whole reproduction code so I think what you are seeing is an artifact of two factors:

  1. the smoothing bandwidth used, ie. how "large of window" your smoother uses when constructing the kernel density estimate. The bell-shape-like shape you are trying to get rid off is mostly due to edge effects. As smaller bandwidth would have almost surely chopped those out.
  2. the size of your sample is insufficient; I strongly suspect you need a large sample to get close to a semi-circle. You are using just 100 samples.
  3. (bonus) You plotting axis looks far from square so visualizing certain effects will not be clear.

See for example the following code:

   # Generate our data:
   m = 5000; 
   n <-m^2; 
   M <- matrix(rnorm(n),nrow=m)
   mEigVals <- eigen(1/(2*n) * (M + t(M)), only.values=TRUE)

   # Plot stuff using default arguments
   # I use the dimensions of the graph in your original post
   png('MyFirstAttempt.png', width= 607, height=485) 
   plot(density(mEigVals$values), main='My first semi-circle attempt')
   # Things look better due to the use of a large sample...

Default kernel bandwidth

   png('MySecondAttempt.png', width= 607, height=485) 
   par(pty='s') # defaults is not square ('s') but actually maximum ('m')
   plot(density(mEigVals$values, bw=1e-8), main='My second semi-circle attempt')
   # Things look even better as the smaller bandwidth eliminated the "tails"

Purposely smaller kernel bandwidth

Clearly because of the smaller bandwidth we have a more noisy curve overall. If we have a larger (ie. denser) sample we would be even smoother. It convey though the fact that you have a clear semicircle arising. (a bit more stretched than I expected but a semi circle with not "tails" of any kind).

Please check your kernel's bandwidth. I did not experiment with this significantly but surely using kernels with finite support (eg. triangular) will give you an even sharper edge effect. A kernel smoother is intrinsically built on the assumption you have a "smooth" data. This an assumption that this data clearly violate as they have a clear step when they reach (and should reach) as zero value.

  • $\begingroup$ I am glad I could help! :) $\endgroup$ – usεr11852 Apr 20 '15 at 4:57
  • $\begingroup$ Thank you! This helped me so much in figuring out, from where should I start working with eigenvalues and some random matrices theory results in R =) $\endgroup$ – Kusavil Jan 29 '18 at 3:53
  • $\begingroup$ @Kusavil: I am glad you found this helpful. I suggest you ask this query at the main site as a stand-alone question. $\endgroup$ – usεr11852 Jan 29 '18 at 22:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.