rmt.ipy
146 lines
| 3.3 KiB
| text/plain
|
TextLexer
Brian E. Granger
|
r4591 | # <nbformat>2</nbformat> | ||
# <markdowncell> | ||||
# # Eigenvalue distribution of Gaussian orthogonal random matrices | ||||
# <markdowncell> | ||||
Bernardo B. Marques
|
r4872 | # The eigenvalues of random matrices obey certain statistical laws. Here we construct random matrices | ||
Brian E. Granger
|
r4591 | # from the Gaussian Orthogonal Ensemble (GOE), find their eigenvalues and then investigate the nearest | ||
# neighbor eigenvalue distribution $\rho(s)$. | ||||
# <codecell> | ||||
from rmtkernel import ensemble_diffs, normalize_diffs, GOE | ||||
import numpy as np | ||||
MinRK
|
r3675 | from IPython.parallel import Client | ||
MinRK
|
r3670 | |||
Brian E. Granger
|
r4591 | # <markdowncell> | ||
MinRK
|
r3670 | |||
Brian E. Granger
|
r4591 | # ## Wigner's nearest neighbor eigenvalue distribution | ||
# <markdowncell> | ||||
# The Wigner distribution gives the theoretical result for the nearest neighbor eigenvalue distribution | ||||
# for the GOE: | ||||
Bernardo B. Marques
|
r4872 | # | ||
Brian E. Granger
|
r4591 | # $$\rho(s) = \frac{\pi s}{2} \exp(-\pi s^2/4)$$ | ||
# <codecell> | ||||
def wigner_dist(s): | ||||
MinRK
|
r3670 | """Returns (s, rho(s)) for the Wigner GOE distribution.""" | ||
Brian E. Granger
|
r4591 | return (np.pi*s/2.0) * np.exp(-np.pi*s**2/4.) | ||
MinRK
|
r3670 | |||
Brian E. Granger
|
r4591 | # <codecell> | ||
MinRK
|
r3670 | |||
Brian E. Granger
|
r4591 | def generate_wigner_data(): | ||
s = np.linspace(0.0,4.0,400) | ||||
rhos = wigner_dist(s) | ||||
MinRK
|
r3670 | return s, rhos | ||
Brian E. Granger
|
r4591 | # <codecell> | ||
s, rhos = generate_wigner_data() | ||||
# <codecell> | ||||
plot(s, rhos) | ||||
xlabel('Normalized level spacing s') | ||||
ylabel('Probability $\rho(s)$') | ||||
# <markdowncell> | ||||
# ## Serial calculation of nearest neighbor eigenvalue distribution | ||||
# <markdowncell> | ||||
# In this section we numerically construct and diagonalize a large number of GOE random matrices | ||||
# and compute the nerest neighbor eigenvalue distribution. This comptation is done on a single core. | ||||
# <codecell> | ||||
def serial_diffs(num, N): | ||||
"""Compute the nearest neighbor distribution for num NxX matrices.""" | ||||
diffs = ensemble_diffs(num, N) | ||||
normalized_diffs = normalize_diffs(diffs) | ||||
return normalized_diffs | ||||
# <codecell> | ||||
serial_nmats = 1000 | ||||
serial_matsize = 50 | ||||
# <codecell> | ||||
%timeit -r1 -n1 serial_diffs(serial_nmats, serial_matsize) | ||||
MinRK
|
r3670 | |||
Brian E. Granger
|
r4591 | # <codecell> | ||
MinRK
|
r3670 | |||
Brian E. Granger
|
r4591 | serial_diffs = serial_diffs(serial_nmats, serial_matsize) | ||
# <markdowncell> | ||||
# The numerical computation agrees with the predictions of Wigner, but it would be nice to get more | ||||
# statistics. For that we will do a parallel computation. | ||||
# <codecell> | ||||
hist_data = hist(serial_diffs, bins=30, normed=True) | ||||
plot(s, rhos) | ||||
xlabel('Normalized level spacing s') | ||||
ylabel('Probability $P(s)$') | ||||
# <markdowncell> | ||||
# ## Parallel calculation of nearest neighbor eigenvalue distribution | ||||
# <markdowncell> | ||||
# Here we perform a parallel computation, where each process constructs and diagonalizes a subset of | ||||
# the overall set of random matrices. | ||||
# <codecell> | ||||
def parallel_diffs(rc, num, N): | ||||
MinRK
|
r3675 | nengines = len(rc.targets) | ||
MinRK
|
r3670 | num_per_engine = num/nengines | ||
print "Running with", num_per_engine, "per engine." | ||||
Brian E. Granger
|
r4591 | ar = rc.apply_async(ensemble_diffs, num_per_engine, N) | ||
diffs = np.array(ar.get()).flatten() | ||||
normalized_diffs = normalize_diffs(diffs) | ||||
return normalized_diffs | ||||
# <codecell> | ||||
client = Client() | ||||
view = client[:] | ||||
view.run('rmtkernel.py') | ||||
view.block = False | ||||
# <codecell> | ||||
parallel_nmats = 40*serial_nmats | ||||
parallel_matsize = 50 | ||||
# <codecell> | ||||
%timeit -r1 -n1 parallel_diffs(view, parallel_nmats, parallel_matsize) | ||||
# <codecell> | ||||
pdiffs = parallel_diffs(view, parallel_nmats, parallel_matsize) | ||||
# <markdowncell> | ||||
# Again, the agreement with the Wigner distribution is excellent, but now we have better | ||||
# statistics. | ||||
# <codecell> | ||||
hist_data = hist(pdiffs, bins=30, normed=True) | ||||
plot(s, rhos) | ||||
xlabel('Normalized level spacing s') | ||||
ylabel('Probability $P(s)$') | ||||