Advertisement
Danila_lipatov

Spectrum_Furier_Python

Dec 3rd, 2024
41
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.87 KB | None | 0 0
  1. import pandas as pd
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. import math
  5. # Чтение данных из файла
  6. #
  7. # # Загружаем данные из файла, пропуская первую строку (заголовок)
  8. # data = np.loadtxt(filename, skiprows=1)
  9. data = pd.read_excel('data_lab_1.xlsx')
  10. print(data)
  11. # Разделение данных
  12. # YEARS = data[0, :]
  13. # X = data[1, :]
  14. # Y = data[2, :]
  15. YEARS = data['YEAR']
  16. X = data['X']
  17. Y = data['Y']
  18. # Вычисление временного шага
  19. dT = YEARS[1] - YEARS[0]
  20.  
  21. # Построение графика X от времени
  22. # Построение графиков X и Y по годам
  23. plt.figure(figsize=(12, 6))
  24. plt.subplot(2, 1, 1)
  25. plt.plot(YEARS, X, label="X(t)")
  26. plt.xlabel('Years')
  27. plt.ylabel('X')
  28. plt.title('X over Time')
  29. plt.grid(True)
  30.  
  31. plt.subplot(2, 1, 2)
  32. plt.plot(YEARS, Y, label="Y(t)", color="red")
  33. plt.xlabel('Years')
  34. plt.ylabel('Y')
  35. plt.title('Y over Time')
  36. plt.grid(True)
  37. plt.show()
  38.  
  39. # БПФ для X и Y
  40. dT = YEARS[1] - YEARS[0]  # Шаг времени
  41. N = len(X)
  42.  
  43. # Быстрое преобразование Фурье (БПФ)
  44. X_fft = np.fft.fft(X) / N
  45. Y_fft = np.fft.fft(Y) / N
  46. freqs = np.fft.fftfreq(N, dT)
  47. positive_frequencies_period = freqs[:N // 2]
  48.  
  49. freqs = 2 * math.pi * freqs
  50. # Ограничение до положительных частот
  51. positive_frequencies = freqs[:N // 2]
  52. X_fft_pos = X_fft[:N // 2]
  53. Y_fft_pos = Y_fft[:N // 2]
  54.  
  55. # Спектры для X и Y
  56. plt.figure(figsize=(12, 6))
  57. plt.subplot(2, 1, 1)
  58. plt.plot(positive_frequencies, np.abs(X_fft_pos), label="X Spectrum")
  59. plt.xlabel('Frequency')
  60. plt.ylabel('Amplitude')
  61. plt.title('Amplitude Spectrum for X')
  62. plt.grid(True)
  63.  
  64. plt.subplot(2, 1, 2)
  65. plt.plot(positive_frequencies, np.abs(Y_fft_pos), label="Y Spectrum", color="red")
  66. plt.xlabel('Frequency')
  67. plt.ylabel('Amplitude')
  68. plt.title('Amplitude Spectrum for Y')
  69. plt.grid(True)
  70. plt.show()
  71.  
  72. # Периоды
  73. plt.figure(figsize=(12, 6))
  74. plt.subplot(2, 1, 1)
  75. plt.plot(1 / positive_frequencies_period, np.abs(X_fft_pos), label="X Periodogram")
  76. plt.xlabel('Period')
  77. plt.xscale('log')
  78. plt.ylabel('Amplitude')
  79. plt.title('Periodogram for X')
  80. plt.grid(True)
  81.  
  82. plt.subplot(2, 1, 2)
  83. plt.plot(1 / positive_frequencies_period, np.abs(Y_fft_pos), label="Y Periodogram", color="red")
  84. plt.xlabel('Period')
  85. plt.ylabel('Amplitude')
  86. plt.xscale('log')
  87. plt.title('Periodogram for Y')
  88. plt.grid(True)
  89. plt.show()
  90.  
  91. # Комплексный ряд χ = X + iY и его БПФ
  92. complex_signal = X + 1j * Y
  93. complex_fft = np.fft.fft(complex_signal) / N
  94.  
  95. # Полные частоты для комплексного сигнала
  96. plt.figure(figsize=(12, 6))
  97. plt.plot(freqs, np.abs(complex_fft), label="Complex Spectrum", color="purple")
  98. plt.xlabel('Frequency')
  99. plt.ylabel('Amplitude ')
  100. plt.title('Amplitude Spectrum for Complex Signal')
  101. plt.grid(True)
  102. plt.show()
  103.  
  104. # Находим индекс с наибольшей амплитудой в спектре
  105. dominant_freq_index = np.argmax(np.abs(X_fft_pos))
  106. dominant_freq = positive_frequencies[dominant_freq_index]
  107.  
  108. # Значения для положительной и отрицательной частот
  109. C_k = X_fft[dominant_freq_index]
  110. C_minus_k = X_fft[-dominant_freq_index]
  111.  
  112. # Вычисление амплитуды и фазы для прямой и ретроградной гармоник
  113. amplitude_k = np.abs(C_k)
  114. amplitude_minus_k = np.abs(C_minus_k)
  115. phase_k = np.angle(C_k)
  116. phase_minus_k = np.angle(C_minus_k)
  117. print(freqs)
  118. print(f"Dominant frequency: {dominant_freq}")
  119. print(f"Amplitude for positive frequency (C_k): {amplitude_k}")
  120. print(f"Phase for positive frequency (C_k): {phase_k}")
  121. print(f"Amplitude for negative frequency (C_-k): {amplitude_minus_k}")
  122. print(f"Phase for negative frequency (C_-k): {phase_minus_k}")
  123.  
  124.  
  125. chi = complex_signal
  126. N = len(chi)  # Количество точек данных
  127.  
  128. # БПФ для комплексного сигнала χ
  129. chi_fft = np.fft.fft(chi) / N
  130. freqs = 2 * math.pi * np.fft.fftfreq(N, dT)
  131.  
  132. # Определяем положительные и отрицательные частоты
  133. positive_frequencies = freqs[:N // 2]
  134. negative_frequencies = freqs[N // 2:]
  135.  
  136. # Находим индекс с наибольшей амплитудой в спектре для положительных частот
  137. dominant_freq_index = np.argmax(np.abs(chi_fft[:N // 2]))
  138. dominant_freq_index_neg = np.argmax(np.abs(chi_fft[N // 2:]))
  139. dominant_freq = positive_frequencies[dominant_freq_index]
  140. dominant_freq_neg = negative_frequencies[dominant_freq_index_neg]
  141. # Значения для положительной и отрицательной частот
  142. C_k = chi_fft[dominant_freq_index]  # Положительная частота
  143. C_minus_k = chi_fft[-dominant_freq_index]  # Отрицательная частота
  144.  
  145. # Вычисление амплитуды и фазы для положительной и отрицательной частот
  146. amplitude_k = np.abs(C_k)  # Амплитуда для положительной частоты
  147. amplitude_minus_k = np.abs(C_minus_k)  # Амплитуда для отрицательной частоты
  148. phase_k = np.angle(C_k)  # Фаза для положительной частоты
  149. phase_minus_k = np.angle(C_minus_k)  # Фаза для отрицательной частоты
  150.  
  151. # Вывод результатов
  152. print('C_k', C_k)
  153. print('C_-k', C_minus_k)
  154. print(f"Dominant frequency: {dominant_freq}")
  155. print(f"Dominant frequency: {dominant_freq_neg}")
  156. print(f"Amplitude for positive frequency (C_k): {amplitude_k}")
  157. print(f"Phase for positive frequency (C_k): {phase_k} rad")
  158. print(f"Amplitude for negative frequency (C_-k): {amplitude_minus_k}")
  159. print(f"Phase for negative frequency (C_-k): {phase_minus_k} rad")
  160.  
  161. # Визуализация спектра
  162. plt.figure(figsize=(10, 6))
  163. plt.plot(positive_frequencies, np.abs(chi_fft[:N // 2]), label="Amplitude Spectrum")
  164. plt.xlabel('Frequency')
  165. plt.ylabel('Amplitude')
  166. plt.title('Amplitude Spectrum of Complex Signal')
  167. plt.grid(True)
  168. plt.legend()
  169. plt.show()
  170.  
  171. # Определяем функцию для вычисления спектра и частот с помощью FFT
  172. # def ampl_fft(signal, dT):
  173. #     N = len(signal)  # Количество точек данных
  174. #     spectr = np.fft.fft(signal)  # Вычисляем преобразование Фурье
  175. #     omega = np.fft.fftfreq(N, dT) * 2 * np.pi  # Частоты в радианах
  176. #     return spectr, omega
  177. import numpy as np
  178. import matplotlib.pyplot as plt
  179.  
  180. # Параметры для гармоник
  181. a = 18  # День рождения
  182. b = 10   # Месяц рождения
  183. c = 2002  # Год рождения
  184.  
  185. # Периоды (в годах)
  186. T1 = 0.5
  187. T2 = 1
  188. T3 = 4.6
  189.  
  190. # Амплитуды гармоник, нормализованные
  191. A1 = (a / 31) * 20
  192. A2 = (b / 12) * 20
  193. A3 = ((c - 2000) / 50) * 20
  194.  
  195. # Временная шкала
  196. N = len(X)  # Количество точек данных как в реальном сигнале
  197. t = np.linspace(0, N * (YEARS[1] - YEARS[0]), N)  # Время в годах от 2000 года
  198. print(t)
  199. # Фазы, чтобы косинус обнулялся в 2000 году
  200. phi1 = np.pi / 2
  201. phi2 = np.pi / 2
  202. phi3 = np.pi / 2
  203. # phi1 = 0
  204. # phi2 = 0
  205. # phi3 = 0
  206. # Модельный сигнал как сумма трёх гармоник
  207. X_model = (A1 * np.cos(2 * np.pi * t / T1 + phi1) +
  208.            A2 * np.cos(2 * np.pi * t / T2 + phi2) +
  209.            A3 * np.cos(2 * np.pi * t / T3 + phi3))
  210.  
  211. # Построение реального и модельного сигнала вместе
  212. plt.figure(figsize=(10, 6))
  213. plt.plot(YEARS, Y, label="Real Signal", color="blue")
  214. plt.plot(YEARS, X_model, label="Model Signal", color="orange", linestyle="--")
  215. plt.xlabel('Years')
  216. plt.ylabel('Amplitude')
  217. plt.title('Real vs Model Signal')
  218. plt.grid(True)
  219. plt.legend()
  220. plt.show()
  221.  
  222. # Спектральный анализ
  223. X_model_fft = np.fft.fft(X_model) / len(X_model)
  224. freqs_model = np.fft.fftfreq(len(X_model), YEARS[1] - YEARS[0])
  225.  
  226. # Ограничение до положительных частот
  227. positive_frequencies_model = freqs_model[:len(X_model) // 2]
  228. X_model_fft_pos = X_model_fft[:len(X_model) // 2]
  229.  
  230. # Построение амплитудного спектра для модельного сигнала
  231. plt.figure(figsize=(10, 6))
  232. plt.plot(2 * math.pi * positive_frequencies_model, np.abs(X_model_fft_pos), label="Model Signal Spectrum", color="green")
  233. plt.xlabel('Frequency')
  234. plt.ylabel('Amplitude')
  235. plt.title('Amplitude Spectrum of Model Signal')
  236. plt.grid(True)
  237. plt.legend()
  238. plt.show()
  239.  
  240. # Сравнение спектра модельного и реального сигнала
  241. X_fft_pos = np.fft.fft(Y)[:len(Y) // 2] / len(Y)
  242. positive_frequencies = np.fft.fftfreq(len(Y), YEARS[1] - YEARS[0])[:len(Y) // 2]
  243.  
  244. plt.figure(figsize=(10, 6))
  245. plt.plot(2 * math.pi * positive_frequencies, np.abs(X_fft_pos), label="Real Signal Spectrum", color="blue")
  246. plt.plot(2 * math.pi * positive_frequencies_model, np.abs(X_model_fft_pos), label="Model Signal Spectrum", color="orange", linestyle="--")
  247. plt.xlabel('Frequency')
  248. plt.ylabel('Amplitude')
  249. plt.title('Real vs Model Signal Spectrum')
  250. plt.grid(True)
  251. plt.legend()
  252. plt.show()
  253.  
  254. def ampl_fft(f, dT):
  255.     # Размер массива и количество точек
  256.     N = len(f)
  257.  
  258.     # Преобразование Фурье и нормировка спектра
  259.     fourier_transform = np.fft.fft(f)
  260.     spectr = fourier_transform / N
  261.  
  262.     # Вычисляем угловые частоты omega
  263.     omega = np.zeros(N)  # Инициализация массива для частот
  264.     t = np.zeros(N)  # Инициализация массива для периодов
  265.  
  266.     for j in range(N):
  267.         if j == 0:
  268.             t[j] = 0
  269.             omega[j] = 0
  270.         elif j <= N // 2:
  271.             t[j] = N * dT / (j)
  272.             omega[j] = 2 * np.pi / t[j]
  273.         else:
  274.             t[j] = N * dT / (N - j)
  275.             omega[j] = -2 * np.pi / t[j]
  276.  
  277.     return spectr, omega
  278. # Преобразование данных X и Y в комплексный сигнал
  279. complex_signal = X + 1j * Y
  280.  
  281. # Вычисляем спектр и частоты
  282. spectr, omega = ampl_fft(complex_signal, dT)
  283.  
  284. # Построение графика спектра
  285. plt.figure()
  286. plt.plot((1.0 / (omega / (2 * np.pi)))[:N // 2], np.abs(spectr)[:N // 2])  # 1/omega для периода
  287. plt.xlabel('Period (years)')
  288. plt.xscale('log')
  289. plt.ylabel('Amplitude')
  290. plt.title('Frequency Spectrum')
  291. plt.grid(True)
  292. plt.show()
  293.  
  294. plt.figure()
  295. plt.plot((1.0 / (omega / (2 * np.pi))), np.abs(spectr))  # 1/omega для периода
  296. plt.xlabel('Period (years)')
  297. plt.ylabel('Amplitude')
  298. plt.title('Frequency Spectrum')
  299. plt.grid(True)
  300. plt.show()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement