1+ using MathCore . DSP . Samples ;
2+ using MathCore . DSP . Samples . Extensions ;
3+
4+ namespace MathCore . DSP . Examples ;
5+
6+ /// <summary>Примеры использования фазовой модуляции и демодуляции</summary>
7+ public static class PhaseModulationExamples
8+ {
9+ /// <summary>Демонстрация базового круглого преобразования</summary>
10+ public static void BasicRoundTripExample ( )
11+ {
12+ Console . WriteLine ( "=== Базовый пример круглого преобразования ===" ) ;
13+
14+ // Исходные данные для передачи (отклонения частоты в Гц)
15+ var original_data = new float [ ] { 0f , 200f , - 300f , 150f , - 100f , 0f } ;
16+
17+ const double f0 = 2400e6 ; // 2.4 ГГц центральная частота
18+ const double fd = 48000.0 ; // 48 кГц дискретизация
19+
20+ Console . WriteLine ( "Исходные данные (отклонения частоты, Гц):" ) ;
21+ Console . WriteLine ( $ "[{ string . Join ( ", " , original_data . Select ( x => x . ToString ( "F0" ) ) ) } ]") ;
22+
23+ // Фазовая модуляция
24+ var modulated_samples = original_data . AsSpan ( ) . PhaseModulation ( f0 , fd , amplitude : 120f ) ;
25+ Console . WriteLine ( $ "\n Модулировано { modulated_samples . Length } I/Q отсчётов") ;
26+
27+ // Фазовая демодуляция
28+ var demodulated_data = modulated_samples . AsSpan ( ) . PhaseDemodulation ( f0 , fd ) ;
29+ Console . WriteLine ( $ "Демодулировано { demodulated_data . Length } значений") ;
30+
31+ // Сравнение результатов (пропускаем первые отсчёты из-за переходных процессов)
32+ Console . WriteLine ( "\n Сравнение исходных и демодулированных данных:" ) ;
33+ Console . WriteLine ( "Индекс | Исходные | Демодул. | Ошибка" ) ;
34+ Console . WriteLine ( "-------|----------|----------|--------" ) ;
35+
36+ for ( var i = 2 ; i < Math . Min ( original_data . Length , demodulated_data . Length ) ; i ++ )
37+ {
38+ var error = Math . Abs ( demodulated_data [ i ] - original_data [ i ] ) ;
39+ Console . WriteLine ( $ "{ i , 6 } | { original_data [ i ] , 8 : F1} | { demodulated_data [ i ] , 8 : F1} | { error , 6 : F1} ") ;
40+ }
41+ }
42+
43+ /// <summary>Демонстрация непрерывной модуляции блоками</summary>
44+ public static void ContinuousBlockModulationExample ( )
45+ {
46+ Console . WriteLine ( "\n === Пример непрерывной модуляции блоками ===" ) ;
47+
48+ // Разбиваем данные на блоки
49+ var data_blocks = new [ ]
50+ {
51+ new float [ ] { 0f , 100f , 200f } ,
52+ new float [ ] { 300f , 200f , 100f } ,
53+ new float [ ] { 0f , - 100f , - 200f }
54+ } ;
55+
56+ const double f0 = 915e6 ; // 915 МГц ISM диапазон
57+ const double fd = 2e6 ; // 2 МГц дискретизация
58+
59+ var all_samples = new List < SampleSI16 > ( ) ;
60+ var phase = 0.0 ; // Начальная фаза
61+
62+ for ( var block_index = 0 ; block_index < data_blocks . Length ; block_index ++ )
63+ {
64+ var data_block = data_blocks [ block_index ] ;
65+ Console . WriteLine ( $ "\n Блок { block_index + 1 } : [{ string . Join ( ", " , data_block . Select ( x => x . ToString ( "F0" ) ) ) } ] Гц") ;
66+ Console . WriteLine ( $ "Начальная фаза: { phase : F3} рад") ;
67+
68+ // Модуляция с сохранением фазы
69+ var ( samples , final_phase ) = data_block . AsSpan ( ) . PhaseModulation ( f0 , fd , phase ) ;
70+
71+ Console . WriteLine ( $ "Финальная фаза: { final_phase : F3} рад") ;
72+ Console . WriteLine ( $ "Сгенерировано { samples . Length } I/Q отсчётов") ;
73+
74+ // Добавляем к общему потоку
75+ all_samples . AddRange ( samples ) ;
76+
77+ // Продолжаем с сохранением фазы
78+ phase = final_phase ;
79+ }
80+
81+ Console . WriteLine ( $ "\n Всего сгенерировано { all_samples . Count } I/Q отсчётов") ;
82+
83+ // Демодуляция всего потока
84+ var demodulated = all_samples . ToArray ( ) . AsSpan ( ) . PhaseDemodulation ( f0 , fd ) ;
85+ Console . WriteLine ( $ "Демодулировано { demodulated . Length } значений") ;
86+
87+ // Показываем восстановленные данные
88+ Console . WriteLine ( "\n Восстановленные данные (пропуская переходные процессы):" ) ;
89+ var flat_original = data_blocks . SelectMany ( x => x ) . ToArray ( ) ;
90+
91+ for ( var i = 3 ; i < Math . Min ( flat_original . Length , demodulated . Length - 1 ) ; i ++ )
92+ {
93+ var error = Math . Abs ( demodulated [ i ] - flat_original [ i ] ) ;
94+ Console . WriteLine ( $ "[{ i } ] Исходные: { flat_original [ i ] : F0} Гц, " +
95+ $ "Демодул.: { demodulated [ i ] : F1} Гц, " +
96+ $ "Ошибка: { error : F1} Гц") ;
97+ }
98+ }
99+
100+ /// <summary>Тест производительности модуляции и демодуляции</summary>
101+ public static void PerformanceTest ( )
102+ {
103+ Console . WriteLine ( "\n === Тест производительности ===" ) ;
104+
105+ const int data_count = 1_000_000 ;
106+ const double f0 = 2.4e9 ;
107+ const double fd = 48000.0 ;
108+
109+ // Генерируем тестовые данные
110+ var random = new Random ( 42 ) ;
111+ var test_data = new float [ data_count ] ;
112+ for ( var i = 0 ; i < data_count ; i ++ )
113+ test_data [ i ] = ( float ) ( random . NextDouble ( ) * 1000 - 500 ) ; // ±500 Гц
114+
115+ Console . WriteLine ( $ "Тестирование на { data_count : N0} образцах") ;
116+
117+ // Тест модуляции
118+ var modulation_timer = System . Diagnostics . Stopwatch . StartNew ( ) ;
119+ var modulated = test_data . AsSpan ( ) . PhaseModulation ( f0 , fd ) ;
120+ modulation_timer . Stop ( ) ;
121+
122+ var modulation_rate = data_count / modulation_timer . Elapsed . TotalSeconds / 1e6 ;
123+ Console . WriteLine ( $ "Модуляция: { modulation_timer . ElapsedMilliseconds } мс, " +
124+ $ "{ modulation_rate : F1} млн. образцов/сек") ;
125+
126+ // Тест демодуляции
127+ var demodulation_timer = System . Diagnostics . Stopwatch . StartNew ( ) ;
128+ var demodulated = modulated . AsSpan ( ) . PhaseDemodulation ( f0 , fd ) ;
129+ demodulation_timer . Stop ( ) ;
130+
131+ var demodulation_rate = data_count / demodulation_timer . Elapsed . TotalSeconds / 1e6 ;
132+ Console . WriteLine ( $ "Демодуляция: { demodulation_timer . ElapsedMilliseconds } мс, " +
133+ $ "{ demodulation_rate : F1} млн. образцов/сек") ;
134+
135+ // Проверка точности
136+ var errors = new List < float > ( ) ;
137+ for ( var i = 10 ; i < data_count - 10 ; i ++ ) // Пропускаем края
138+ {
139+ var error = Math . Abs ( demodulated [ i ] - test_data [ i ] ) ;
140+ errors . Add ( error ) ;
141+ }
142+
143+ var avg_error = errors . Average ( ) ;
144+ var max_error = errors . Max ( ) ;
145+
146+ Console . WriteLine ( $ "Средняя ошибка: { avg_error : F2} Гц") ;
147+ Console . WriteLine ( $ "Максимальная ошибка: { max_error : F2} Гц") ;
148+ Console . WriteLine ( $ "Точность: { 100 * ( 1 - avg_error / 500 ) : F1} %") ;
149+ }
150+
151+ /// <summary>Запуск всех примеров</summary>
152+ public static void RunAllExamples ( )
153+ {
154+ Console . WriteLine ( "Примеры использования фазовой модуляции и демодуляции" ) ;
155+ Console . WriteLine ( "=====================================================" ) ;
156+
157+ BasicRoundTripExample ( ) ;
158+ ContinuousBlockModulationExample ( ) ;
159+ PerformanceTest ( ) ;
160+
161+ Console . WriteLine ( "\n === Примеры завершены ===" ) ;
162+ }
163+ }
0 commit comments