«Манифест начинающих программистов из смежных специальностей» или как я дошел до жизни такой

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

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

a949c0d6d91143aa9e5193fa5b177fc9.png
Источник: https://xkcd.com/664/

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

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

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

А зря…

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

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


9c94902b705f2d2158f8207596850665.jpg

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

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

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

ab49c7725ef3ec9119df539998244129.jpg

И вот на руки нам выдают несколько вариантов ТЗ с заведомо непрактичными параметрами кадра (дабы не искать решение в Интернете), и мы накидываемся на уже упомянутый 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)

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


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

1295f327898f65e98bb1499772dc0b87.png

Блок-схема рассматриваемой модели. Остановимся мы до блока обратного БПФ (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); 

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

У нас есть шаблон (переменная pilots), и, допустим, мы хотим, чтобы в наш кадр пилоты вставлялись из этого шаблона последовательно. Сделать это, конечно, можно в цикле. А можно немного помудрить с матрицами — благо 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 года с двумя ректорами: Петером Шарффом (справа) и Альбертом Харисовичем Гильмутдиновым (слева).

image

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

© Habrahabr.ru