Matlab示例-Examine 16-QAM Using MATLAB学习笔记

news2024/11/15 16:30:37

​工作之余学习16-QAM

写在前面

网上看到许多示例,但一般都比较难以跑通。所以,还是老方法,先将matlab自带的例子研究下。
Examine 16-QAM Using MATLAB

Examine 16-QAM Using MATLAB

或者,在matlab中,键入:

openExample(‘comm/Examine16QAMUsingMATLABExample’)

会打开:

~\Document\MATLAB\Examples\R2022b\comm\Examine16QAMUsingMATLABExample

不得不感叹,WathWorks公司,依然在飞速的进步,其文档代码一体化能力,已经非常强了。
要注意有梯子之后,这个例子,可以直接在浏览器中运行和单步Trace.
在这里插入图片描述在这里插入图片描述不由得有些哀叹。软件这东西怎么说呢,越落后,就越落后。因为人家是在加速,我们则永远在零和搞一年就放弃归零的循环中。

我们能想象,如果MathWorks是中国公司,当你和老板说,我们也开发个网页版的调试器后,老板第一件事就问你这有用吗?这耽误我们挣钱吗?好吧,这玩意真的没什么用处,但真的是太cool了。
而且,下面就是有用的地方:

【注意】Matlab的示例,网页中的一般是最新的,而我们安装好的matlab所带的例子,往往,存在一些小的缺陷,并没有得到修正。

所以,当发生怀疑是不是哪里出错的时候,可以将被怀疑的代码段,与网页版的代码section 进行下比较。

比如当前的这个例子,的最后一段:

网页版是:

scatterplot(symgray,1,0,'b*');
for k = 1:M
    text(real(symgray(k)) - 0.0,imag(symgray(k)) + 0.3, ...
        dec2base(x(k),2,4),'Color',[0 1 0]);
     text(real(symgray(k)) - 0.5,imag(symgray(k)) + 0.3, ...
         num2str(x(k)),'Color',[0 1 0]);
    
    text(real(symbin(k)) - 0.0,imag(symbin(k)) - 0.3, ...
        dec2base(x(k),2,4),'Color',[1 0 0]);
    text(real(symbin(k)) - 0.5,imag(symbin(k)) - 0.3, ...
        num2str(x(k)),'Color',[1 0 0]);
end
title('16-QAM Symbol Mapping')
axis([-4 4 -4 4])

可是matlab中:

scatterplot(symgray,1,0,'b*');
for k = 1:M
    text(real(symgray(k)) - 0.0,imag(symgray(k)) + 0.3, ...
        dec2base(x(k),2,4));
     text(real(symgray(k)) - 0.5,imag(symgray(k)) + 0.3, ...
         num2str(x(k)));
    
    text(real(symbin(k)) - 0.0,imag(symbin(k)) - 0.3, ...
        dec2base(x(k),2,4),'Color',[1 0 0]);
    text(real(symbin(k)) - 0.5,imag(symbin(k)) - 0.3, ...
        num2str(x(k)),'Color',[1 0 0]);
end
title('16-QAM Symbol Mapping')
axis([-4 4 -4 4])

​要注意,matlab中的代码,for循环中,少了一小段:
dec2base(x(k),2,4),‘Color’,[0 1 0]);
少了的这段Color,对我这样的学习的人,还是造成了一定的困扰。
初学者,在实操时,往往同时面对几个到十几个知识要学习,难以确定自己哪里是可以确认的。
正确的图像是这样的(在Web Cloud版跑出来的):
在这里插入图片描述
下面不对的是这样的:
在这里插入图片描述
所以,我很久都没有看懂——因为这张图。
看原图,很清楚是想让我们了解自然码与Gray Code的区别。

修改第一部分代码

这个示例的第一段是准备数据。

dataIn = randi([0 1],n,1); % Generate vector of binary data

但这一段,对于我来说,是不太喜欢的。因为作为初学者,要可控。
所以,我打算将数据进行变换,变换成为标准的0,1,2,3,…,15的样子。
所以,这是我第一步要做的。
在与ChatGPT进行了一番不对等的沟通之后,大致改好了,事实上,我花了不少时间。。。

clc;
clear all;
close all;

M = 16; % Modulation order (alphabet size or number of points in signal constellation)
k = log2(M); % Number of bits per symbol
n = 256; % Number of bits to process
sps = 1; % Number of samples per symbol (oversampling factor)

上面的代码是将总binary长度,减为256

array_length=n/4

% Create an array named input_data and fill it cyclically with numbers from 0 to 15
decimalArray = mod(0:array_length-1, 16);

% Convert decimal array to binary array
binaryArray = dec2bin(decimalArray) - '0';
%swap columns
swappedBinaryArray = binaryArray(:, [4 3 2 1]);

