上一章问怎样用更少的 bit 表示消息。这一章问:线路会出错时,怎样让接收端仍然知道我们发了什么?
把每个比特发送三遍、用多数表决,是一种纠错方法,但速率降到了 1/3。继续增加重复次数还会继续降低速率。香农的结论更强:对合适的信道,先固定一个低于容量的正速率,再使用越来越长、设计得当的块码,就能使块解码错误概率趋于零。
这里的“越来越长”会带来延迟、存储和计算成本,也不保证随意选一个长码就能改善性能。以下先讨论无记忆信道,离散公式均以 2 为底,单位为 bit。
信道是一个条件概率模型
信道用 P(Y=y∣X=x) 表示。输入分布 P(X) 描述发送端如何使用信道,条件分布 P(Y∣X) 描述线路如何改变输入。两者是不同的对象。
二元对称信道(BSC)可以写成:
Y=X⊕Z,Z∼Bernoulli(p)
其中 Z 与 X 独立,每次使用的噪声也独立。p 是翻转概率;1−p 是保持原值的概率。
一次使用的平均信息传递由互信息度量:
I(X;Y)=H(X)−H(X∣Y)=H(Y)−H(Y∣X)
它是给定输入分布下的平均量,不是说收到的每一个具体比特都携带同样的信息。
容量为什么要对输入分布取最大值?
设发送 1 的概率是 α=P(X=1)。输出为 1 有两条途径:输入 1 且未翻转,或输入 0 且翻转。因此:
β=P(Y=1)=α(1−p)+(1−α)p=p+α(1−2p)
给定任一输入,输出剩下的不确定性都是翻转噪声的二元熵 h2(p),所以:
I(X;Y)=h2(β)−h2(p)
固定线路参数 p 后,第二项不变。要增大互信息,就要让输出熵 h2(β) 尽量大。
正在呈现知识画面
同一条信道,输入方式不同,传递的信息也不同先选 BSC 的翻转概率 p,再改变发送 1 的比例 α。圆点表示当前输入的互信息,曲线展示所有 α,虚线标出最大值 C;公式同步拆成输出熵减去噪声熵。
{"id":"channel-bsc","title":"同一条信道,输入方式不同,传递的信息也不同","summary":"先选 BSC 的翻转概率 p,再改变发送 1 的比例 α。圆点表示当前输入的互信息,曲线展示所有 α,虚线标出最大值 C;公式同步拆成输出熵减去噪声熵。","height":950,"html":"<p class=\"eyebrow\" data-i18n=\"eyebrow\"></p><h2 data-i18n=\"heading\"></h2><p class=\"intro\" data-i18n=\"intro\"></p>\n<div class=\"presets\" role=\"group\" data-i18n-label=\"noise\"><button data-p=\"0\">p = 0</button><button data-p=\"0.11\">p = 0.11</button><button data-p=\"0.5\">p = 0.5</button><button data-p=\"1\">p = 1</button></div>\n<label class=\"control\" for=\"bias\"><span data-i18n=\"control\"></span><output id=\"bias-value\"></output></label><input id=\"bias\" type=\"range\" min=\"0\" max=\"100\" value=\"20\" step=\"1\">\n<div class=\"flow\"><div><span data-i18n=\"input\"></span><strong id=\"input-value\"></strong><div class=\"binary-band\"><div id=\"input-one\"></div></div></div><span class=\"arrow\">→</span><div><span data-i18n=\"output\"></span><strong id=\"output-value\"></strong><div class=\"binary-band\"><div id=\"output-one\"></div></div></div></div>\n<p class=\"note\" data-i18n=\"axis\"></p><div class=\"plot\"><svg viewBox=\"0 0 600 190\" preserveAspectRatio=\"none\" role=\"img\" data-i18n-label=\"chart\"><path id=\"capacity-curve\" class=\"curve\"/></svg><div id=\"capacity-line\"></div><div id=\"current-point\"></div></div>\n<div class=\"scale\"><span>α = 0</span><span class=\"middle\">0.5</span><span>1</span></div>\n<div class=\"formula\"><div id=\"output-formula\"></div><div id=\"information-formula\"></div></div>\n<div class=\"metric-pair\"><div><span data-i18n=\"current\"></span><strong id=\"information\"></strong></div><div><span data-i18n=\"maximum\"></span><strong id=\"capacity\"></strong></div></div>\n<div class=\"copy-stack\"><p id=\"explanation\" aria-live=\"polite\"></p><p class=\"reserve\" aria-hidden=\"true\" data-i18n=\"ordinary\"></p><p class=\"reserve\" aria-hidden=\"true\" data-i18n=\"random\"></p><p class=\"reserve\" aria-hidden=\"true\" data-i18n=\"inverted\"></p></div>","css":".intro { margin:8px 0 18px; color:var(--muted); font-size:14px; }\n.control { display:flex; align-items:center; justify-content:space-between; gap:16px; margin-top:18px; }\n.control output { min-width:4em; flex-shrink:0; text-align:center; background:var(--accent-soft); color:var(--accent); padding:2px 8px; border-radius:6px; font-weight:600; }\n.formula { margin-top:18px; padding:14px 0; border-block:1px solid var(--rule); font-size:16px; font-variant-numeric:tabular-nums; overflow-wrap:anywhere; }\n.copy-stack { display:grid; margin-top:14px; color:var(--muted); font-size:14px; }\n.copy-stack > * { grid-area:1/1; }\n.copy-stack .reserve { visibility:hidden; }\n.note { margin-top:14px; color:var(--muted); font-size:12px; }\n.metric-pair { display:grid; grid-template-columns:1fr 1fr; gap:16px; margin-top:18px; }\n.metric-pair > div { min-width:0; }\n.metric-pair span { display:block; font-size:12px; color:var(--muted); }\n.metric-pair strong { display:block; font-size:24px; font-weight:500; font-variant-numeric:tabular-nums; }\n.scale { display:flex; justify-content:space-between; color:var(--muted); font-size:12px; font-variant-numeric:tabular-nums; }\n@media(max-width:480px) { .metric-pair strong { font-size:21px; } }\n.presets { display:flex; }\n.plot { position:relative; margin-top:18px; height:190px; border-left:1px solid var(--rule); border-bottom:1px solid var(--muted); }\n.plot svg { width:100%; height:100%; overflow:hidden; }\n.plot .curve { fill:none; stroke:var(--accent); stroke-width:2.5; vector-effect:non-scaling-stroke; }\n.plot .curve.secondary { stroke:var(--second); stroke-dasharray:5 4; }\n.scale { position:relative; }.scale .middle { position:absolute; left:50%; transform:translateX(-50%); }\n.formula { font-size:14px; }.formula div+div { margin-top:6px; }\n@media(max-width:480px) { .plot { height:170px; } }\n.plot .curve { transition:d .28s cubic-bezier(.22,1,.36,1); }\n.flow { display:grid; grid-template-columns:1fr auto 1fr; gap:12px; align-items:center; margin-top:12px; }\n.flow > div { min-width:0; }.flow span { font-size:12px; color:var(--muted); }.flow strong { display:block; font-size:16px; font-variant-numeric:tabular-nums; }.arrow { padding-top:20px; }\n.binary-band { height:12px; margin-top:6px; background:var(--surface); box-shadow:inset 0 0 0 1px var(--rule); }.binary-band div { height:100%; background:var(--accent); transition:width .28s; }\n#capacity-line { position:absolute; left:0; right:0; border-top:1px dashed var(--muted); }\n#current-point { position:absolute; width:11px; height:11px; border:2px solid var(--paper); border-radius:50%; background:var(--accent); box-shadow:0 0 0 1px var(--accent); transform:translate(-50%,50%); transition:left .2s,bottom .2s; }\n@media(max-width:480px) { .presets { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); }.flow { gap:8px; }.flow strong { font-size:14px; } }\n#capacity-line { transition:bottom .28s cubic-bezier(.22,1,.36,1); }\n","js":"let flip=.11;const bias=document.querySelector('#bias');const h=a=>viz.entropy([a,1-a]);\nfunction draw(){const a=+bias.value/100,b=flip+a*(1-2*flip),noise=h(flip),capacity=1-noise,information=Math.max(0,h(b)-noise);\n document.querySelector('#bias-value').textContent=viz.number(a,2);document.querySelector('#input-value').textContent='α = '+viz.number(a,2);document.querySelector('#output-value').textContent='β = '+viz.number(b,4);\n document.querySelector('#input-one').style.width=a*100+'%';document.querySelector('#output-one').style.width=b*100+'%';\n const points=Array.from({length:201},(_,i)=>{const x=i/200,y=Math.max(0,h(flip+x*(1-2*flip))-noise);return (i?'L':'M')+(x*600).toFixed(3)+','+((1-y)*190).toFixed(3);});document.querySelector('#capacity-curve').setAttribute('d',points.join(' '));\n document.querySelector('#capacity-line').style.bottom=capacity*100+'%';const dot=document.querySelector('#current-point');dot.style.left=a*100+'%';dot.style.bottom=information*100+'%';\n document.querySelector('#output-formula').textContent='β = p + α(1 − 2p) = '+viz.number(b,4);\n document.querySelector('#information-formula').textContent='I = h₂(β) − h₂(p) = '+viz.number(h(b),3)+' − '+viz.number(noise,3)+' ≈ '+viz.number(information,3);\n document.querySelector('#information').textContent=viz.number(information,3)+' bit';document.querySelector('#capacity').textContent=viz.number(capacity,3)+' bit';\n document.querySelector('#explanation').textContent=viz.t(flip===.5?'random':flip===1?'inverted':'ordinary');document.querySelectorAll('[data-p]').forEach(button=>button.setAttribute('aria-pressed',String(+button.dataset.p===flip)));\n}\nbias.addEventListener('input',draw);document.querySelectorAll('[data-p]').forEach(button=>button.addEventListener('click',()=>{flip=+button.dataset.p;draw();}));draw();","audio":false,"strings":{"axis":"横轴:输入比例 α;纵轴:I,固定为 0–1 bit。实线是 I(α),虚线是容量 C,圆点是当前值。","chart":"BSC 互信息随输入比例变化的曲线,与容量和当前输入对应的位置。","control":"发送 1 的比例 α","current":"当前输入的 I(X;Y)","eyebrow":"容量里的 max 在优化什么","heading":"信道没变,为什么传递的信息变了?","input":"发送端","intro":"先固定一条线路,再改变输入比例。曲线保持整段可见,圆点沿它移动;改变翻转概率时,再比较整条曲线。","inverted":"p = 1 时,β = 1 − α:输出虽然总与输入相反,却能完整恢复输入。噪声熵为 0,容量仍是 1;均匀输入时达到最大值。","maximum":"整条曲线的最大值 C","noise":"BSC 翻转概率","ordinary":"把 α 调到 0.5,输出熵达到 1,互信息达到容量。若输入确定,输出中的随机性全部来自噪声,I 为 0;容量本身并未因此变小。","output":"接收端","random":"p = 0.5 时,接收端始终一半为 1,与输入比例无关。H(Y) 与 H(Y|X) 都是 1,整条互信息曲线为 0,任何输入都无法传递信息。"}}
由于二元输出的熵至多为 1,而均匀输入 α=1/2 可以使 β=1/2,我们得到:
C=α∈[0,1]maxI(X;Y)=1−h2(p)
曲线上的一点是当前输入分布的互信息,整条曲线的最大值才是容量。若总发送同一个确定比特,H(X)=0,即使线路完全无噪声,也没有新的随机消息可供区分。
几个边界能检验这个公式:
| 翻转概率 | 容量(bit/次使用) | 原因 |
| p=0 | 1 | 输入可以完整恢复 |
| p=0.11 | 约 0.500 | 均匀输入时,约一半的输出熵来自不可预测的翻转 |
| p=0.5 | 0 | 输出与输入独立,任何输入分布的互信息都为零 |
| p=1 | 1 | 输出必为输入的反值,接收端取反即可恢复 |
因此随机性最强的 p=0.5 最有破坏性,确定性翻转本身并不丢失信息。对于一般的离散无记忆信道,容量写成 C=maxP(X)I(X;Y);最优输入不一定均匀。相关定理见 MIT 6.441 第 16 章。
香农定理保证的是怎样的“可靠”?
一个块码把 M 条可能的消息分别映射成长度为 n 的码字。速率为:
R=nlog2Mbit / 信道使用
解码器根据整段接收序列估计消息。下面用 Pe 表示等概率消息下的块错误概率:整条消息解错的概率,它不同于单个信道比特被翻转的概率 p。
对离散无记忆信道,固定 R<C,存在速率趋近该值的码序列,使 n→∞ 时 Pe→0。反之,固定 R>C 时,不存在块错误概率趋于零的码序列。
圆点代表码字,外围色块示意噪声带来的接收区域:消息更密集时,区域更容易重叠。平面位置不表示汉明距离,圆的大小也不是错误概率;这张图只帮助理解容量的空间直觉。
图中的门槛描述渐近可达性。它没有给出某个有限块长的错误率,也没有说在 R=C 的边界上任意码都可靠。低于容量是存在好码的条件,具体实现还要选择码、解码器和块长。
“加更多冗余也救不了 R>C”也要读准确:如果多发送一些信道符号,实际速率 R 就可能下降,甚至降到容量以下。逆定理禁止的是保持速率高于容量,同时还要求错误概率趋于零。
一个计数直觉:为什么 BSC 容量是 1−h2(p)?
对 0<p<1/2 的长 BSC 块,典型噪声模式的数量具有约 2nh2(p) 的指数规模。一个码字经过噪声后,会对应一片可能的接收序列。若有约 2nR 个码字,而接收空间总共只有 2n 个二元串,要让各消息的高概率接收区域足够容易区分,就会出现计数关系:
2nR2nh2(p)≲2n⟹R≲1−h2(p)
它把上一章的典型集与容量连接起来。这是指数尺度的直觉,不是有限长度下互不相交区域的完整证明。严格定理需要可达性与逆定理两部分;噪声事件也不要求全部都被纠正。
先在 64 个位置上看清“争用空间”
下面枚举六位接收串。每个码字的半径 t 邻域含 Vt=∑j=0t(j6) 个串;t=1 时是 7 个。若这些邻域要互不重叠,必须有 MVt≤64,但满足计数条件并不保证某个实际码本就能做到。图中直接检查每个位置的归属,而不是把平面距离当成汉明距离。
正在呈现知识画面
接收空间有限,更多码字怎样争用它?枚举 6 位接收空间的全部 64 个字符串。增加码字、改变噪声邻域半径,观察唯一覆盖与重叠,并独立计算 p=0.1 时的精确平均 ML 块错误率;有限邻域与渐近容量计数分别说明。
{"id":"channel-packing","title":"接收空间有限,更多码字怎样争用它?","summary":"枚举 6 位接收空间的全部 64 个字符串。增加码字、改变噪声邻域半径,观察唯一覆盖与重叠,并独立计算 p=0.1 时的精确平均 ML 块错误率;有限邻域与渐近容量计数分别说明。","height":850,"html":"<p class=\"eyebrow\" data-i18n=\"eyebrow\"></p><h2 data-i18n=\"heading\"></h2><p class=\"intro\" data-i18n=\"intro\"></p>\n<div class=\"packing-controls\"><div><p class=\"control\" data-i18n=\"messages\"></p><div class=\"presets\" role=\"group\" data-i18n-label=\"messages\"><button data-count=\"2\">2</button><button data-count=\"4\">4</button><button data-count=\"8\">8</button><button data-count=\"16\">16</button></div></div><div><p class=\"control\" data-i18n=\"radius\"></p><div class=\"presets\" role=\"group\" data-i18n-label=\"radius\"><button data-radius=\"0\">0</button><button data-radius=\"1\">1</button><button data-radius=\"2\">2</button></div></div></div>\n<div class=\"metrics\"><div class=\"metric\"><span data-i18n=\"rate\"></span><strong id=\"rate\"></strong><span>C ≈ 0.531</span></div><div class=\"metric\"><span data-i18n=\"error\"></span><strong id=\"error\"></strong></div></div>\n<div class=\"space-wrap\"><div><div id=\"space\" role=\"img\" data-i18n-label=\"space\"></div><div class=\"space-legend\"><span class=\"unique\" data-i18n=\"unique\"></span><span class=\"overlap\" data-i18n=\"overlap\"></span><span class=\"codeword\" data-i18n=\"codeword\"></span></div></div><div class=\"space-readout\"><p class=\"note\" data-i18n=\"gridNote\"></p><div class=\"occupancy-stack\"><div class=\"formula\" id=\"occupancy\"></div><div class=\"formula reserve\" id=\"occupancy-reserve\" aria-hidden=\"true\"></div></div><p class=\"note\" id=\"noise-mass\"></p></div></div>\n<label class=\"control\" for=\"received\"><span data-i18n=\"received\"></span><output id=\"received-value\"></output></label><input id=\"received\" type=\"range\" min=\"0\" max=\"63\" value=\"0\">\n<div class=\"probe\" aria-live=\"polite\"><span data-i18n=\"owners\"></span><strong id=\"owners\"></strong><span data-i18n=\"nearest\"></span><div class=\"nearest-stack\"><strong id=\"nearest\"></strong><strong class=\"reserve\" aria-hidden=\"true\">000000, 000000, 000000 (d=6)</strong></div></div>\n<details class=\"audit-details\"><summary data-i18n=\"details\"></summary><div class=\"formula\" id=\"codebook\"></div><p class=\"note\" data-i18n=\"capacity\"></p><div class=\"formula\" id=\"asymptotic\"></div><p class=\"note\" data-i18n=\"asymptoticNote\"></p><p class=\"note\" data-i18n=\"errorNote\"></p></details>","css":"\n.intro { margin:8px 0 14px; color:var(--muted); font-size:14px; }\n.presets { display:flex; flex-wrap:wrap; margin:12px 0; }\n.presets button { flex:1 1 auto; min-width:0; }\n.control { display:flex; align-items:center; justify-content:space-between; gap:12px; margin-top:12px; font-size:14px; }\n.control output { flex-shrink:0; font-variant-numeric:tabular-nums; font-weight:600; }\n.metrics { grid-template-columns:repeat(2,minmax(0,1fr)); margin:12px 0; }\n.metric strong { font-size:23px; }.metric span { font-size:12px; overflow-wrap:anywhere; }\n.note { color:var(--muted); font-size:12px; line-height:1.65; margin-top:10px; }\n.formula { font-size:14px; font-variant-numeric:tabular-nums; overflow-wrap:anywhere; margin:10px 0; }\n.copy-stack { display:grid; margin:12px 0; font-size:13px; line-height:1.65; }\n.copy-stack > p { grid-area:1/1; min-width:0; }.reserve { visibility:hidden; pointer-events:none; user-select:none; }\n.audit-details { border-top:1px solid var(--rule); margin-top:14px; padding-top:10px; font-size:13px; }\n.audit-details summary { cursor:pointer; color:var(--accent); min-height:32px; padding:5px 0; }\n.audit-details summary:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }\n@media(max-width:480px){.intro{font-size:13px}.metric strong{font-size:21px}.presets button{font-size:13px}.formula{font-size:13px}}\n\n.packing-controls { display:grid; grid-template-columns:1fr 1fr; gap:16px; }.packing-controls .presets { margin:6px 0; }.packing-controls button { padding-inline:8px; }.packing-controls .control { margin:0; }\n.space-wrap { display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:20px; margin-top:16px; }#space { display:grid; grid-template-columns:repeat(8,minmax(0,1fr)); gap:3px; }.cell { display:grid; place-items:center; height:29px; border-radius:3px; background:var(--surface); color:var(--muted); font-size:12px; font-variant-numeric:tabular-nums; }.cell.unique { background:var(--accent-soft); color:var(--ink); }.cell.overlap { background:repeating-linear-gradient(135deg,transparent 0 4px,var(--second-soft) 4px 8px),var(--paper);color:var(--ink);border-bottom:2px solid var(--second); }.cell.codeword { box-shadow:inset 0 0 0 1.5px var(--ink); font-weight:700; }.cell.selected { outline:2px solid var(--accent); outline-offset:1px; }\n.space-legend { display:flex; flex-wrap:wrap; gap:4px 12px; font-size:11px; margin-top:8px; }.space-legend span::before{content:'';display:inline-block;width:10px;height:10px;margin-right:4px;background:var(--accent-soft);border:1px solid var(--accent)}.space-legend .overlap::before{background:var(--second-soft);border-color:var(--second)}.space-legend .codeword::before{background:var(--paper);border-color:var(--ink)}\n.probe { display:grid; grid-template-columns:auto minmax(0,1fr); gap:6px 12px; font-size:13px; margin-top:6px; }.probe strong { font-weight:500; text-align:right; font-variant-numeric:tabular-nums; overflow-wrap:anywhere; }.probe span{color:var(--muted)}\n.occupancy-stack,.nearest-stack{display:grid;min-width:0}.occupancy-stack>div,.nearest-stack>strong{grid-area:1/1;min-width:0}.nearest-stack strong{font-family:var(--viz-font-ui)}.probe{grid-template-columns:minmax(0,1fr) minmax(0,1.3fr)}#occupancy,#occupancy-reserve{line-height:1.8}#codebook{font-size:12px;line-height:1.8}#received-value { font-family:var(--viz-font-ui); }\n@media(max-width:600px){.space-wrap{grid-template-columns:1fr;gap:4px}.space-readout{display:grid;grid-template-columns:1fr 1fr;gap:0 10px}.space-readout>p:first-child{grid-column:1/-1}#occupancy{margin:6px 0}.packing-controls{gap:8px}#space{max-width:360px;margin:auto}.cell{height:25px}.space-wrap{margin-top:10px}.probe{font-size:12px}}\n","js":"const $=s=>document.querySelector(s),bits=x=>x.toString(2).padStart(6,'0'),dist=(a,b)=>bits(a^b).replaceAll('0','').length;let count=4,radius=1;\n// Fixed nested codebooks: greedily maximize distance to existing codewords, break ties by integer value.\nconst book=[0];while(book.length<16){let best=-1,score=-1;for(let v=0;v<64;v++){if(book.includes(v))continue;const d=Math.min(...book.map(c=>dist(v,c)));if(d>score){score=d;best=v;}}book.push(best);}\nfor(let i=0;i<64;i++){const e=document.createElement('span');e.className='cell';e.textContent=i.toString().padStart(2,'0');$('#space').append(e);}\nfunction draw(){const codes=book.slice(0,count),y=+$('#received').value,p=.1,vol=[1,7,22][radius],h=viz.entropy([p,1-p]),rate=Math.log2(count)/6;let overlaps=0,covered=0,success=0;\n for(let v=0;v<64;v++){const ds=codes.map(c=>dist(v,c)),owners=ds.filter(d=>d<=radius).length;overlaps+=owners>1;covered+=owners>0;success+=Math.max(...ds.map(d=>p**d*(1-p)**(6-d)))/count;const e=$('#space').children[v];e.classList.toggle('unique',owners===1);e.classList.toggle('overlap',owners>1);e.classList.toggle('codeword',codes.includes(v));e.classList.toggle('selected',v===y);e.dataset.coverage=owners;e.setAttribute('aria-label',bits(v)+': '+owners);}\n const ds=codes.map(c=>dist(y,c)),min=Math.min(...ds),near=codes.filter((c,i)=>ds[i]===min),ownerCount=ds.filter(d=>d<=radius).length,noiseMass=[.9**6,.9**6+6*.1*.9**5,.9**6+6*.1*.9**5+15*.1**2*.9**4][radius];\n $('#rate').textContent=viz.number(rate,3);$('#error').textContent=viz.number((1-success)*100,3)+'%';$('#received-value').textContent=bits(y)+' / '+y;\n $('#occupancy').textContent='M·Vₜ = '+count+' × '+vol+' = '+count*vol+'; '+viz.t('covered')+' '+covered+'/64; '+viz.t('overlap')+' '+overlaps+'/64';$('#noise-mass').textContent='P(d ≤ '+radius+') = '+viz.number(noiseMass*100,3)+'%';\n $('#occupancy-reserve').textContent='M·Vₜ = 16 × 22 = 352; '+viz.t('covered')+' 64/64; '+viz.t('overlap')+' 64/64';$('#owners').textContent=ownerCount+' / '+count;$('#nearest').textContent=near.map(bits).join(', ')+' (d='+min+')';$('#codebook').textContent=viz.t('codeword')+': '+codes.map(bits).join(' · ');$('#asymptotic').textContent='n = 120: 2^[n(R+h₂(p))] = 2^'+viz.number(120*(rate+h),2)+'; 2^n = 2^120';\n $('#space').setAttribute('aria-label',viz.t('space')+' M='+count+', t='+radius+', '+viz.t('covered')+' '+covered+'/64; '+viz.t('overlap')+' '+overlaps+'/64.');document.querySelectorAll('[data-count]').forEach(e=>e.setAttribute('aria-pressed',String(+e.dataset.count===count)));document.querySelectorAll('[data-radius]').forEach(e=>e.setAttribute('aria-pressed',String(+e.dataset.radius===radius)));}\n document.querySelectorAll('[data-count]').forEach(e=>e.addEventListener('click',()=>{count=+e.dataset.count;draw();}));document.querySelectorAll('[data-radius]').forEach(e=>e.addEventListener('click',()=>{radius=+e.dataset.radius;draw();}));$('#received').addEventListener('input',draw);draw();","audio":false,"strings":{"asymptoticNote":"保持当前 R,设想块长变为 120。这里比较典型噪声邻域总需求与接收空间的指数规模,忽略次指数因子;不是上面短码的扩展仿真,也不是精确的典型集条数。R+h₂(p)>1 时需求的指数超过空间,连接到容量门槛 R<C。","capacity":"容量 C≈0.531 bit/次。这里 n 固定为 6;R<C 也不保证这个短码的错误率接近零。","codeword":"码字","covered":"已覆盖","details":"完整码本、渐近计数与错误率口径","error":"精确平均 ML 块错误率","errorNote":"码本按最大化到已有码字的最小距离逐个构造,同分取较小整数,不宣称全局最优。错误率按等概率消息、全部 64 个接收串精确求和:Pₑ=1−Σᵧ max꜀ P(y|c)/M。最近码字并列时可固定选一项。t 仅改变展示的邻域,不改变信道或 ML 解码器,所以调 t 不改变 Pₑ;重叠格数也不是错误概率。","eyebrow":"有限接收空间 → 渐近计数","gridNote":"编号 00–63 对应六位二进制串,按数值排列;屏幕上的远近不是汉明距离。空白格未被半径 t 的邻域覆盖。","heading":"消息更多时,噪声邻域怎样重叠?","intro":"固定 n=6、BSC p=0.1。每个码字周围取距离 ≤t 的接收串,增加消息数 M,观察它们怎样争用 64 个位置。","messages":"消息数 M","nearest":"最近码字","overlap":"重叠","owners":"半径 t 内的候选数","radius":"邻域半径 t","rate":"R · bit/次","received":"检查一个接收串","space":"全部 64 个接收串的邻域覆盖图","unique":"唯一覆盖"}}
邻域重叠、漏掉的噪声尾部和最终解码错误,是不同的对象。 对固定码本,图中用完整 BSC 概率计算平均最大似然(ML)块错误率,邻域半径仅用于观察。即使邻域互不重叠,距离超过 t 的噪声仍可能导致错误。
长块讨论把小图中的有限邻域替换成概率趋近 1 的典型噪声集合,其规模约为 2nh2(p)。此时总需求的指数是 n(R+h2(p)),接收空间的指数是 n。这解释了容量计数的来源,但并未由六位演示证明随机编码定理;下面的 Hamming 码再展示一个具体的纠错结构。
一个真实小码:为什么距离 3 能纠正 1 位?
两个等长二元串的 Hamming 距离,就是不同位置的数量。一个码的最小距离 dmin 是任意两个不同合法码字之间的最小距离。
若接收串最多偏离原码字 t 位,并且每两个合法码字都至少相距 2t+1,原码字就是唯一最近的候选。原因是三角不等式:如果同一个接收串距离两个码字都不超过 t,那两个码字之间的距离就不超过 2t,与条件矛盾。
dmin≥2t+1
下面使用真正的 Hamming (7,4) 码:4 位消息变成 7 位码字,共有 16 个合法码字,最小距离为 3。点击接收串中的位即可引入翻转,下面同时显示全部候选与它们到接收串的距离。
正在呈现知识画面
翻转接收位,看最小码距怎样保护消息固定发送消息 0000,编码为 Hamming(7,4) 的全零码字。点击七个接收位引入翻转,实时比较与全部 16 个合法码字的距离:一位错误能纠正,两位错误会被误纠正。
{"id":"channel-hamming","title":"翻转接收位,看最小码距怎样保护消息","summary":"固定发送消息 0000,编码为 Hamming(7,4) 的全零码字。点击七个接收位引入翻转,实时比较与全部 16 个合法码字的距离:一位错误能纠正,两位错误会被误纠正。","height":950,"html":"<p class=\"eyebrow\" data-i18n=\"eyebrow\"></p><h2 data-i18n=\"heading\"></h2><p class=\"intro\" data-i18n=\"intro\"></p>\n<div class=\"sent\"><span data-i18n=\"sent\"></span><strong>0000 → 0000000</strong></div>\n<fieldset><legend data-i18n=\"received\"></legend><div id=\"received-bits\"></div></fieldset>\n<div class=\"reset-row\"><span><span data-i18n=\"flips\"></span> <strong id=\"flip-count\"></strong></span><button id=\"reset\" data-i18n=\"reset\"></button></div>\n<div class=\"decoded\"><span data-i18n=\"decoded\"></span><strong id=\"decoded\"></strong></div>\n<div class=\"formula\">d<sub>min</sub> = 3 ≥ 2t + 1 ⇒ t<sub>max</sub> = 1</div>\n<div class=\"copy-stack\"><p id=\"explanation\" aria-live=\"polite\"></p><p class=\"reserve\" aria-hidden=\"true\" data-i18n=\"clean\"></p><p class=\"reserve\" aria-hidden=\"true\" data-i18n=\"corrected\"></p><p class=\"reserve\" aria-hidden=\"true\" data-i18n=\"wrong\"></p></div>\n<details class=\"audit-details\"><summary data-i18n=\"detailLabel\"></summary><p class=\"note\" data-i18n=\"candidates\"></p><div id=\"codebook\"></div></details>\n<p class=\"note\" data-i18n=\"note\"></p>","css":".intro { margin:8px 0 18px; color:var(--muted); font-size:14px; }\n.control { display:flex; align-items:center; justify-content:space-between; gap:16px; margin-top:18px; }\n.control output { min-width:4em; flex-shrink:0; text-align:center; background:var(--accent-soft); color:var(--accent); padding:2px 8px; border-radius:6px; font-weight:600; }\n.formula { margin-top:18px; padding:14px 0; border-block:1px solid var(--rule); font-size:16px; font-variant-numeric:tabular-nums; overflow-wrap:anywhere; }\n.copy-stack { display:grid; margin-top:14px; color:var(--muted); font-size:14px; }\n.copy-stack > * { grid-area:1/1; }\n.copy-stack .reserve { visibility:hidden; }\n.note { margin-top:14px; color:var(--muted); font-size:12px; }\n.metric-pair { display:grid; grid-template-columns:1fr 1fr; gap:16px; margin-top:18px; }\n.metric-pair > div { min-width:0; }\n.metric-pair span { display:block; font-size:12px; color:var(--muted); }\n.metric-pair strong { display:block; font-size:24px; font-weight:500; font-variant-numeric:tabular-nums; }\n.scale { display:flex; justify-content:space-between; color:var(--muted); font-size:12px; font-variant-numeric:tabular-nums; }\n@media(max-width:480px) { .metric-pair strong { font-size:21px; } }\n.presets { display:flex; }\n.plot { position:relative; margin-top:18px; height:190px; border-left:1px solid var(--rule); border-bottom:1px solid var(--muted); }\n.plot svg { width:100%; height:100%; overflow:hidden; }\n.plot .curve { fill:none; stroke:var(--accent); stroke-width:2.5; vector-effect:non-scaling-stroke; }\n.plot .curve.secondary { stroke:var(--second); stroke-dasharray:5 4; }\n.scale { position:relative; }.scale .middle { position:absolute; left:50%; transform:translateX(-50%); }\n.formula { font-size:14px; }.formula div+div { margin-top:6px; }\n@media(max-width:480px) { .plot { height:170px; } }\n.plot .curve { transition:d .28s cubic-bezier(.22,1,.36,1); }\n.sent,.decoded { display:flex; flex-wrap:wrap; align-items:baseline; justify-content:space-between; gap:8px; font-size:13px; }.sent strong,.decoded strong { font:600 17px/1.5 var(--viz-font-ui); }\nfieldset { border:0; padding:0; margin:18px 0 0; min-width:0; }legend { font-size:13px; padding:0; margin-bottom:8px; }\n#received-bits { display:grid; grid-template-columns:repeat(7,minmax(0,1fr)); gap:6px; }#received-bits button { min-height:50px; display:flex; flex-direction:column; gap:0; padding:5px; }#received-bits small { font-size:10px; color:var(--muted); }#received-bits strong { font-size:19px; }#received-bits button[aria-pressed='true'] { background:var(--second-soft); color:var(--second); border-color:var(--second); }\n.reset-row { display:flex; justify-content:space-between; align-items:center; margin-top:10px; font-size:13px; }\n#codebook { display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:6px; margin-top:10px; }\n.codeword { padding:7px 6px; text-align:center; border:1px solid var(--rule); border-radius:6px; background:var(--surface); transition:background .2s,border-color .2s; }.codeword code { display:block; font:13px/1.4 var(--viz-font-mono); }.codeword span { display:block; font-size:11px; color:var(--muted); }.codeword.sent-word { box-shadow:inset 0 0 0 1px var(--ink); }.codeword.nearest { background:var(--accent-soft); border-color:var(--accent); }.codeword.nearest.mistaken { background:var(--second-soft); border-color:var(--second); }\n.decoded { margin-top:16px; }\n@media(max-width:480px) { #received-bits { grid-template-columns:repeat(4,minmax(0,1fr)); }#codebook { grid-template-columns:repeat(2,minmax(0,1fr)); } }\n\n.decoded{margin-top:12px}.copy-stack{margin-top:10px}.formula{margin-top:10px;padding:10px 0}.note{margin-top:10px}\n@media(max-width:480px){#received-bits{grid-template-columns:repeat(4,minmax(0,1fr));gap:5px}#received-bits button{padding:4px 0;min-width:0}.intro{font-size:13px;margin-bottom:12px}.sent{margin-top:12px}.copy-stack{font-size:13px}}\n\n.audit-details { border-top:1px solid var(--rule); margin-top:14px; padding-top:8px; }\n.audit-details summary { cursor:pointer; color:var(--accent); font-size:13px; min-height:36px; padding:6px 0; }\n.audit-details summary:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }\n.audit-details .formula { border:0; margin-top:8px; padding:8px 0; }\n","js":"function encode(value){const [a,b,c,d]=value.toString(2).padStart(4,'0').split('').map(Number);return [a^b^d,a^c^d,a,b^c^d,b,c,d];}\nconst words=Array.from({length:16},(_,i)=>encode(i)),received=Array(7).fill(0),bits=document.querySelector('#received-bits'),book=document.querySelector('#codebook');\nfor(let i=0;i<7;i++){const button=document.createElement('button');button.type='button';button.innerHTML='<small>'+(i+1)+'</small><strong>0</strong>';button.setAttribute('aria-label',viz.t('bit')+' '+(i+1));button.addEventListener('click',()=>{received[i]^=1;draw();});bits.append(button);}\nwords.forEach(word=>{const item=document.createElement('div');item.className='codeword';item.innerHTML='<code>'+word.join('')+'</code><span></span>';book.append(item);});\nfunction draw(){const distances=words.map(word=>word.reduce((s,bit,i)=>s+(bit!==received[i]),0)),nearest=distances.indexOf(Math.min(...distances)),flips=received.reduce((a,b)=>a+b,0);\n received.forEach((bit,i)=>{bits.children[i].querySelector('strong').textContent=bit;bits.children[i].setAttribute('aria-pressed',String(!!bit));});\n distances.forEach((d,i)=>{const el=book.children[i];el.classList.toggle('sent-word',i===0);el.classList.toggle('nearest',i===nearest);el.classList.toggle('mistaken',nearest!==0);el.querySelector('span').textContent='d = '+d;});\n document.querySelector('#flip-count').textContent=flips;document.querySelector('#decoded').textContent=words[nearest].join('')+' → '+nearest.toString(2).padStart(4,'0');document.querySelector('#explanation').textContent=viz.t(flips===0?'clean':flips===1?'corrected':'wrong');\n}\ndocument.querySelector('#reset').addEventListener('click',()=>{received.fill(0);draw();});draw();","audio":false,"strings":{"bit":"翻转接收位","candidates":"全部 16 个合法码字;d 是与当前接收串不同的位置数。","clean":"没有翻转,接收串就是原码字,距离为 0。其他合法码字至少相距 3 位,这段间隔为纠错留下了空间。","corrected":"只有一位翻转。原码字距离为 1,其他合法码字至少距离 2,因此原码字仍是唯一最近的候选,四位消息被正确还原。","decoded":"最近码字 → 解码消息","detailLabel":"展开全部 16 个合法码字","eyebrow":"从最小码距到纠错半径","flips":"翻转位数","heading":"只差一位时,为什么还能认出原来的消息?","intro":"点击接收位,0 与 1 互换。深色边框标记真正发送的码字,彩色背景标记最近候选;候选位置始终不变。","note":"本图使用实际偶校验 Hamming(7,4) 码和最近码字解码,不依赖随机采样。速率为 4/7、最小距离为 3;有限小码的纠错演示并不是达到香农容量的证明。","received":"接收串:点击任意位翻转","reset":"清除翻转","sent":"固定发送","wrong":"已超出单错纠正范围。最近候选变成另一个合法码字,解码结果出错。这个 Hamming 码总能找到唯一最近候选,但唯一不代表正确。"}}
这里把数据位放在位置 3,5,6,7,三个偶校验位放在位置 1,2,4。若四个数据位为 a,b,c,d,码字是:
(a⊕b⊕d, a⊕c⊕d, a, b⊕c⊕d, b, c, d)
固定发送全零码字,只是为了容易看出哪些位被翻转;这个线性码对其他消息也有相同的单错纠正能力。图中采用最近码字解码,它在 BSC 的 p<1/2 且消息等概率时也是最大似然解码。
任意一位翻转都能纠正;两位翻转时,这个码会更接近另一个合法码字,导致误纠正。事实上它的 16 个半径为 1 的邻域恰好覆盖所有 27=128 个接收串,所以最近码字总是唯一,但唯一并不等于正确。更高错误重量也不在单错保证之内。
这个小码不是香农极限的证明。其速率固定为 4/7≈0.571。若 BSC 的 p=0.1,最近码字解码成功当且仅当噪声至多翻转一位,因此:
Pe=1−(1−p)7−7p(1−p)6≈0.1497
这时容量约为 0.531,低于这个码的速率。示例展示的是一个有限码怎样纠错,而不是固定此速率就能让错误任意小。
进入高斯信道前:密度与微分熵
前面使用离散概率。实数信号改用概率密度 f(x),区间上的概率是密度的积分;密度的值本身不是某个实数出现的概率,也可以大于 1。微分熵定义为:
h(X)=−∫f(x)log2f(x)dx.
例如 X 均匀分布在宽度为 a 的区间上,密度为 1/a,所以 h(X)=log2a。当 a<1 时它为负;把同一个量换一种单位,其数值也会改变。一般有 h(cX)=h(X)+log2∣c∣(c=0,相关熵存在)。
因此微分熵不是“精确编码一个实数需要多少 bit”。实际编码必须说明量化精度;而下一节比较相同坐标和单位下的高斯输出与噪声,熵差中的共同尺度项会抵消。KL 和互信息在适当可逆坐标变换下保持不变。
AWGN:对数与 1/2 从哪里来?
实数加性高斯白噪声信道写作:
Y=X+N,N∼N(0,σ2),E[X2]≤P
噪声与输入独立,σ2>0,每次使用的噪声独立。必须给出平均功率约束,否则允许无限增大信号功率就没有有限容量上界。
给定 X 后,Y 只是噪声的平移,所以 h(Y∣X)=h(N)。这里 h 是微分熵。高斯噪声的熵是:
h(N)=21log2(2πeσ2)
而 Var(Y)≤P+σ2。给定方差时高斯分布的微分熵最大,因此:
I(X;Y)=h(Y)−h(N)≤21log2σ2P+σ2
取独立的零均值高斯输入 X∼N(0,P) 可达到等号,于是:
C=21log2(1+SNR)=log2σNσY,SNR=σ2P
后一种写法尤其直观:高斯分布的标准差扩大多少倍,微分熵就增加这个倍数的对数。 用方差比表达时,因为标准差是方差的平方根,对数前出现 1/2。
正在呈现知识画面
高斯分布变宽,熵差按对数增长固定噪声方差为 1,使用达到容量的高斯输入。改变功率 P,输出标准差成为 √(1+P),容量等于标准差比的对数。下方独立的熵条带把 h(Y) 分成固定 h(N) 和新增容量。
{"id":"channel-awgn","title":"高斯分布变宽,熵差按对数增长","summary":"固定噪声方差为 1,使用达到容量的高斯输入。改变功率 P,输出标准差成为 √(1+P),容量等于标准差比的对数。下方独立的熵条带把 h(Y) 分成固定 h(N) 和新增容量。","height":950,"html":"<p class=\"eyebrow\" data-i18n=\"eyebrow\"></p><h2 data-i18n=\"heading\"></h2><p class=\"intro\" data-i18n=\"intro\"></p>\n<label class=\"control\" for=\"power\"><span data-i18n=\"control\"></span><output id=\"power-value\"></output></label><input id=\"power\" type=\"range\" min=\"0\" max=\"150\" value=\"30\" step=\"1\">\n<div class=\"legend\"><span class=\"noise\" data-i18n=\"noise\"></span><span class=\"output\" data-i18n=\"output\"></span></div>\n<div class=\"plot\"><svg viewBox=\"0 0 600 190\" preserveAspectRatio=\"none\" role=\"img\" data-i18n-label=\"chart\"><path id=\"output-density\" class=\"curve\"/><path id=\"noise-density\" class=\"curve secondary\"/></svg></div>\n<div class=\"scale\"><span>−12</span><span class=\"middle\">0</span><span>12</span></div>\n<div class=\"formula\"><div id=\"variance-ratio\"></div><div id=\"capacity-formula\"></div></div>\n<p class=\"note\" data-i18n=\"entropy\"></p><div class=\"entropy-track\"><div id=\"noise-entropy\"></div><div id=\"capacity-extra\"></div></div><div class=\"scale\"><span>0</span><span>4.5 bit</span></div>\n<div class=\"metric-pair\"><div><span data-i18n=\"base\"></span><strong id=\"base\"></strong></div><div><span data-i18n=\"capacity\"></span><strong id=\"capacity\"></strong></div></div>\n<p class=\"note\" data-i18n=\"note\"></p>","css":".intro { margin:8px 0 18px; color:var(--muted); font-size:14px; }\n.control { display:flex; align-items:center; justify-content:space-between; gap:16px; margin-top:18px; }\n.control output { min-width:4em; flex-shrink:0; text-align:center; background:var(--accent-soft); color:var(--accent); padding:2px 8px; border-radius:6px; font-weight:600; }\n.formula { margin-top:18px; padding:14px 0; border-block:1px solid var(--rule); font-size:16px; font-variant-numeric:tabular-nums; overflow-wrap:anywhere; }\n.copy-stack { display:grid; margin-top:14px; color:var(--muted); font-size:14px; }\n.copy-stack > * { grid-area:1/1; }\n.copy-stack .reserve { visibility:hidden; }\n.note { margin-top:14px; color:var(--muted); font-size:12px; }\n.metric-pair { display:grid; grid-template-columns:1fr 1fr; gap:16px; margin-top:18px; }\n.metric-pair > div { min-width:0; }\n.metric-pair span { display:block; font-size:12px; color:var(--muted); }\n.metric-pair strong { display:block; font-size:24px; font-weight:500; font-variant-numeric:tabular-nums; }\n.scale { display:flex; justify-content:space-between; color:var(--muted); font-size:12px; font-variant-numeric:tabular-nums; }\n@media(max-width:480px) { .metric-pair strong { font-size:21px; } }\n.presets { display:flex; }\n.plot { position:relative; margin-top:18px; height:190px; border-left:1px solid var(--rule); border-bottom:1px solid var(--muted); }\n.plot svg { width:100%; height:100%; overflow:hidden; }\n.plot .curve { fill:none; stroke:var(--accent); stroke-width:2.5; vector-effect:non-scaling-stroke; }\n.plot .curve.secondary { stroke:var(--second); stroke-dasharray:5 4; }\n.scale { position:relative; }.scale .middle { position:absolute; left:50%; transform:translateX(-50%); }\n.formula { font-size:14px; }.formula div+div { margin-top:6px; }\n@media(max-width:480px) { .plot { height:170px; } }\n.plot .curve { transition:d .28s cubic-bezier(.22,1,.36,1); }\n.legend { display:flex; flex-wrap:wrap; gap:12px; margin-top:10px; font-size:12px; }.legend span::before { content:''; display:inline-block; width:16px; margin-right:6px; vertical-align:middle; border-top:2px solid var(--accent); }.legend .noise::before { border-color:var(--second); border-top-style:dashed; }\n.entropy-track { height:25px; display:flex; margin-top:8px; background:var(--surface); }#noise-entropy { background:var(--second); }#capacity-extra { background:var(--accent); transition:width .28s; }\n","js":"const input=document.querySelector('#power'),noiseEntropy=.5*Math.log2(2*Math.PI*Math.E);\nfunction density(sigma){return Array.from({length:481},(_,i)=>{const x=-12+i/20,y=Math.exp(-x*x/(2*sigma*sigma))/(Math.sqrt(2*Math.PI)*sigma);return(i?'L':'M')+(i*600/480).toFixed(3)+','+(190*(1-y/.45)).toFixed(3);}).join(' ');}\ndocument.querySelector('#noise-density').setAttribute('d',density(1));document.querySelector('#noise-entropy').style.width=noiseEntropy/4.5*100+'%';document.querySelector('#base').textContent=viz.number(noiseEntropy,3)+' bit';\nfunction draw(){const power=+input.value/10,ratio=Math.sqrt(1+power),capacity=Math.log2(ratio);document.querySelector('#power-value').textContent=viz.number(power,1);document.querySelector('#output-density').setAttribute('d',density(ratio));\n document.querySelector('#variance-ratio').textContent='σY / σN = √(1 + '+viz.number(power,1)+') ≈ '+viz.number(ratio,3);\n document.querySelector('#capacity-formula').textContent='C = log₂(σY / σN) = ½ log₂(1 + '+viz.number(power,1)+') ≈ '+viz.number(capacity,3)+' bit';\n document.querySelector('#capacity-extra').style.width=capacity/4.5*100+'%';document.querySelector('#capacity').textContent=viz.number(capacity,3)+' bit';\n}\ninput.addEventListener('input',draw);draw();","audio":false,"strings":{"base":"固定噪声熵 h(N)","capacity":"熵差 h(Y) − h(N) = C","chart":"固定噪声与高斯输出的概率密度,横轴为 −12 至 12,纵轴固定为 0 至 0.45。","control":"输入功率 P(σ² = 1)","entropy":"熵条带:金色是 h(N),蓝色是 C,两段合计为 h(Y)。","eyebrow":"标准差的倍数 → 熵差","heading":"为什么容量是 ½ log₂(1 + SNR)?","intro":"噪声保持不变。增加高斯输入的功率,观察输出分布如何变宽,以及这对应多少额外的信息。","noise":"虚线:固定噪声 N","note":"密度图统一使用 x ∈ [−12,12]、密度 0–0.45 的标尺。两条完整密度积分均为 1,容量不是它们的面积差。这里使用独立高斯输入和平均功率约束;下方熵条带另用 0–4.5 bit 标尺,容量单位为 bit/实数信道使用。","output":"实线:输出 Y = X + N"}}
图中固定噪声方差为 1,并使用达到容量的高斯输入。P=0 时,输出分布等于噪声,容量为 0;P=3 时标准差比是 2,熵差为 1 bit;P=15 时比值是 4,熵差为 2 bit。两条完整密度曲线下的积分都是 1,容量不是它们的面积差。
这个推导也解释了功率收益的对数增长。高 SNR 下把功率翻倍,每次实数信道使用的容量大约只增加 0.5 bit。若限制为二元输入或其他星座,通常不能直接取得这里高斯输入的容量。参阅 MIT 6.441 第 17 章。
连续时间、带宽为 B 的标准实数 AWGN 模型,若双边噪声功率谱密度为 N0/2,带内噪声功率为 N0B,常写成 C=Blog2(1+P/(N0B)) bit/s。它与上面的“每次实数使用”单位不同,不能直接比较系数。
从理论极限到工程实现
编码定理给出可达速率的边界,实际系统还需要指定块长、目标块错误率、译码延迟、功耗和计算预算。Hamming、Reed–Solomon、turbo、LDPC、polar 等码针对不同结构和约束取舍;不能仅凭“码字更长”或某个码族名称就断言已经接近容量。
随机编码论证说明好码存在,但直接存储庞大码本并穷举译码通常不实用。工程的重要工作,是找到有结构、能高效编码和解码、并且满足有限长度性能要求的码。
信源—信道分离:先对齐单位,再比较速率
源编码消除信源的可预测冗余,信道编码再有目的地加入纠错冗余。对于经典点对点、有限字母表平稳遍历信源与离散无记忆信道,在允许长块的条件下,可以先压缩再纠错,实现渐近最优的可靠传输条件。
如果信源每秒产生 fs 个符号,熵率为 Hˉ bit/信源符号;信道每秒使用 fc 次,容量为 C bit/次使用,那么应比较:
fsHˉ<fcC
例如每秒 1000 个源符号、熵率 0.4 bit/符号,需要约 400 bit/s 的渐近信息率;每秒使用 1000 次、容量 0.5 bit/次的信道提供 500 bit/s 的理论预算,可以在两者之间选择压缩输出率和信道码率。有限块的开销与目标可靠性仍须单独计算。
分离结论有适用条件。短延迟、多用户网络或其他严格约束下,独立优化压缩和纠错可能不再最合适。相关边界见 MIT 6.441 第 20 章。下一篇讨论允许一定信息损失时的率失真与信息瓶颈。
参考