- PVSM.RU - https://www.pvsm.ru -

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

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

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

«Манифест начинающих программистов из смежных специальностей» или как я дошел до жизни такой - 1
Источник: https://xkcd.com/664/ [1]

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

Ожидания

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

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

А зря...

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

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

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

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

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

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

Реальность

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

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

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

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

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

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

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

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

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

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

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

Step by step

Вместо теоретических выкладок я просто дам ссылку на эту прекрасную статью [4] 2011 года от tgx [5] и на слайды по физическому уровню LTE [6] профессора Мишель-Тиля [7] (ТУ Ильменау). Я думаю, этого будет достаточно.

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

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

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

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

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

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

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

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

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

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

Скрипт целиком можно скачать по ссылке [8].

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

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 [9], приведя значения к наименьшему из ближайших целых:

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 — это хорошо, но понимать что содержится "под капотом" — лучше.

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

  • Дерзайте!

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

  • Требуйте!

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

  • Творите!

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

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

P.S.

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

image

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

Автор: ritchie_kyoto

Источник [10]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/matlab/328229

Ссылки в тексте:

[1] https://xkcd.com/664/: https://xkcd.com/664/

[2] "Communication and Signal Processing": https://griat.kai.ru/communications-and-signal-processing

[3] https://ch.mathworks.com/help/comm/examples/parallel-concatenated-convolutional-coding-turbo-codes.html: https://ch.mathworks.com/help/comm/examples/parallel-concatenated-convolutional-coding-turbo-codes.html

[4] прекрасную статью: https://habr.com/ru/post/129101/

[5] tgx: https://habr.com/ru/users/tgx/

[6] физическому уровню LTE: https://www.tu-ilmenau.de/fileadmin/public/iks/files/lehre/UMTS/11_LTE_Radio_ws18.pdf

[7] Мишель-Тиля: https://scholar.google.ru/citations?user=KZi1MesAAAAJ&hl=ru&oi=sra

[8] ссылке: https://gist.github.com/kirlf/552c39d0b33823c8c61f4148ea0a9d24

[9] linspace: https://ch.mathworks.com/help/matlab/ref/linspace.html

[10] Источник: https://habr.com/ru/post/464479/?utm_campaign=464479&utm_source=habrahabr&utm_medium=rss