"מאַניפעסטאָ פֿאַר אָנהייב פּראָוגראַמערז פון פֿאַרבונדענע ספּעשאַלטיז" אָדער ווי איך גאַט צו דעם פונט אין לעבן

Сегодняшняя моя статья — это мысли вслух от человека, который встал на путь программирования почти случайно (хотя и закономерно).

Да, я понимаю, что мой опыт — это только мой опыт, однако он, мне кажется, хорошо попадает в общую тенденцию. Более того, опыт, описанный ниже, больше относится к сфере научной деятельности, однако чем чёрт не шутит — может пригодится и вне.

"מאַניפעסטאָ פֿאַר אָנהייב פּראָוגראַמערז פון פֿאַרבונדענע ספּעשאַלטיז" אָדער ווי איך גאַט צו דעם פונט אין לעבן
מקור: https://xkcd.com/664/

В общем, всем настоящим студентам от бывшего студента посвящается!

עקספּעקטיישאַנז

Когда в 2014 году я заканчивал бакалавриат по специальности «Инфокоммуникационные технологии и системы связи» я почти ничего не знал о мире программирования. Да, у меня, как и у многих, был на первом курсе предмет «Информатика» — но, господи, это же было на первом курсе! Прошла целая вечность!

В общем и целом, ничего особенно отличного от бакалавриата я не ждал, и поступая на магистерскую программу «Communication and Signal Processing» Германо-Российского Института Новых Технологий.

А зря…

Мы были всего вторым набором, и ребята с первого ещё только собирали чемоданы в далёкую Германию (стажировка занимает полгода на втором курсе магистратуры). Иначе говоря, никто из ближайшего круга ещё не сталкивался всерьёз с методами европейского образования, и спрашивать о деталях было особо не у кого.

Были у нас на первом курсе, конечно, разного рода практики, на которых обычно нам демократично предлагался выбор между написанием скриптов (преимущественно на языке MATLAB) и использованием разных узкоспециализированных GUI (в том смысле, что без написания скриптов — сред имитационного моделирования).

"מאַניפעסטאָ פֿאַר אָנהייב פּראָוגראַמערז פון פֿאַרבונדענע ספּעשאַלטיז" אָדער ווי איך גאַט צו דעם פונט אין לעבן

Стоит ли говорить, что мы, будущие Masters of Science, по своей юношеской дурости, как огня, сторонились написания кода. Вот, он, допустим, Simulink от компании MathWorks: вот они блоки, вот они связи, вот они всякого рода настройки и переключатели.

Родной и понятный для человека, занимавшегося прежде схемотехникой и системотехникой, вид!

"מאַניפעסטאָ פֿאַר אָנהייב פּראָוגראַמערז פון פֿאַרבונדענע ספּעשאַלטיז" אָדער ווי איך גאַט צו דעם פונט אין לעבן
מקור: https://ch.mathworks.com/help/comm/examples/parallel-concatenated-convolutional-coding-turbo-codes.html

Так нам казалось…

רעאַליטי

Одной из практических работ первого семестра была разработка приёмопередатчика OFDM сигнала в рамках предмета «Methods for Modeling and Optimization». Идея весьма удачная: технология и по сей день актуальная и довольно популярная в силу использования, например, в сетях Wi-Fi и LTE/LTE-A (в виде OFDMA). Самое то для магистров, чтобы потренировать навыки моделирования телеком систем.

"מאַניפעסטאָ פֿאַר אָנהייב פּראָוגראַמערז פון פֿאַרבונדענע ספּעשאַלטיז" אָדער ווי איך גאַט צו דעם פונט אין לעבן

И вот на руки нам выдают несколько вариантов ТЗ с заведомо непрактичными параметрами кадра (дабы не искать решение в Интернете), и мы накидываемся на уже упомянутый Simulink… И получаем чайником действительности по голове:

  • Каждый блок таит в себе уйму неизвестных параметров, менять которые с кондачка — страшновато.
  • Манипуляции с числами произвести нужно, вроде, простые, однако городить приходится всё равно дай боже.
  • Кафедральные машины заметно подтормаживают от лихорадочного использование GUI, даже на этапе серфинга по библиотекам доступных блоков.
  • Чтобы доделать что-то дома, нужно иметь такой же Simulink. И никаких, собственно, альтернатив.

Да, проект в итоге мы, конечно, доделали, но доделали с громким выдохом облегчения.

