“相关专业的新手程序员宣言”或我如何过上这样的生活

我今天的文章是一个几乎偶然地走上编程道路的人的想法(尽管很自然)。


是的,我知道我的经验只是我的经验,但在我看来,这很符合大趋势。 此外,以下描述的经验与科学活动领域更为相关,但是到底是不是在开玩笑-它可以在外面派上用场。



资料来源: https : //xkcd.com/664/


总的来说,他致力于从以前的学生到所有真正的学生!


期望值


2014年,当我完成了“信息与通信技术和通信系统”的本科学位时,我几乎对编程世界一无所知。 是的,我像许多人一样,在第一年就学习了计算机科学,但是,我的天哪,那是在第一年! 好久不见了!


总的来说,我没有想到与本科生有什么特别的不同,而且我没有想到要参加德国-俄罗斯新技术学院的硕士课程“通信与信号处理”


但是徒劳的...


我们只是第二组,而第一组的人只是在遥远的德国收拾行李(在研究生院的第二年实习需要六个月)。 换句话说,最近的一个圈子还没有认真对待欧洲教育方法,也没有太多关于细节的问题了。


当然,在第一年,我们有各种各样的实践,通常会为我们提供民主的选择,包括编写脚本(主要是在MATLAB中)和使用不同的高度专业化的GUI(即无需编写脚本即模拟环境)。



不用说,我们,未来的科学大师,由于我们年轻的愚蠢,如火,避免编写代码。 例如,在这里,他是MathWorks的Simulink:这是块,这里是通信,这里是各种设置和开关。


本地,对于以前从事电路和系统工程的人来说可以理解,瞧!

所以在我们看来...


现实性


第一学期的实际工作之一是在“建模与优化方法”主题的框架内开发OFDM信号收发器。 这个想法非常成功:由于该技术在Wi-Fi和LTE / LTE-A网络(以OFDMA的形式)中的使用,因此该技术仍然具有实用性并且非常受欢迎。 对于硕士来说,最重要的事情是训练他们在电信系统建模中的技能。



现在,我们为技术规范提供了几种选项,这些选项具有明显不切实际的框架参数(以免在Internet上寻找解决方案),并且我们攻击了已经提到的Simulink……头上有一个现实的茶壶:


  • 每个块都充满了许多未知参数,这些参数从kondachka来看是很恐怖的。
  • 看似需要做一些操纵数字,这很简单,但是上帝禁止所有同样的事情来围栏。
  • 忙于使用GUI,即使在浏览可用块库的阶段,大教堂汽车也明显减速。
  • 要在家中完成某些工作,您需要具有相同的Simulink。 实际上,没有其他选择。

是的,最后,我们当然完成了该项目,但是在完成时感到非常欣慰。


一段时间过去了,我们来到了硕士课程的第一年末。 尽管没有达到范式转换的地步,但使用GUI进行的家庭作业的数量却随着德国科目的比例的增加而按比例下降。 我们中的许多人,包括我在内,克服了我们积累的大量精力,越来越多地在其科学项目中使用了Matlab(尽管以工具箱的形式),而不是看似熟悉的Simulink。


我们怀疑的重点是其中一个二年级学生的话(当时他们刚刚回到俄罗斯):


  • 至少在您实习期间,忘记Similink,MathCad和其他LabView的知识-每个人都使用MatLab本身或其免费的Octave版本在MATLAB中编写代码,

声明部分是正确的:在伊尔默瑙(Ilmenau),关于工具选择的争议也没有解决。 没错,选择主要是在MATLAB,Python和C语言之间进行。


在同一天,逻辑上的兴奋带给了我:我可以将OFDM发射机模型的一部分转换成脚本形式吗? 只是为了好玩。


我去上班了


一步一步


除了理论上的计算,我将链接到tgx于2011年发表的这篇出色文章以及 Michel-Thiel教授(TU Ilmenau) 在LTE物理级别上的幻灯片。 我认为就足够了。

“所以,”我想,“让我们重复一下我们要建模的东西吗?”
我们将模拟OFDM帧发生器。


内容包括:


  • 信息符号
  • 导频信号
  • 零(DC)

从什么(为了简单起见)中我们抽象出:


  • 通过对循环前缀进行建模(如果您了解基础知识,则添加起来并不困难)


正在考虑的模型的框图。 我们将停止到返回FFT(IFFT)的块。 每个人都可以继续自己完成剩下的事情-我向部门的老师保证要给学生一些东西。


我们为自己定义那些。 任务:


  • 固定数量的子载波;
  • 固定帧长;
  • 我们必须在帧的中间加上一个零,在帧的开头和结尾加上一对零(总共5个);
  • 信息符号使用M-PSK或M-QAM进行调制,其中M是调制阶数。

进入代码。


整个脚本可以在这里下载。

定义输入参数:


clear all; close all; clc M = 4; % eg 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 

“嗡嗡声!” -我想得很清楚,然后关闭了笔记本电脑。 我花了几个小时才能完成所有工作:包括编写代码,学习一些Matlab函数以及通过数学技巧进行思考。


那我得出什么结论


主观


  • 编写代码很不错,类似于诗歌!
  • 脚本是通信和信号处理领域最便捷的研究方法。

目的


  • 无需从大炮中射麻雀(如果这样的教育目标当然不值得):使用Simulink,我们开始着手使用复杂的工具解决简单的任务。
  • GUI很不错,但是了解幕后的东西更好。

现在,我离学生远了,我想向学生们的兄弟会讲以下几点:


  • 加油!

尝试编写代码,即使一开始会很糟糕。 与其他活动一样,编程是一个开始。 最好早点开始:如果您是科学家,甚至只是技术人员,迟早将需要此技能。


  • 需求!

需要教育工作者和监督者的创新方法和工具。 如果可以的话,当然要尽可能...


  • 做吧!

如果不是教育计划的一部分,那么生一个初生疮的病在哪里更好? 创建并磨练您的技能-同样,越早开始越好。


来自所有国家的新手程序员,团结一致!


聚苯乙烯


为了记录我与学生的直接关系,我附上一张由两位校长撰写的2017年令人难忘的照片:彼得·沙夫(Peter Sharff,右)和阿尔伯特·哈里索维奇(Albert Harisovich Gilmutdinov,左)。


图片


至少为了这样的服装,值得完成程序! (开个玩笑)

Source: https://habr.com/ru/post/zh-CN464479/


All Articles