# Smoothing Kernel Preventing Simulation of Semi-Circle Law of Random Matrices

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:

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;
set.seed(m);
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') dev.off() # Things look better due to the use of a large sample... 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')
dev.off()
# Things look even better as the smaller bandwidth eliminated the "tails"

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.

• I am glad I could help! :) Commented Apr 20, 2015 at 4:57
• 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 =) Commented Jan 29, 2018 at 3:53
• @Kusavil: I am glad you found this helpful. I suggest you ask this query at the main site as a stand-alone question. Commented Jan 29, 2018 at 22:27