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?
 A: You do not provide the whole reproduction code so I think what you are seeing is an artifact of two factors:


*

*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.

*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.

*(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. 