Прошло некоторое время, и мы подошли к окончанию первого курса магистратуры. Количество домашних работ с использованием GUI стало пропорционально спадать с увеличением доли немецких предметов, хотя ещё и не достигало точки смены парадигмы. Многие из нас, включая меня, преодолевая свою немалую амплитуду на раскачку, всё больше и больше использовали в своих научных проектах именно Matlab (пусть и в виде Toolbox’ов), а не знакомый, казалось бы, Simulink.

Точкой в наших сомнениях стала фраза одного из студентов второго курса (они как раз к тому времени вернулись в Россию):

  • Забудьте, по крайне мере на время стажировки, про Similink, MathCad и прочий LabView — за бугром всё пишут на языке MATLAB, используя собственно сам MatLab или его бесплатную «версию» Octave.

Заявление оказалось верным отчасти: в Ильменау спор о выборе инструментария тоже не был решен до конца. Правда, выбор стоял по большей части между языками MATLAB, Python и C.

В тот же день меня взял закономерный азарт: а не перенести ли свою часть модели OFDM передатчика в скриптовую форму? Just for fun.

И я приступил к работе.

שריט פֿאַר שריט

Вместо теоретических выкладок я просто дам ссылку на эту ויסגעצייכנט אַרטיקל 2011 года от tgx и на слайды по физическому уровню LTE פראפעסארן Мишель-Тиля (ТУ Ильменау). Я думаю, этого будет достаточно.

«Итак, — подумал я, — повторим, что же мы будем моделировать?»
Моделировать будем генератор OFDM кадра (OFDM frame generator).

Что он будет включать:

  • информационные символы
  • пилотные сигналы
  • нули (DC)

От чего (простоты ради) мы абстрагируемся:

  • от моделирования циклического префикса (при знании основ, добавить оный уже не составит труда)

"מאַניפעסטאָ פֿאַר אָנהייב פּראָוגראַמערז פון פֿאַרבונדענע ספּעשאַלטיז" אָדער ווי איך גאַט צו דעם פונט אין לעבן

Блок-схема рассматриваемой модели. Остановимся мы до блока обратного БПФ (IFFT). Остальное для полноты картины каждый может продолжить сам — я обещал преподавателям с кафедры оставить что-то и для студентов.

Определим для себя тех. задание:

  • фиксированное количество поднесущих (sub-carriers);
  • фиксированная длина кадра;
  • мы должны добавить один ноль в середину и по паре нулей к началу и концу кадра (итого, 5 штук);
  • информационные символы модулируются с помощью M-PSK или M-QAM, где M — это порядок модуляции.

Приступаем к коду.

Скрипт целиком можно скачать по רונג.

Определим входные параметры:

clear all; close all; clc

M = 4; % e.g. QPSK 
N_inf = 16; % number of subcarriers (information symbols, actually) in the frame
fr_len = 32; % the length of our OFDM frame
N_pil = fr_len - N_inf - 5; % number of pilots in the frame
pilots = [1; j; -1; -j]; % pilots (QPSK, in fact)

nulls_idx = [1, 2, fr_len/2, fr_len-1, fr_len]; % indexes of nulls

Теперь определим индексы информационных символов, приняв предпосылку, что пилотные сигналы должны обязательно идти до и/или после нулей:

idx_1_start = 4;
idx_1_end = fr_len/2 - 2;

idx_2_start = fr_len/2 + 2;
idx_2_end =  fr_len - 3;

Тогда позиции можно определить с помощью функции linspace, приведя значения к наименьшему из ближайших целых:

inf_idx_1 = (floor(linspace(idx_1_start, idx_1_end, N_inf/2))).'; 
inf_idx_2 = (floor(linspace(idx_2_start, idx_2_end, N_inf/2))).';

inf_ind = [inf_idx_1; inf_idx_2]; % simple concatenation

Добавим к этому индексы нулей и отсортируем:

%concatenation and ascending sorting
inf_and_nulls_idx = union(inf_ind, nulls_idx); 

Соответственно, индексы пилотных сигналов — это всё остальное:

%numbers in range from 1 to frame length 
% that don't overlape with inf_and_nulls_idx vector
pilot_idx = setdiff(1:fr_len, inf_and_nulls_idx); 

Теперь давайте разбираться с пилотными сигналами.

У нас есть шаблон (переменная פּיילאַץ), и, допустим, мы хотим, чтобы в наш кадр пилоты вставлялись из этого шаблона последовательно. Сделать это, конечно, можно в цикле. А можно немного помудрить с матрицами — благо MATLAB позволяет делать это с достаточным комфортом.

