dimensiereductie_BOFC_verbeterd.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. #!/bin/env python3
  2. import ithildin as ith
  3. import numpy as np
  4. import matplotlib.pyplot as plt
  5. import sys
  6. from typing import List
  7. from scipy.interpolate import RectBivariateSpline
  8. from pydiffmap.diffusion_map import DiffusionMap
  9. from pydiffmap import visualization as diff_visualization
  10. import matplotlib
  11. # BOFC model (phase_9010/PDL_9010).
  12. # Dit bouwt verder op dimensiereductie_AP_veelpunten.py, maar dan voor BOFC
  13. # (en dus in meer dimensies).
  14. # Laadt eerst de data in
  15. data = ith.SimData.from_stem("results_9010/PDL_9010")
  16. # Vermijd randeffecten en initialiatie
  17. def snij_randen_weg(data,variabele,begintijd):
  18. def begin(index):
  19. if index == 0:
  20. return begintijd
  21. return data.vars[variabele].shape[index]//8
  22. def eind(index):
  23. if index == 0:
  24. return data.vars[variabele].shape[index]
  25. if data.vars[variabele].shape[index] < 20:
  26. return data.vars[variabele].shape[index]
  27. return (7 * data.vars[variabele].shape[index])//8
  28. return data.vars[variabele][begin(0):eind(0),begin(1):eind(1),begin(2):eind(2),begin(3):eind(3)]
  29. def onderzoek(aantal_punten,eps):
  30. begintijd = (41 * 7 + 32)//33 # wacht tot de vlakke golf voorbij is (TODO controleer dit beter,msch vergelijk met simulaties in plaats van movie?)
  31. var_u = snij_randen_weg(data, 'u', begintijd).flatten()
  32. var_v = snij_randen_weg(data, 'v', begintijd).flatten()
  33. var_w = snij_randen_weg(data, 'w', begintijd).flatten()
  34. var_s = snij_randen_weg(data, 's', begintijd).flatten()
  35. # Verlaag aantal punten om geheugengebruik en tijdsduur te beperken.
  36. # replace=True strikt genomen incorrect maar wel een stuk sneller
  37. np.random.seed(0)
  38. keuzes = np.random.choice(var_u.shape[0], aantal_punten, replace=True)
  39. var_u = var_u[keuzes]
  40. var_v = var_v[keuzes]
  41. var_w = var_w[keuzes]
  42. var_s = var_s[keuzes]
  43. # Plot het!
  44. print("scatter")
  45. #fig = plt.figure()
  46. #ax = fig.add_subplot(projection='3d')
  47. #ax.scatter(var_u,var_v,var_w,c=var_s,cmap=plt.hot())
  48. #plt.show()
  49. #plt.close()
  50. # plt.scatter(var_u,var_v)
  51. # plt.title("phaseplot of steekproef of BOFC model (%s points)" % (aantal_punten,)) # todo engels
  52. # plt.xlabel("u")
  53. # plt.ylabel("v")
  54. # plt.savefig("BOFC %s punten 0.04 eps 2 eigvectoren (scatter).png" % (aantal_punten,))
  55. # plt.savefig("BOFC %s punten 0.04 eps 2 eigvectoren (scatter).pdf" % (aantal_punten,))
  56. # plt.close()
  57. # Maak nu diffusion maps
  58. faseruimte = np.column_stack((var_u,var_v,var_w,var_s))
  59. np.random.seed(100)
  60. dmap = DiffusionMap.from_sklearn(epsilon=eps, n_evecs=4) #0.01)
  61. np.random.seed(200)
  62. print("fitting")
  63. dmap.fit(faseruimte)
  64. print("data")
  65. fig = diff_visualization.data_plot(dmap,show=False)
  66. fig.gca().set_title("Data coloured with first DC (BOFC model, %s points)" % (aantal_punten,)) # todo engels
  67. plt.xlabel("u")
  68. plt.ylabel("v")
  69. fig.savefig("BOFC %s punten 0.04 eps 2 eigvectoren (data, uv).png" % (aantal_punten,))
  70. fig.savefig("BOFC %s punten 0.04 eps 2 eigvectoren (data, uv).pdf" % (aantal_punten,))
  71. plt.close()
  72. print("embedding")
  73. scatter_kwargs = { 'c': dmap.dmap[:,3], 'cmap': 'viridis' }
  74. fig = diff_visualization.embedding_plot(dmap,show=True,dim=3,scatter_kwargs=scatter_kwargs)
  75. # Why 'viridis'? No particular reason, it's copied from an example of pydiffmap.
  76. fig.gca().set_title("Embedding given by first three DCs, coloured by fourth (BOFC model, %s points)" % (aantal_punten,)) # todo engels
  77. fig.savefig("BOFC %s punten %s eps 3+1 eigenvectors (embedding, uvw, s).png" % (aantal_punten,eps))
  78. fig.savefig("BOFC %s punten %s eps 3+1 eigenvectors (embedding, uvw, s).pdf" % (aantal_punten,eps))
  79. plt.close()
  80. return dmap
  81. # Zoals ‘Embedding given by first three DCs, coloured by fourth (BOFC model, %s points)’,
  82. # maar plot ook de punten die niet gebruikt worden om de diffusion map op te stellen.
  83. # Hopelijk maakt dat de figuur wat duidelijker ...
  84. def plot_veel_punten(data,aantal_punten,dmap):
  85. begintijd = (41 * 7 + 32)//33
  86. # copied from 'onderzoek'
  87. var_u = snij_randen_weg(data, 'u', begintijd).flatten()
  88. var_v = snij_randen_weg(data, 'v', begintijd).flatten()
  89. var_w = snij_randen_weg(data, 'w', begintijd).flatten()
  90. var_s = snij_randen_weg(data, 's', begintijd).flatten()
  91. np.random.seed(0) # determinisme (TODO)
  92. keuzes = np.random.choice(var_u.shape[0], aantal_punten, replace=True)
  93. var_u = var_u[keuzes]
  94. var_v = var_v[keuzes]
  95. var_w = var_w[keuzes]
  96. var_s = var_s[keuzes]
  97. print("gesnoeid")
  98. # bereken de diffusiecoordinaten # TODO waarom vind Emacs+Python de o-trema niet goed?
  99. var_phi1234 = dmap.transform(np.column_stack((var_u,var_v,var_w,var_s)))
  100. print("getransformeerd")
  101. # plot het!
  102. fig = plt.figure(figsize=(6,6))
  103. ax = fig.add_subplot(111,projection='3d')
  104. ax.scatter(var_phi1234[:,0],var_phi1234[:,1],var_phi1234[:,2],var_phi1234[:,3],c=var_phi1234[:,3],cmap='viridis')
  105. ax.set_title("Embedding given by first three DCs, coloured by fourth (BOFC model)") # todo engels
  106. ax.set_xlabel(r'$\psi_1$')
  107. ax.set_ylabel(r'$\psi_2$')
  108. ax.set_zlabel(r'$\psi_3$')
  109. plt.axis('tight') # ? copied from pydiffmap
  110. fig.savefig("BOFC 3+1 eigenvectors, extended embedding (uvw, s).png")
  111. #fig.savefig("BOFC 3+1 eigenvectors, extended embedding (uvw, s).pdf")
  112. plt.show()
  113. plt.close()
  114. matplotlib.use("TkAgg")
  115. # todo np.random.seed(...) is precies niet voldoende voor determinisme
  116. #dmap = onderzoek(1000,0.04)
  117. #dmap = onderzoek(2000,0.01)
  118. #dmap = onderzoek(3000,0.01)
  119. #dmap = onderzoek(4000,0.01)
  120. dmap = onderzoek(5000,0.01)
  121. # 6000 is te veel voor deze laptop
  122. # Duurt lang! Bij 10000 is er trouwens al veel structuur zichtbaar
  123. plot_veel_punten(data,300000,dmap)
  124. # De meeste pHet is precies één ‘hoofdreeks’
  125. # # Voor 7000 moet ik al een tijdje wachten
  126. #for aantal_punten in [100, 200, 500, 1000, 2000, 3000, 4000, 5000, 6000]:
  127. # onderzoek(aantal_punten)
  128. # AP 6000 punten 0.04 eps 2 eigvectoren.png: twee deuken in een cirkel, een paar uitschieters
  129. # AP 3000 punten 0.04 eps 2 eigvectoren.png: twee deukjes, een aantal uitschieters
  130. # AP 2000 punten 0.04 eps 2 eigvectoren.png: een appel met twee ogen
  131. # AP 1000 punten 0.04 eps 2 eigvectoren.png: een neus met een paar stippen