% Concatenate each line of binaryArray
%onerow_binaryArray = binaryArray_pose(:);
onerow_binaryArray = swappedBinaryArray(:);

% Transpose the binary array to a column vector
%transposedBinaryArray = onerow_binaryArray.';

dataIn = onerow_binaryArray;

这段花了不少时间,是因为这里面的矩阵的变换自己不是不熟,是完全不知道如何操作。。。
这一次是学明白了。

这段是为了得到可控的输出
在这里插入图片描述

在这里插入图片描述
然后我们直接到调制

Modulate Using 16-QAM
Use the qammod function to apply 16-QAM modulation to the dataSymbolsIn column vector for natural-encoded and Gray-encoded binary bit-to-symbol mappings.

dataMod = qammod(dataSymbolsIn,M,'bin'); % Binary coding with phase offset of zero
dataModG = qammod(dataSymbolsIn,M); % Gray coding with phase offset of zero

然后是开始Trace这个函数
在跟踪之前,不得不先学习格雷码。
关于格雷码(Gray Code),最好的文章是wikipedia的内容:https://en.wikipedia.org/wiki/Gray_code

还有一篇也不错:
QAM格雷码映射的规则(Gray Code Mapping in QAM)
自己biying

这句是得到自然码的调制后编码,
dataMod = qammod(dataSymbolsIn,M,‘bin’); % Binary coding with phase offset of zero

然后,下面这句是得到Gray的编码
dataModG = qammod(dataSymbolsIn,M); % Gray coding with phase offset of zero
汇总后见下图:
在这里插入图片描述
然后,进入matlab的qammod函数:
在这里插入图片描述从这里

    [y, const] = comm.internal.qam.modulate(x, M, symbolOrder, symbolOrderVector, ...
        bitInput, unitAveragePower, outputDataType);
function y = processIntInput(x, M, symbolOrder, symbolOrderVector, const)
    msg = processSymbols(x, M, symbolOrder, symbolOrderVector);
    y = lookupTable(const, msg);
end
function [y, const] = modulate(x, M, symbolOrderStr, ...
        symbolOrderVector, bitInput, unitAveragePower, outputDataType)
       y = processIntInput(x, Mnew, symbolOrderStr, symbolOrderVector, newConst);
end

重点是这句:
y = lookupTable(const, msg);


function y = lookupTable(table, x)
    y = coder.nullcopy(zeros(size(x),'like',table));
    y(:) = table(x + cast(1,'like',x));
end

重点是这句:

 y(:) = table(x + cast(1,'like',x));

  1. cast(1,'like',x): This part casts the value 1 to the same data type as the input variable x. This is necessary to ensure that the indexing operation doesn’t cause any type mismatches.

  2. x + cast(1,'like',x): This adds 1 to each element of the input vector x.

  3. table(x + cast(1,'like',x)): This indexes the table array using the modified values of x + cast(1,'like',x). It effectively looks up values in the table corresponding to the modified indices.

  4. y(:) = table(x + cast(1,'like',x));: This assigns the values obtained from the lookup to the entire vector y. The (:) syntax is used to linearize y into a column vector.

Let’s walk through an example:

  • Original x values: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
  • Modified indices: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
  • Values from the table corresponding to the modified indices: [-3 + 1i, -3 - 1i, -3 - 3i, -1 + 3i, -1 + 1i, -1 - 1i, -1 - 3i, 1 + 3i, 1 + 1i, 1 - 1i, 1 - 3i, 3 + 3i, 3 + 1i, 3 - 1i, 3 - 3i]

So, the resulting y would be the values obtained from the table using the modified indices. The purpose seems to be to perform a table lookup operation using the input vector x to generate the output vector y.


解调的部分

注意,条件检查的部分,我省略了,实际我也是详细看了的,写得很精妙!
Demodulate 16-QAM
Use the qamdemod function to demodulate the received data and output integer-valued data symbols.

dataSymbolsOut = qamdemod(receivedSignal,M,'bin');
dataSymbolsOutG = qamdemod(receivedSignalG,M);

function x = qamdemod(y, M, varargin)   
    x = comm.internal.qam.demodulate(y, M, symbolOrderStr, symbolOrderVector, unitAveragePower, ...
        outputType, noiseVar);
end
function x = demodulate(y, M, symbolOrderStr, symbolOrderVector, ...
        unitAveragePower, outputType, noiseVar)
                intX = computeHardInt(y, Mnew);        

这里是关键函数


