matlab源码链接: https://blog.csdn.net/qq_44394952/article/details/122508697.
为了便于计算把系统的仿真参数设置的较小。仿真参数为:子载波个数为 200,总符号数为100,IFFT/FFT 的长度为 512,调制方式选用16QAM调制,为了最大限度的减少插入保护间隔带来的信噪比损失,一般选择符号周期长度是保护间隔长度的5倍,所以保护间隔的长度为有效符号周期的1/4,故设循环前缀的长度为128,信噪比为20dB。

使用函数rand(),生成随机0-1串行序列,个数为:子载波个数总符号数4。
bit_length = carrier_count*symbol_count*bit_per_symbol;
bit_sequence = round(rand(1,bit_length))';
reshape()函数用来把指定的矩阵改变形状,但是元素个数不变,串并变换、并串转换均通过调用reshape()函数。OFDM将频带划分为多个子信道并行传输数据,将高速数据流分成多个并行的低速数据流,然后调制到每个信道的子载波上进行传输。
信号的调制方式有多种,可以通过改变发射的射频信号的幅度、相位和频率
来调制信号。对于OFDM系统来说,只能采用前两种方法,而不能采用频率的调制方法,因为子载波是频率正交,并且携带独立的信息,调制子载波频率会破坏这些子载波的正交特性。本次仿真中我们采用16QAM调制的方式,由二进制变为四进制数字基带信号并进行格雷码映射,取值为-3,-1,1,3。格雷码的特点是邻近的两个信号,其标识仅有一位不同,这样当误符号率一定时,误比特率最小。仿真时直接调用qammod()函数实现。
16QAM调制:
carrier_position = 29:228;
conj_position = 485:-1:286;
bit_moded = qammod(bit_sequence,16,'InputType','bit');
16QAM解调:
bit_demod_sig = reshape(qamdemod(data_sig,16,'OutputType','bit'),[],1);
bit_demod_mut = reshape(qamdemod(data_mut,16,'OutputType','bit'),[],1);
在IFFT实现OFDM中,发送端添加了IFFT模块、接收端添加了FFT模块。IFFT模块的功能相当于说:别麻烦发送N个子载波信号了,我直接算出你们在空中会叠加成啥样子吧;FFT模块的功能相当于说:别用老式的积分方法来去除其余的正交子载波了,我帮你一次把N个携带信号全算出来吧。IFFT实现OFDM的系统用数学的方法在发送端计算信号的叠加波形,在接收端去除正交子载波,从而大大简化了系统的复杂度。
I FFT:
ifft_position = zeros(ifft_length,symbol_count);
%将symbols_per_carrier*IFFT_bin_length矩阵赋0值,这里将20*512矩阵赋0值。这里512是%IFFT的长度,也是OFDM符号子载波的个数。
bit_moded = reshape(bit_moded,carrier_count,symbol_count);\
ifft_position(carrier_position,:)=bit_moded(:,:);
ifft_position(conj_position,:)=conj(bit_moded(:,:));
signal_time = ifft(ifft_position,ifft_length);
%这段程序构造了512个子载波的OFDM符号,并且各个子载波上的数据是共轭对称的。这样做的目的是经过%IFFT后形成的OFDM符号均为实数。另外,在512个子载波中,仅有400个子载波为数据,其余为0值。相%当于补零,补零的目的是通常IFFT的长度应该为2的整数次幂。
FFT:
fft_sig = fft(Rx_data_sig);
fft_mut = fft(Rx_data_mut);
OFDM可以有效地对抗多径时延扩展,把输入数据流中并变换到N个并行的子信道中,使得每一个调制子载波的数据周期可以扩大为原始数据符号周期的N倍,因此时延扩展与符号周期的数值比也同样降低N倍。为了最大限度的消除符号间干扰,还可以在每个OFDM符号的起始位置插入保护间隔,而且该保护间隔长度一般要大于无线信道中的最大时延扩展,这样一个符号的多径分量就不会对下一个符号造成干扰。这种保护间隔是一种循环复制,增加了符号的波形长度,在符号的数据部分,将每个OFDM符号的后Tg时间中的样点复制到OFDM符号的前面,形成前缀,因此交接点没有任何的间断。

