plot_eigenspectrum.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. import numpy as np
  2. import scipy as sc
  3. import argparse
  4. from scipy.integrate import quad
  5. import math
  6. from types import SimpleNamespace
  7. import itertools
  8. import matplotlib.pyplot as plt
  9. import seaborn as sns
  10. import sys
  11. from pathlib import Path
  12. sys.path.append(str(Path.cwd().parents[0] / 'scripts'))
  13. from eigenangle_test import EigenangleTest
  14. def process_eigenvectors(vecs, lengths):
  15. sort_idx = np.argsort(lengths)
  16. vecs = vecs.T[sort_idx]
  17. for i, eva in enumerate(vecs):
  18. vecs[i] = eva * np.sign(eva[np.argmax(np.absolute(eva))])
  19. vecs[i] /= np.linalg.norm(eva)
  20. return vecs
  21. def load_eigenspectrum(path_list, N):
  22. matrix_num = len(path_list)
  23. all_eigenvalues = np.empty(N*matrix_num, dtype=complex)
  24. all_eigenangles = np.array([], dtype=float)
  25. for i, path_a in enumerate(path_list):
  26. matrix = np.load(path_a)
  27. eigenvalues, vectors_a = sc.linalg.eig(matrix)
  28. all_eigenvalues[N*i:N*(i+1)] = eigenvalues
  29. vectors_a = process_eigenvectors(vectors_a, np.real(eigenvalues))
  30. for j, path_b in enumerate(path_list[i+1:]):
  31. matrix = np.load(path_b)
  32. eigenvalues , vectors_b = sc.linalg.eig(matrix)
  33. vectors_b = process_eigenvectors(vectors_b, np.real(eigenvalues))
  34. M = np.real(np.dot(vectors_a, np.conjugate(vectors_b).T))
  35. M = np.real(M)
  36. M[np.argwhere(M > 1)] = 1.
  37. all_eigenangles = np.append(all_eigenangles, np.arccos(np.diag(M)))
  38. return all_eigenvalues, all_eigenangles
  39. def plot_eigenvalue_dist(test, eigenvalues, ax=None, color=None, width=.9,
  40. bins=20, scale=1):
  41. hist, edges = np.histogram(np.real(eigenvalues), bins=bins, density=True)
  42. dx = np.diff(edges)[0]
  43. xvalues = np.linspace(-test.critical_radius, test.critical_radius, 200)
  44. norm = quad(test.eigenvalue_real_dist,
  45. -test.critical_radius, test.critical_radius)[0]
  46. yvalues = [np.nan_to_num(test.eigenvalue_real_dist(x))*scale/norm
  47. for x in xvalues]
  48. if ax is None:
  49. fig, ax = plt.subplots()
  50. ax.bar(edges[:-1]+dx/2, hist*scale, color=color, width=width*dx)
  51. ax.plot(xvalues, yvalues, 'k--')
  52. curve_area = np.nansum(yvalues)*np.diff(xvalues)[0]
  53. return ax
  54. def plot_eigenangle_dist(test, eigenangles, ax=None, color=None,
  55. width=.9, bins=20):
  56. edges = np.linspace(0, np.pi, bins)
  57. hist, edges = np.histogram(eigenangles, bins=edges, density=True)
  58. dx = np.diff(edges)[0]
  59. xvalues = edges[:-1] + dx/2
  60. if ax is None:
  61. fig, ax = plt.subplots()
  62. ax.bar(xvalues, hist, color=color, width=width*dx)
  63. edges = np.linspace(0, np.pi, bins*10)
  64. yvalues = [test.angle_dist(x) for x in edges]
  65. ax.plot(edges, yvalues, 'k--')
  66. return ax
  67. def plot_eigenspectrum(test, eigenvalues, eigenangles, original=False):
  68. sns.set(style='ticks', context='talk')
  69. sns.set_color_codes('colorblind')
  70. mosaic = """
  71. AB
  72. """
  73. figsize = (15,7)
  74. fig, ax = plt.subplot_mosaic(mosaic, figsize=figsize,
  75. gridspec_kw=dict(hspace=.2, width_ratios=[1,1]))
  76. ax = SimpleNamespace(**ax)
  77. plot_eigenvalue_dist(eigenangle_test, np.real(eigenvalues), ax.A, scale=1,
  78. color=sns.color_palette('deep')[0], width=.9, bins=40)
  79. ax.A.set_yticks([])
  80. ax.A.set_xlabel(r'real eigenvalue $\lambda_{\mathbb{R}}$')
  81. sns.despine(ax=ax.A, left=True, right=True, top=True)
  82. inset_size = .35
  83. iax = fig.add_axes((.38,.55,inset_size*figsize[1]/figsize[0],inset_size))
  84. iax.plot(np.real(eigenvalues), np.imag(eigenvalues), linestyle='None',
  85. color=sns.color_palette('deep')[0], marker='.', markersize=1)
  86. vmax = max([np.abs(np.real(eigenvalues)).max(),
  87. np.abs(np.imag(eigenvalues)).max()])
  88. iax.set_xlim((-vmax, vmax))
  89. iax.set_ylim((-vmax, vmax))
  90. iax.set_axis_off()
  91. bins = 300
  92. binwidth = np.pi/bins
  93. plot_eigenangle_dist(eigenangle_test, eigenangles, ax.B,
  94. sns.color_palette('rocket')[2], width=.9, bins=bins,)
  95. ax.B.set_xlim((min(eigenangles)-binwidth, max(eigenangles)+binwidth))
  96. if original:
  97. ax.B.set_xlim((np.pi*11/24, np.pi*13/24))
  98. ax.B.set_xticks([np.pi*15/32, np.pi/2, np.pi*17/32])
  99. ax.B.set_xticklabels([r'$\frac{15}{32}\pi$', r'$\frac{1}{2}\pi$',
  100. r'$\frac{17}{32}\pi$'])
  101. else:
  102. ax.B.set_yscale('log')
  103. ax.B.set_ylim((0.001,30))
  104. ax.B.set_yticks([])
  105. ax.B.set_xlabel(f'eigenangle $\phi$')
  106. sns.despine(ax=ax.B, left=True, right=True, top=True)
  107. <<<<<<< HEAD
  108. return fig, ax
  109. =======
  110. return fig
  111. >>>>>>> refs/remotes/origin/synced/master
  112. if __name__ == '__main__':
  113. CLI = argparse.ArgumentParser()
  114. CLI.add_argument("--input", nargs='?', type=lambda s: s.split(' '))
  115. CLI.add_argument("--output", nargs='?', type=Path)
  116. CLI.add_argument("--N", nargs='?', type=int)
  117. CLI.add_argument("--f", nargs='?', type=float)
  118. CLI.add_argument("--mu", nargs='?', type=float)
  119. CLI.add_argument("--epsilon", nargs='?', type=float)
  120. CLI.add_argument("--sigma_ex", nargs='?', type=float)
  121. CLI.add_argument("--sigma_in", nargs='?', type=float)
  122. args, unknown = CLI.parse_known_args()
  123. eigenangle_test = EigenangleTest(N=args.N,
  124. f=args.f,
  125. mu=args.mu,
  126. epsilon=args.epsilon,
  127. sigma_ex=args.sigma_ex,
  128. sigma_in=args.sigma_in,
  129. is_connectivity=True)
  130. eigenvalues, eigenangles = load_eigenspectrum(args.input, N=args.N)
  131. <<<<<<< HEAD
  132. fig, ax = plot_eigenspectrum(eigenangle_test, eigenvalues, eigenangles,
  133. original=('original' in args.input[0]))
  134. fig.suptitle(f'{Path(args.output).name.strip(".pdf")}')
  135. for axi, panel in zip([ax.A, ax.B], ['A', 'B']):
  136. axi.text(s=panel, x=0, y=1, ha='right', va='center',
  137. transform=axi.transAxes, fontsize=20, fontweight='bold')
  138. fig.align_labels()
  139. plt.savefig(args.output, dpi=300, bbox_inches='tight')
  140. =======
  141. fig = plot_eigenspectrum(eigenangle_test, eigenvalues, eigenangles,
  142. original=('original' in args.input[0]))
  143. fig.suptitle(f'{Path(args.output).name.strip(".png")}')
  144. fig.align_labels()
  145. plt.savefig(args.output, bbox_inches='tight')
  146. >>>>>>> refs/remotes/origin/synced/master