function z = computeHardInt(y, M)
    
    if isa(y,'single')
        z = coder.nullcopy(zeros(size(y), 'single'));
    else
        z = coder.nullcopy(zeros(size(y), 'double'));
    end
    if mod(log2(M), 2) % Cross constellation, including M=2
        const = comm.internal.qam.getSquareConstellation(M);
        z(:) = genqamdemod(y,const);
    else % Square constellation, starting with M=4
        
        % Precompute for later use
        sqrtM = sqrt(M);
        
        % Inphase/real rail
        % Move the real part of input signal; scale appropriately and round the
        % values to get index ideal constellation points
        rIdx = round( ((real(y) + (sqrtM-1)) ./ 2) );
        % clip values that are outside the valid range
        rIdx(rIdx < 0) = 0;
        rIdx(rIdx > (sqrtM-1)) = sqrtM-1;
        
        % Quadrature/imaginary rail
        % Move the imaginary part of input signal; scale appropriately and round
        % the values to get index of ideal constellation points
        iIdx = round(((imag(y) + (sqrtM-1)) ./ 2));
        % clip values that are outside the valid range
        iIdx(iIdx < 0) = 0;
        iIdx(iIdx > (sqrtM-1)) = sqrtM-1;
        
        % compute output from indices of ideal constellation points
        z(:) = sqrtM-iIdx-1 +  sqrtM*rIdx;
        
    end
end

computeHardInt中,这两句是重点

        % Inphase/real rail
        % Move the real part of input signal; scale appropriately and round the
        % values to get index ideal constellation points
        rIdx = round( ((real(y) + (sqrtM-1)) ./ 2) );
                
        % Quadrature/imaginary rail
        % Move the imaginary part of input signal; scale appropriately and round
        % the values to get index of ideal constellation points
        iIdx = round(((imag(y) + (sqrtM-1)) ./ 2));

格雷码,并没有多大不同,调制是后处理,解调是前处理,将数据重新映射。
以上是所有的内容。
可惜这个例子只有基带的处理,没有信号的调制与解调。
是为遗憾。
希望再找个更全面的例子。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1310514.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大模型微调方法:冻结方法 Freeze、P-Tuning 系列、LoRA、QLoRA

大模型微调方法 冻结方法 FreezeP-Tuning 系列Prefix-TuningPrompt TuningP-Tuning v1P-Tuning v2 LoRAQLoRA 冻结方法 Freeze 方法意思是&#xff0c;只用少部分参数训练&#xff0c;把模型的大部分参数冻结。 只要设置微调层的参数&#xff1a; # 遍历模型的所有参数和名称…

汉缆股份携手航天科技AIRIOT建设智慧工厂,加速数字化转型升级

工业4.0时代&#xff0c;工厂早已不是传统概念里流水线与机器制造的简单叠加&#xff0c;而是伴随工业互联网技术的发展&#xff0c;持续朝数字化与智能化方向演进&#xff0c;打造智慧工厂已成为众多制造企业转型升级的共同选择。近期&#xff0c;航天科技控股集团股份有限公司…

拦截器与过滤器的区别

1.最通俗的理解 过滤器&#xff1a;你要从一堆请求中通过一个工具挑选出符合你要求的请求&#xff0c;而这个工具就是过滤器 拦截器&#xff1a;当一个流程正在进行时&#xff0c;你希望干预它的进展&#xff0c;甚至是直接将它终止 2.触发时机不同 过滤器是在请求进入容器…

基于SSM的药房药品采购集中管理系统的设计与实现论文

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对药房药品采购信息管理混乱&#xff0c;出错率高&#xff0c;信息安全…

shiro入门demo(一)身份验证

shiro&#xff08;身份&#xff09;认证&#xff0c;简单来说就是登录/退出。搭建springboot项目&#xff0c;引入shiro和单元测试依赖&#xff1a; <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-…

python程序编程代码大全,python编程代码详解

这篇文章主要介绍了python语言的代码书写规则有哪些&#xff0c;具有一定借鉴价值&#xff0c;需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获&#xff0c;下面让小编带着大家一起了解一下。 Python代码主要由&#xff1a;5个部分组成&#xff0c;下面就分别介绍&…

数据清洗、特征工程和数据可视化、数据挖掘与建模的主要内容

1.4 数据清洗、特征工程和数据可视化、数据挖掘与建模的内容 视频为《Python数据科学应用从入门到精通》张甜 杨维忠 清华大学出版社一书的随书赠送视频讲解1.4节内容。本书已正式出版上市&#xff0c;当当、京东、淘宝等平台热销中&#xff0c;搜索书名即可。内容涵盖数据科学…

什么是纯净IP?如何判断IP地址的纯净度?有哪些干净IP推荐?

您是否想知道什么使代理“干净”或如何确保您的代理不会将您列入网站的黑名单&#xff1f;对于通过代理访问网络的人来说&#xff0c;干净的代理是无缝在线体验的重要组成部分。在这篇文章中&#xff0c;我们将深入研究干净代理的世界&#xff0c;并探讨决定其质量的因素。 一、…