加循环前缀和循环后缀:
signal_time_C = [signal_time(end-CP_length+1:end,:);signal_time];
signal_time_C = [signal_time_C; signal_time_C(1:CS_length,:)];
去循环前缀和循环后缀:
Rx_data_sig(1:CP_length,:) = [];
Rx_data_sig(end-CS_length+1:end,:) = [];
Rx_data_mut(1:CP_length,:) = [];
Rx_data_mut(end-CS_length+1:end,:) = [];
根据OFDM符号的功率谱密度,其带外衰减比较慢,为了加快带外衰减的速度我们需要使用加窗技术。通常采用升余弦类型的窗函数:
signal_window = zeros(size(signal_time_C));
signal_window =signal_time_C.*repmat(rcoswindow
(alpha,size(signal_time_C,1)),1,symbol_count);
仿真中分析了两种情况:
1)高斯白噪声新道
2)多径信道+高斯白噪声信道
多径信道:
mult_path_am = [1 0.2 0.1]; % 多径幅度
mutt_path_time = [0 20 50]; % 多径时延
windowed_Tx = zeros(size(signal_Tx));
path2 = 0.2*[zeros(1,20) signal_Tx(1:end-20) ];
path3 = 0.1*[zeros(1,50) signal_Tx(1:end-50) ];
signal_Tx_mult = signal_Tx + path2 + path3; % 多径信号
高斯白噪声信道:
SNR_linear = 10^(SNR/10);
noise_power_mut = signal_power_mut/SNR_linear;
noise_power_sig = signal_power_sig/SNR_linear;
noise_sig = randn(size(signal_Tx))*sqrt(noise_power_sig);
noise_mut = randn(size(signal_Tx_mult))*sqrt(noise_power_mut);
Rx_data_sig = signal_Tx+noise_sig;
Rx_data_mut = signal_Tx_mult+noise_mut;
%在发送数据上加噪声,相当于OFDM信号经过加性高斯白噪声信道
误码率=错误的bit数/序列长度
分别计算单径和多径下的误码率。
error_bit_sig = sum(bit_demod_sig~=bit_sequence);
error_bit_mut = sum(bit_demod_mut~=bit_sequence);
error_rate_sig = error_bit_sig/bit_length;
error_rate_mut = error_bit_mut/bit_length;
rate = [rate; error_rate_sig error_rate_mut]

图3 16QAM调制后的星座图
16QAM调制的方式,由二进制数字基带信号变为四进制并进行格雷码映射,取值为-3,-1,1,3。

图4 IFFT变换后

图5 原始/加循环前缀后缀/加窗后的OFDM信号

图6 加窗后的信号频谱图
加窗后信号的频率不再分布于整个频域上,而是限定在一定范围内,便于后面在信道中的传输。

图7 单径/多径下的OFDM信号

图8 单径下接收信号的星座图

图9 多径下接收信号的星座图
对比图8图9单径和多径下接收信号的星座图,可以明显看出,相较于单径多径下信号混叠严重。
上图所示分别为单径和多径下的误码率,单径下的误码率为0、多径下的误码率为0.0184,结合图8图9可以看出OFDM在单径下的误码率很低,在多径下的误码率略高于单径。
OFDM技术就正面直视并解决了这种载波相互干扰的问题,解决方法就是引入了正交的特性,从而可以在较少带宽中更快的发送信息。在本次OFDM仿真的过程中,引入了两个辅助技术,一是循环前缀和循环后缀,另一个则是加入余弦滚降窗函数。同时仿真过程采用了单径和多径两种信道,实验表明OFDM在单径下的误码率很低,在多径下的误码率略高于单径,可以很好的降低多径效应对于信号的不利影响。
matlab源码链接: https://blog.csdn.net/qq_44394952/article/details/122508697.
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has
我的主要目标是能够完全理解我正在使用的库/gem。我尝试在Github上从头到尾阅读源代码,但这真的很难。我认为更有趣、更温和的踏脚石就是在使用时阅读每个库/gem方法的源代码。例如,我想知道RubyonRails中的redirect_to方法是如何工作的:如何查找redirect_to方法的源代码?我知道在pry中我可以执行类似show-methodmethod的操作,但我如何才能对Rails框架中的方法执行此操作?您对我如何更好地理解Gem及其API有什么建议吗?仅仅阅读源代码似乎真的很难,尤其是对于框架。谢谢! 最佳答案 Ru
我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的
几个月前,我读了一篇关于rubygem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:
我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur
前言作为一名程序员,自己的本质工作就是做程序开发,那么程序开发的时候最直接的体现就是代码,检验一个程序员技术水平的一个核心环节就是开发时候的代码能力。众所周知,程序开发的水平提升是一个循序渐进的过程,每一位程序员都是从“菜鸟”变成“大神”的,所以程序员在程序开发过程中的代码能力也是根据平时开发中的业务实践来积累和提升的。提高代码能力核心要素程序员要想提高自身代码能力,尤其是新晋程序员的代码能力有很大的提升空间的时候,需要针对性的去提高自己的代码能力。提高代码能力其实有几个比较关键的点,只要把握住这些方面,就能很好的、快速的提高自己的一部分代码能力。1、多去阅读开源项目,如有机会可以亲自参与开源
电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。 准备工作: 1、U盘一个(尽量使用8G以上的U盘)。 2、一台正常联网可使用的电脑。 3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。 4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。 U盘启动盘制作步骤: 注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注
matlab打开matlab,用最简单的imread方法读取一个图像clcclearimg_h=imread('hua.jpg');返回一个数组(矩阵),往往是a*b*cunit8类型解释一下这个三维数组的意思,行数、数和层数,unit8:指数据类型,无符号八位整形,可理解为0~2^8的数三个层数分别代表RGB三个通道图像rgb最常用的是24-位实现方法,即RGB每个通道有256色阶(2^8)。基于这样的24-位RGB模型的色彩空间可以表现256×256×256≈1670万色当imshow传入了一个二维数组,它将以灰度方式绘制;可以把图像拆分为rgb三层,可以以灰度的方式观察它figure(1
在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList()Obt