资讯详情

MATLAB仿真QPSK/8PSK/16PSK/16QAM信道容量对比

📅 2026/11/3 5:15:25 | 华诺云谱 👁 阅读
MATLAB仿真QPSK/8PSK/16PSK/16QAM信道容量对比
简介围绕QPSK、8PSK、16PSK与16QAM四种调制方式在高斯信道下的信道容量曲线这份文档面向通信工程、电子信息类学生及需要理解数字调制容量分析的读者重点处理二维M元信号容量公式推导与MATLAB仿真落地之间的衔接问题。压缩包仅含1个doc文件大小345KB正文以理论推导、星座图说明和程序代码片段为主适合按公式、参数、曲线顺序阅读。已有1353人学习下载在课程设计、实验复现和入门研究中具备一定参考面。文档从二维复信号表示出发结合复高斯噪声概率密度、信道容量公式及Eb/N0换算说明QPSK、8PSK、16PSK和16QAM的星座点设置与容量曲线绘制思路并给出MATLAB代码片段与信噪比遍历、信号能量和噪声方差计算等关键环节读者可据此核对公式、复现曲线并比较不同调制方式的频谱效率差异。1. 四种调制、一条曲线这套 MATLAB 仿真到底解决什么问题调通信仿真最容易被低估的一步不是把公式推出来而是推完之后跑出来的曲线和教科书对不上。这份资源处理的正是这个环节QPSK、8PSK、16PSK、16QAM 四种调制在高斯信道下的信道容量曲线用 MATLAB 从微分熵公式一路算到绘图最后四条曲线放在同一张坐标里横向对比。核心是蒙特卡洛法把理论上的期望值用大样本平均逼近。适合三类人通信原理或信息论课程需要交仿真报告的学生、想搞懂「容量」到底怎么从公式变成代码的工程师、以及准备在 MATLAB 里做链路级仿真、需要一条基准曲线的开发者。资源形态是一份推导文档加一份 .m 脚本公式编号和代码变量能一一对上这一点比很多只丢代码不给推导的仓库强。2. 项目结构与技术选型一个脚本撑起整套仿真这套资源的体量很小但结构是完整的一份文档负责公式推导从二维 M 元信号集合的定义出发推出式 (1) 差熵形式、式 (2) 的混合概率密度、式 (3) 的复高斯密度最终收敛到式 (4) 这个可以直接写进代码的形式一份 .m 脚本负责把式 (4) 里的每一项翻译成 MATLAB 语句。文档和脚本互为索引看代码卡住的时候翻公式看公式抽象的时候翻代码这个组合对自学特别友好。2.1 为什么这套仿真用 MATLAB 而不是 Python选 MATLAB 不是习惯问题是场景问题。这类仿真的核心操作是三件事复数运算、大矩阵广播、快速出图。MATLAB 的复数是一等公民23j直接写abs()、conj()、angle()全都能直接吃复数数组不需要numpy那套1j*的写法plot命令三行就能出带网格、带标注、带不同线型的对比图省掉的样板代码比想象中多。更实际的原因是信号空间本身用复数表示最自然。式 (3) 里的复高斯密度exp(-|y-ms|²/N0)在 MATLAB 里就是exp(-(abs(y - s)).^2 / No)一行到位换成别的语言要么拆成实部虚部两段要么引入额外的复数库。做通信仿真的人对复基带表示已经形成肌肉记忆工具顺着这个思路走出错的概率最低。代价也存在MATLAB 的for循环慢得离谱而这个脚本恰恰是三重循环套出来的。后面第 5 章会专门处理这个问题那是最典型的性能瓶颈。脚本引用的理论出处是《Channel Codes: Classical and Modern》这个引用在文档里明确标了属于可以放心照着查的方向——不是说代码有多复杂是万一推导某一步看不懂知道该翻哪本书的哪一章。2.2 文件构成与目录组织资源给定的内容是一份带推导的文档和一份 .m 脚本。落到实际使用上我一般会把它们整理成这样路径作用说明doc/capacity_derivation.docx公式推导式 (1) 到式 (4) 的完整过程含星座图示意src/capacity_curve.m主脚本四种调制的星座图构造、容量估计、绘图全在里面out/capacity_compare.png输出图脚本跑完后手动另存方便贴进报告关键点是一个脚本一个文件不做函数拆分。这看起来不像工程实践但对这类教学型仿真反而是优点——所有中间变量都在同一个工作区里跑完之后可以直接在命令行敲Capacity、EbNo、signal_space看它们长什么样调试的时候不用在多个文件之间跳。等你把它改成自己的项目再拆函数也不迟。需要注意的是文档里提到「matlab 的 m 文件在下一个帖子里」也就是说脚本和推导是分两处给的。拿到手第一件事是把两者对齐文档里的Es、N0、y分别对应代码里的哪个变量这个映射关系搞清楚了后面改参数才不会改错地方。2.3 符号到变量的映射表这是我认为整个资源里最有价值的一张对照表照着它看代码几乎不需要额外的注释公式符号代码变量含义单位s_msignal_space(b)第 m 个星座点复数无量纲MM 2.^k调制阶数个E_sEs平均符号能量 mean(sN_0No复噪声总方差二维合计能量P_s/P_nPsPn(i)信号功率比噪声功率倍数p(y)pysm/(M*pi*No)接收信号的混合密度密度C_M-aryCapacity(i)每信道使用的比特数bit/symbolE_b/N_0EbNo(i)每比特能量比噪声谱密度倍数画图取 dB有一处约定必须提前说清楚否则看到数字会觉得不对劲No在这里指的是二维复噪声的总方差不是单边功率谱密度。式 (3) 里的归一化系数是1/(π·N0)对应的指数项是exp(-|y-s|²/N0)这两个地方必须自洽改一个不改另一个曲线会整体平移。原始推导里写的是「噪声每一维的方差 N0/2因此噪声的方差是 N0」代码里的sqrt(No/2)*(randn 1j*randn)正是这句话的直译两边对得上。3. 核心代码拆解从一个星座点到一个容量数值整个脚本的骨架其实只有四步构造星座图、按信噪比生成含噪接收信号、用蒙特卡洛估出-E[log2 p(y)]、换算横坐标并画图。四步之间靠Es和No这两个量串起来理解了这两个量的定义剩下的就是纯粹的数学搬运。3.1 星座图构造四种调制的坐标怎么摆原代码用for k2:4循环k既是 2、3、4也是M2.^k的指数把 QPSKM4、8PSKM8、16PSKM16串在一个循环里处理。每个分支里手写complex()把星座点一个个塞进signal_space数组。% QPSK四个点落在 (±1, ±1) signal_space(1) complex(1,1); signal_space(2) complex(-1,1); signal_space(3) complex(-1,-1); signal_space(4) complex(1,-1); % 8PSK单位圆上 45 度一个点 signal_space(1) complex(1,0); signal_space(2) complex(cos(pi/4),sin(pi/4)); signal_space(3) complex(0,1); % ... 依次按 pi/4 递增共 8 个这种写法直观星座图上每个点的位置一眼就能对上但有两个隐含约定值得注意。第一QPSK 用的是 (±1,±1) 而不是单位圆上的 (±√2/2, ±√2/2)所以 QPSK 的Es (11)×4/4 2而 8PSK 和 16PSK 因为都落在单位圆上Es 1。两者能量差了 2 倍。这不影响曲线的可比性——因为噪声方差No是按各自Es算出来的Es/N0这个比值对所有调制都相同而横坐标Eb/N0 (Es/N0)/C能量绝对值在换算里被约掉了。但如果你把这份代码和误码率仿真拼在一起能量不统一就会出乱子。第二16PSK 那段代码里出现了cos(7*pi/8), sin(-7*pi/8)这种写法看着别扭实际算出来是(-0.924, -0.383)和正确的cos(9π/8), sin(9π/8)完全等价只是绕了个弯。这种写法不影响结果因为遍历所有星座点的求和与顺序无关但读代码的时候容易怀疑自己算错别慌。16QAM 单独放在循环外面用的是(±1,±3)的矩形排布平均能量Es (2101018)×4/16 10。这个数值比 PSK 大一个量级是正常的星座点离原点的平均距离本来就更远。如果让我重写会把星座图生成抽成函数用向量化的方式统一能量% 生成 M-PSK 星座点单位平均能量 function s psk_const(M) s exp(1j * 2*pi*(0:M-1). / M); % 列向量|s| 恒为 1 end % 生成 16QAM 星座点归一化到单位平均能量 function s qam16_const() I [-3 -1 1 3]; [X, Y] meshgrid(I, I); s X(:) 1j*Y(:); s s / sqrt(mean(abs(s).^2)); % 除以前Es 10除以后 Es 1 end参数说明psk_const的入参M是调制阶数必须取 2 的幂输出是M×1的复列向量qam16_const无入参固定生成 16 点方形星座。归一化那一步是我加的原始代码没做加了之后四种调制的Es都是 1后续如果要把误码率曲线叠上来横坐标就直接对齐了。3.2 噪声注入sqrt(No/2)这个系数从哪来循环里最核心的一行是这一句% 每个信噪比点生成 sample 个接收样本 for j 1:sample x(j) signal_space(floor(rand*M)1); % 等概率随机选一个星座点发送 end y x sqrt(No./2)*complex(randn(1,sample), randn(1,sample)); % 叠加复高斯噪声rand*M产生[0, M)的均匀随机数floor取整得到0到M-11转成 MATLAB 的 1-based 下标。这一步实现了「M 个符号等概率发送」也就是式 (2) 里那个1/M的来历。噪声部分是关键。randn产生标准正态分布方差为 1。要让实部和虚部各自的方差等于N0/2就得乘以sqrt(N0/2)。这样实部方差N0/2虚部方差N0/2复数噪声的总方差|n|²的期望就是N0/2 N0/2 N0和式 (3) 里exp(-|y-s|²/N0)的分母严格对应。No Es / PsPn(i); % 噪声方差 信号能量 / 信噪比这一行是整个仿真的地基。PsPn(i) 10^(0.1*snr(i))是线性功率比因为功率比等于能量比所以Es/No Ps/Pn反解出No Es/(Ps/Pn)。物理意义很直白信噪比越高同一个信号能量对应的噪声方差越小。低 SNR 时No可能比Es大几十倍高 SNR 时No小到1e-3量级这个动态范围后面会引出数值稳定性问题。我一般会在这里加一行断言自检防止参数改错assert(abs(mean(abs(sqrt(No/2)*(randn(1,1e6)1j*randn(1,1e6))).^2) - No) 0.01*No, ... 噪声方差与 No 不匹配检查 sqrt(No/2) 系数);一百万样本下实测方差和理论值No的相对误差应该在 1% 以内超了就是系数写错了。3.3 容量估计一个log2里塞了两重求和这是整个脚本最烧脑的十行也是唯一需要对照公式 (4) 才能看懂的部分for j 1:sample pysm 0; for b 1:M pysm pysm exp(-(abs(y(j) - signal_space(b))).^2 / No); end log2py(j) log2(1/M/(pi*No)*pysm); % 对应 log2 p(y) end Capacity(i) -mean(log2py) - log2(pi*exp(1)*No);内层for b 1:M计算的是Σ_b exp(-|y_j - s_b|²/N0)也就是式 (2) 里混合密度p(y)的分子部分。为什么是求和因为接收端不知道发的是哪个符号p(y)必须是所有可能符号贡献的加权和权重就是先验概率1/M。这个求和结果是|y - s_b|²的单调递减函数——离得越近的星座点贡献越大离得越远的贡献趋近于零。外层log2(1/M/(pi*No)*pysm)把分子、先验概率1/M、复高斯的归一化系数1/(π·N0)一次性合成log2 p(y)。Capacity(i)那一行是式 (4) 的逐字翻译-mean(log2py)就是式 (4) 里的-(1/L)Σ log2 p(y_l)即-E[log2 p(Y)]-log2(pi*exp(1)*No)就是减去复高斯噪声的微分熵h(Z) log2(πeN0)。两项相减得到的就是「接收信号的熵减掉噪声的熵」也就是信道容量。这里有个容易混淆的点log2py单独看是负的mean之后取负号才是正的熵。低信噪比下Capacity会趋近于 0但不严格等于 0——蒙特卡洛样本有限可能算出极小的负数。这时候后面EbNo 10*log10(PsPn./Capacity)就会翻车出现Inf或者复数。第 5 章会讲怎么处理。3.4 横坐标换算从SNR到Eb/N0的最后一步EbNo 10*log10(PsPn ./ Capacity);这一行做的事是Es/N0已经存在PsPn里除以C每信道使用的比特数得到Eb/N0再转 dB。为什么这么换算因为不同调制方式在相同SNR下传的比特数不一样——16QAM 一次传 4 比特QPSK 一次只传 2 比特。拿Es/N0做横坐标16QAM 天然占便宜比较不公平。除以C之后横坐标统一成「每比特花多少能量」四种调制才站在同一条起跑线上。换算过程有个隐含假设C本身就是「每符号能可靠传送的比特数」用当前信噪比下的容量去除得到的是「每比特的实际能量代价」。这个自洽关系是 Shannon 那套理论的基础Eb/N0的香农极限-1.59 dB就是从C log2(1 SNR)和SNR C·Eb/N0联立解出来的。脚本里画出来的四条曲线高信噪比段都会趋近各自的log2(M)上界QPSK 是 28PSK 是 316PSK 和 16QAM 都是 4这个上界在图上能直接看出来。绘图部分用的是plot加不同线型区分QPSK 蓝色虚线b--8PSK 红色点划线r-.16PSK 黑色点线k:16QAM 青色实线c-。axis([-2,20,0,5])把视野锁死在Eb/N0从 -2 到 20 dB、容量从 0 到 5 比特的范围内最后用text手动标注四条曲线的名字。4. 跑通流程从拿到脚本到出图的完整操作脚本本身没有外部依赖不调用任何工具箱理论上任何一个能跑.m文件的 MATLAB 版本都行。但实际跑起来有几个地方会卡这一章按顺序走一遍。4.1 环境准备与文件放置推荐 R2016b 及以上。原因不是语法是隐式扩展——从 R2016b 开始y - signal_space这种N×1减1×M的广播才不需要bsxfun。原脚本用的是三重for循环其实没用到广播所以更老的版本也能跑只是速度一样慢。文件放置很朴素新建一个工作目录把.m文件丢进去就行# 目录结构 capacity_project/ ├── capacity_curve.m # 主脚本 └── out/ # 手动新建用来存图命令行执行有两种方式。图形界面下直接打开文件按 F5工作区会留下所有变量方便逐行检查无界面服务器上可以用批处理模式# R2019a 及以上支持 -batch跑完自动退出 matlab -batch cd(/path/to/capacity_project); capacity_curve-batch的参数是一段 MATLAB 表达式cd先切到脚本目录再调用脚本名注意不要带.m后缀。跑之前建议先把sample从66666降到6666试一次确认没语法错误再跑全量——全量跑一次的时间在第 5 章会详细说不是几分钟能解决的。4.2 三个参数决定跑多久、跑多准脚本里可以调的参数不多但每一个都直接影响结果参数默认值影响建议snr-10:1:35横坐标采样密度46 个点调试期改成0:5:205 个点够看趋势sample66666蒙特卡洛样本数决定曲线平滑度调试用 6666出图用 2e5 以上k2:4调制阶数控制跑哪几种只想看 QPSK 就写k2sample是最需要理解的。这个仿真是用样本均值去逼近数学期望估计误差按1/√sample衰减。想让曲线噪声减半样本数得翻四倍。66666 这个数字看着奇怪实际效果是标准差大约在 0.005 比特量级人眼已经看不出毛刺了但它不是 2 的幂内存对齐上也没优势——我一般会改成2^17 131072好算也好调。信噪比范围-10到35 dB、步长 1一共 46 个点。这个范围覆盖了从「几乎全是噪声」到「几乎无差错」的完整过渡区Eb/N0换算后大致落在 -20 到 20 dB 之间取决于容量值刚好把四条曲线的拐点都框进去。如果你的兴趣只在拐点附近把范围收窄到0:1:15能省掉三分之二的运行时间。4.3 结果怎么读四条曲线的相对位置跑完之后图上会出现四条曲线它们的相对关系本身就是结论最下方是 QPSK上界 2 bit/symbol拐点最早Eb/N0在 0 dB 附近就开始明显抬升。8PSK 在上界 3 的位置拐点比 QPSK 晚大约 2 到 3 dB。16PSK 和 16QAM 的上界都是 4但在中低Eb/N0区间16QAM 明显在 16PSK 之上——这个差距就是「同样传 4 比特方形星座比圆形星座更抗噪」的直接证据。为什么 16QAM 优于 16PSK因为 16PSK 把 16 个点全挤在单位圆上相邻点之间的最小欧氏距离只有2·sin(π/16) ≈ 0.39而 16QAM 的点分布在平面上最小距离是2/√10 ≈ 0.63归一化到单位能量后。最小距离越大噪声把点推到相邻判决域的概率越低容量就越高。这个结论在图上表现为 16QAM 曲线整体右移更慢高信噪比段两者收敛到同一个上界 4。QPSK 和 16QAM 在低信噪比段有个有趣的交叉——理论上 QPSK 因为阶数低、抗噪强在极低 SNR 下容量衰减更慢。这个现象在图上不太明显需要把axis的横坐标往左拉到 -20 dB 才能看清属于验证脚本正确性的一个好check如果四条曲线在高 SNR 段没有分别收敛到 2、3、4、4肯定是哪一步的参数写错了。5. 避坑与排查跑不出正确曲线的五个典型场景这一章是踩坑记录。前面四章讲的是「应该怎么做」这里讲的是「做错了会看到什么」每一条都是真实翻车过的场景。5.1 曲线跑到一半断掉右侧出现 Inf 或 NaN现象Capacity数组前十几个元素正常后面突然变成NaN或者-Inf画出来的曲线在某个点之后直接消失。原因在log2(1/M/(pi*No)*pysm)这一行。高信噪比下No极小exp(-|y-s|²/No)对远离y的星座点会下溢成 0。极端情况下如果某个样本y恰好离所有星座点都比较远噪声抽样偏离均值pysm整个变成 0log2(0)返回-Infmean一算整个容量就废了。解决方式是把求和挪到对数域里做用 log-sum-exp 稳定化L -abs(y - signal_space.).^2 / No; % sample x M 的对数似然 m max(L, [], 2); % 每行最大值防止 exp 上溢 logsum m log(sum(exp(L - m), 2)); % log(sum(exp(L))) log2py log2(1/M) - log2(pi*No) logsum/log(2);关键是L - m这一步减去每行的最大值之后exp的入参最大是 0结果落在(0, 1]区间绝不会溢出同时m在最后加回来数学上完全等价。改完之后即使No 1e-6也不会出NaN。5.2 跑一次要半小时以上风扇狂转现象脚本点运行之后 MATLAB 长时间显示「忙」CPU 单核占满等了二十分钟还没出图。算一下复杂度就明白了46 个信噪比点 × 4 种调制 × 66666 个样本 × 每种调制内层再循环 M 次。最坏情况下 16QAM 那一段是 46 × 66666 × 16 ≈ 4900 万次exp调用而且全部在解释执行的for里跑。MATLAB 的循环开销本来就大这个量级跑半小时很正常属于血泪经验。解决方式是向量化把内层的两个for一次干掉x signal_space(randi(M, sample, 1)); % 一次性抽样替代 for j n sqrt(No/2) * (randn(sample,1) 1j*randn(sample,1)); y x n; D abs(y - signal_space.).^2; % sample x M隐式扩展 pysm sum(exp(-D / No), 2); % 沿第 2 维求和 log2py log2(1/M/(pi*No) * pysm); Capacity(i) -mean(log2py) - log2(pi*exp(1)*No);randi(M, sample, 1)一步生成所有发送符号比floor(rand*M)1快且不会越界。abs(y - signal_space.)靠隐式扩展直接算出sample×M的距离矩阵sum(..., 2)沿行求和。改完之后同样的样本量大概快两到三个数量级sample加到1e6也能在几十秒内跑完。还有一个容易被忽略的点x、log2py这些数组在原脚本里没有预分配每轮循环都在动态扩容。MATLAB 会给「看起来在增长」的数组分配额外内存跑大样本时这部分开销很可观。改成向量化写法之后这个问题自动消失。5.3 16QAM 的曲线和 16PSK 几乎重合位置明显不对现象图上 16QAM 那条青色实线贴着 16PSK 的点线走两者该有的差距完全看不到。这个问题只在改动过脚本结构之后才会出现。原脚本的signal_space是在for k2:4循环外面声明的每轮只覆盖当前 M 个位置。如果某一轮 M 变小了比如你注释掉 16PSK 那一段直接从 8PSK 跳到 16 点的 QAMsignal_space的第 9 到 16 个位置还残留着上一轮的旧值Es sum(|s|²)/M就会算错噪声方差跟着错整条曲线平移。解决办法很简单每轮循环开头显式清空for k 2:4 M 2.^k; signal_space zeros(1, M); % 每个 M 重新分配杜绝残留 % ... 后续赋值 endzeros而不是clear是因为clear在循环里会连工作区里其他同名变量一起清掉风险更大。用zeros(1, M)明确形状赋值前如果漏了某个点abs(0)也会算出一个 0 能量点比随机残留值更容易发现。5.4 图形被裁掉看不到高信噪比段的收敛现象四条曲线画到一半就撞到图框上边界或者右边界log2(M)那个平台完全没显示出来。原因是axis([-2,20,0,5])写死了范围。这个范围是针对某种特定的 SNR 区间调出来的snr从 -10 到 35 时Eb/N0的取值范围可能超出[-2, 20]超出部分直接被裁。而容量上界最大是 40到5的纵轴范围是够的问题主要在横轴。处理方式是把axis换成自动模式或者根据数据动态计算xlim([min(EbNo)-2, max(EbNo)2]); ylim([0, log2(max(M)) 1]); grid on;还有一个相关的坑text标注的坐标(18, 2.2)这类也是写死的。一旦横轴范围变了标注会跑到图外面去。我一般改成取曲线末端的位置text(EbNo(end)-2, Capacity(end)-0.3, QPSK);这样即使改参数标注也跟着曲线走。5.5 和教科书上的图对不上整体左右平移现象自己跑出来的曲线形状没问题但和书上或者别人论文里的图相比整体左右差了 3 dB 或者更多。绝大多数情况下是No的定义被改了。原代码No Es / PsPn(i)的前提是PsPn表示E_s/N_0其中N_0是复噪声总方差。如果你按另一套约定每维噪声方差为N_0/2总方差为N_0把No改成Es/(2*PsPn(i))而exp的分母和sqrt(No/2)的系数没同步改就会出现 3 dB 偏差——正好是 2 倍能量。排查方法是单点验证取snr 0 dBEs 1此时No应该等于 1sqrt(No/2)应该等于 0.707。在命令行敲一遍No 1 / 10^(0.1*0); sqrt(No/2) % 应该输出 0.7071如果不是 0.7071说明系数关系被破坏了。恢复的办法是把「No是复方差」「sqrt(No/2)是每维标准差」「exp的分母是No」这三处约定同时检查一遍三处必须一致。还有一个小概率情况是蒙特卡洛样本太少导致低信噪比段的Capacity算出负值EbNo变成复数plot只画实部看起来就像平白无故少了一段。加一句Capacity(i) max(Capacity(i), 0)兜底即可不改物理意义。6. 二次开发把四条曲线扩成一套可对比的容量工具箱原始脚本能出图但复用性一般。真正想拿它做二次开发我建议从三个方向改每个都能直接出成果。第一个方向是扩调制阶数。现在的骨架只支持 4、8、16 三种 PSK 和 16QAM加 32QAM、64QAM 其实只需要一个星座点生成函数不用动容量估计那部分。矩形 QAM 的通用生成方式是按√M × √M排布再归一化M 64时I [-7 -5 -3 -1 1 3 5 7]meshgrid一展就出来了。往上的问题是指数级复杂度——64QAM 一个样本要算 64 次exp向量化之后sample×64的矩阵也就几十兆还能扛再往上就得上近似算法了。第二个方向是加 Shannon 极限做参照。这四条曲线分开看只是四条线和理论上界放在一起才有冲击力% 复 AWGN 信道的容量上界高斯输入不限制星座 C_awgn log2(1 10.^(0.1*snr_dB)); EbNo_awgn 10*log10(10.^(0.1*snr_dB) ./ C_awgn); semilogy(EbNo_awgn, C_awgn, k-, LineWidth, 1.5); legend(QPSK,8PSK,16PSK,16QAM,AWGN 上界);C_awgn就是香农公式本身EbNo_awgn换算方式和离散星座完全一致。画上去会看到四条离散调制曲线全部落在上界下方高 SNR 段各自收敛到log2(M)的水平线而香农上界无限增长。Eb/N0的左极限大约在 -1.59 dB 附近这就是那条著名极限的位置——离散调制永远碰不到它因为等概输入的星座点集天然损失了一部分成形增益。第三个方向是批量跑参、导出数据。做报告或者论文的时候光有一张图不够得有数据表。加几行T table(EbNo(:), Capacity(:), repmat({16QAM}, numel(EbNo), 1), ... VariableNames, {EbNo_dB, Capacity_bps, Modulation}); writetable(T, fullfile(out, capacity_16qam.csv));这段代码放在绘制完成后把横纵坐标和调制类型一起导出成 CSV方便直接丢进别的工具里重画或者做拟合。fullfile拼路径比手写斜杠稳Windows 和 Linux 都能跑。改完之后怎么验证没改坏我的做法是保留一份原始脚本的输出作为基准任何改动之后先跑snr 0:5:20这五个点和基准的对应数值逐个比对误差超过 0.01 比特就说明某处约定被动了。这个习惯是从一次惨痛经历里养成的当时为了「优化」把No的系数改了一半图和之前几乎一样只是整体右移了一点肉眼完全看不出来最后是拿出来的数据和别人的结果差 3 dB 才发现。从那以后我每次动噪声模型相关的代码都强制跑一遍五点校验再往下走。还有一个值得试的改法是把sample做成自适应低信噪比段容量接近 0估计方差小样本可以少拐点附近方差最大样本要加。写个简单的两层循环外层 SNR、内层样本数随Capacity的变化率动态调总耗时能再降一半左右。希望帮到你。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