字节跳动面经题

字节跳动面经题 1、了解anchor-free? "Anchor-free"是一个指向一类目标检测方法的术语&#xff0c;与传统的"anchor-based"方法相对应。在传统的目标检测中&#xff0c;通常会使用一系列预定义的锚框&#xff08;anchors&#xff09;作为模型的基础。这些…

Java IO 流详解

Java IO 流详解 1 .Java IO概念 Java IO&#xff1a;即 Java 输入 / 输出系统。 Java 的 IO 模型设计非常优秀&#xff0c;它使用 Decorator (装饰者)模式&#xff0c;按功能划分 Stream &#xff0c;您可以动态装配 这些 Stream &#xff0c;以便获得您需要的功能。 Stream &…

阿里云国际版CDN网页打不开、页面报错该如何解决?

如果在使用CDN过程中&#xff0c;遇到了网页打不开、页面报错等问题时&#xff0c;您可以通过自助诊断工具来进行诊断。诊断工具会告知本次诊断结果&#xff0c;您可以根据结果来调整CDN配置或提交工单进行咨询。 使用场景 主要支持以下情况&#xff1a; 域名访问异常&#x…

Java,这是一个模仿HashMap的put,get功能的自定义MyHashMap

Java 手写HashMap源码 一&#xff0c;手写源码 这是一个模仿HashMap的put&#xff0c;get功能的自定义的MyHashMap package cn.wxs.demo;import java.io.Serializable; import java.util.*; import java.util.function.BiConsumer; import java.util.function.BiFunction; i…

Linux-----10、查找命令

# 查找命令 # 1、 命令查找 Linux下一切皆文件&#xff01; which 命令 &#xff1a;找出命令的绝对路径 whereis 命令 &#xff1a;找出命令的路径以及文档手册信息 [rootheima ~]# which mkdir /usr/bin/mkdir[rootheima ~]# whereis mkdir mkdir: /usr/bin/mkdir /usr/…

+0和不+0的性能差异

前几日&#xff0c;有群友转发了某位技术大佬的weibo。并在群里询问如下两个函数哪个执行的速度比较快&#xff08;weibo内容&#xff09;。 func g(n int, ch chan<- int) {r : 0for i : 0; i < n; i {r i}ch <- r 0 }func f(n int, ch chan<- int) {r : 0for …

读书笔记-《数据结构与算法》-摘要5[归并排序]

归并排序 核心&#xff1a;将两个有序对数组归并成一个更大的有序数组。通常做法为递归排序&#xff0c;并将两个不同的有序数组归并到第三个数组中。 先来看看动图&#xff0c;归并排序是一种典型的分治应用。 public class MergeSort {public static void main(String[] ar…

vscode 文件目录栏缩进

一个好的开发IDE&#xff0c;一定是让人赏心悦目的&#xff0c;这个赏心悦目也一定是包含层级目录的清晰明了&#xff01;不能像感冒的鼻涕一样一擤一摊子&#xff01;就像。。。。嗯&#xff0c;算了&#xff0c;断子还是不讲了&#xff0c;怕有些妹子投诉 或发消息批评我。。…

Java反射类、构造方法、类变量、类方法

被反射的Student类 package reflect;public class Student {public String name;private String age;public int num;public Student(){}public Student(String age) {this.age age;}private Student(String name, String age){this.age age;this.name name;}public String…

Windows下使用CMake编译lua

Lua 是一个功能强大、高效、轻量级、可嵌入的脚本语言。它支持程序编程、面向对象程序设计、函数式编程、数据驱动编程和数据描述。 Lua的官方网站上只提供了源码&#xff0c;需要使用Make进行编译&#xff0c;具体的编译方法为 curl -R -O http://www.lua.org/ftp/lua-5.4.6.…

从零构建属于自己的GPT系列6:模型部署2(文本生成函数解读、模型本地化部署、文本生成文本网页展示、代码逐行解读)

&#x1f6a9;&#x1f6a9;&#x1f6a9;Hugging Face 实战系列 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在PyCharm中进行 本篇文章配套的代码资源已经上传 从零构建属于自己的GPT系列1&#xff1a;数据预处理 从零构建属于自己的GPT系列2&#xff1a;模型训…

IP属地变化背后的原因

随着互联网的普及和技术的不断发展&#xff0c;IP属地变化的现象越来越受到人们的关注。近日&#xff0c;有网友发现自己的IP属地发生了变化&#xff0c;引发了广泛讨论。那么&#xff0c;IP属地为什么会发生变化呢&#xff1f; 首先&#xff0c;网络环境的变化是导致IP属地变化…