Во-первых, определим, сколько таких шаблонов помещается в кадр полностью:

pilots_len_psudo = floor(N_pil/length(pilots));

Далее формируем вектор, который состоит из наших шаблонов:

% linear algebra tricks:
mat_1 = pilots*ones(1, pilots_len_psudo); % rank-one matrix
resh = reshape(mat_1, pilots_len_psudo*length(pilots),1); % vectorization

И определяем небольшой вектор, который содержит только кусок шаблона — «хвост», не поместившийся полностью в кадр:

tail_len = fr_len  - N_inf - length(nulls_idx) ...
                - length(pilots)*pilots_len_psudo; 
tail = pilots(1:tail_len); % "tail" of pilots vector

Получаем пилотные символы:

vec_pilots = [resh; tail]; % completed pilots vector that frame consists

Переходим к информационным символам, а именно сформируем сообщение и промодулируем его:

message = randi([0 M-1], N_inf, 1); % decimal information symbols

if M >= 16
    info_symbols = qammod(message, M, pi/4);
else
    info_symbols = pskmod(message, M, pi/4);
end 

Всё готово! Собираем кадр:

%% Frame construction
frame = zeros(fr_len,1);
frame(pilot_idx) = vec_pilots;
frame(inf_ind) = info_symbols

Получится должно что-то такое:

frame =

   0.00000 + 0.00000i
   0.00000 + 0.00000i
   1.00000 + 0.00000i
  -0.70711 - 0.70711i
  -0.70711 - 0.70711i
   0.70711 + 0.70711i
   0.00000 + 1.00000i
  -0.70711 + 0.70711i
  -0.70711 + 0.70711i
  -1.00000 + 0.00000i
  -0.70711 + 0.70711i
  -0.70711 - 0.70711i
   0.00000 - 1.00000i
   0.70711 + 0.70711i
   1.00000 + 0.00000i
   0.00000 + 0.00000i
   0.00000 + 1.00000i
   0.70711 - 0.70711i
  -0.70711 + 0.70711i
  -1.00000 + 0.00000i
  -0.70711 + 0.70711i
   0.70711 + 0.70711i
   0.00000 - 1.00000i
  -0.70711 - 0.70711i
   0.70711 + 0.70711i
   1.00000 + 0.00000i
   0.70711 - 0.70711i
   0.00000 + 1.00000i
   0.70711 - 0.70711i
  -1.00000 + 0.00000i
   0.00000 + 0.00000i
   0.00000 + 0.00000i

«Кайф!» — подумал я довольно и закрыл ноутбук. Ушло у меня на всё про всё пару часов: включая написание кода, изучение некоторых матлабовских функций и продумывание математических трюков.

Какие выводы я тогда сделал

Субъективные:

  • Писать код приятно и сродни поэзии!
  • Написание скриптов — наиболее удобный метод исследований для области Communication and Signal Processing.

Объективные:

  • Не надо палить из пушки по воробьям (если такая учебная цель, конечно, не стоит): использовав Simulink, мы взялись за решение простой задачи навороченным инструментом.
  • GUI — это хорошо, но понимать что содержится «под капотом» — лучше.

И теперь, будучи уже далеко не студентом, я хочу сказать студенческой братии следующее:

  • גיין פֿאַר אים!

Пробуйте писать код, пусть даже поначалу он будет плохим. С программированием как и с любой другой деятельностью, лиха беда — начало. А начать лучше раньше: если вы ученый или даже просто технарь — рано или поздно этот навык вам понадобится.

  • Требуйте!

Требуйте от преподавателей и научных руководителей прогрессивных подходов и инструментов. Если это, конечно, сколько-то возможно…

  • Творите!

Где же ещё лучше всего переболеть всеми болячками новичка, как не в рамках образовательной программы? Творите и оттачивайте своё мастерство — опять же чем раньше начать, тем лучше.

Начинающие программисты всех стран, объединяйтесь!

פּס

Дабы запротоколировать своё прямое отношение к студенчеству, прикладываю памятное фото 2017 года с двумя ректорами: Петером Шарффом (справа) и Альбертом Харисовичем Гильмутдиновым (слева).

"מאַניפעסטאָ פֿאַר אָנהייב פּראָוגראַמערז פון פֿאַרבונדענע ספּעשאַלטיז" אָדער ווי איך גאַט צו דעם פונט אין לעבן

Стоило закончить программу как минимум ради таких костюмов! (шучу)

מקור: www.habr.com

לייגן אַ באַמערקונג