Salta al contenuto principale

04 - Canale rumoroso e capacità: dalla probabilità d'errore al secondo teorema di Shannon

La capacità del canale binario simmetrico è 1 - H(p): la ricaviamo in tre modi indipendenti e vediamo che cosa il secondo teorema di Shannon garantisce.

Cosa ne pensi di questo articolo?

04 - Canale rumoroso e capacità: dalla probabilità d'errore al secondo teorema di Shannon
Teoria dell'Informazionefedericocalo.dev

In Breve

La capacità del canale binario simmetrico è 1 - H(p): la ricaviamo in tre modi indipendenti e vediamo che cosa il secondo teorema di Shannon garantisce.

Un bit su dieci, ogni tanto, arriva capovolto: succede su un disco che invecchia, su un collegamento radio disturbato, su un Wi-Fi lontano dal router. Tu vuoi consegnare i dati senza errori, e la soluzione ovvia è ripetere ogni bit tre volte e votare a maggioranza. Funziona (l'errore scende al 2,8%), ma la velocità cala a un terzo. La domanda che questo articolo risolve è: quanto velocemente si può comunicare in modo affidabile su un canale che sbaglia con probabilità p? La risposta di Shannon è un numero, la capacità C = 1 - H2(p), che per p = 0,1 vale 0,531 bit per uso del canale. Sotto quella velocità esistono codici con errore piccolo quanto vuoi, e la ripetizione è lontanissima dal migliore; sopra, nessun codice può avere errore piccolo a piacere. Il teorema è però un enunciato di esistenza: non ti consegna il codice, e non dice quanto deve essere lungo. Vediamo l'enunciato preciso, calcoliamo la capacità in tre modi indipendenti e simuliamo un canale per vedere i numeri muoversi.

Che cosa è un canale e che cosa misura la capacità

Un canale discreto senza memoria è una tabella Q(y|x): per ogni simbolo x in ingresso, la probabilità di ricevere ciascun y, indipendentemente da ciò che è accaduto agli usi precedenti. Il canale binario simmetrico (BSC, dall'inglese binary symmetric channel) ha ingressi e uscite in {0, 1} e capovolge il bit con probabilità p, uguale nei due versi. Un codice a blocchi (N, K) è un elenco di 2K parole di lunghezza N; la sua velocità è R = K/N bit per uso del canale. Con queste definizioni, che seguono MacKay (§9.6), la capacità si definisce come massimo dell'informazione mutua sulla distribuzione dell'ingresso: C = maxP(x) I(X;Y).

La definizione sembra astratta, ma ha un significato concreto: l'informazione mutua I(X;Y) = H(Y) - H(Y|X) è quanta incertezza sull'ingresso scompare quando vedi l'uscita. Per il BSC, se l'ingresso vale 1 con probabilità q, l'uscita vale 1 con probabilità q(1-p) + (1-q)p, mentre H(Y|X) = H2(p) non dipende da q, perché il rumore ha la stessa forza qualunque bit tu mandi. Quindi I = H2(q(1-p) + (1-q)p) - H2(p), e il primo termine raggiunge il suo massimo, 1 bit, quando l'uscita è equiprobabile, cioè con q = 1/2. Ne segue C = 1 - H2(p), la formula (1.35) di MacKay.

Tre modi indipendenti di calcolare la stessa capacità

Una formula che ti ho appena derivato a mano non è ancora una formula verificata. Il listato che segue la controlla in tre modi che non condividono il ragionamento: la forma chiusa con SymPy, la ricerca del massimo di I(X;Y) calcolata dalla definizione su 2001 valori di q, e l'algoritmo di Blahut-Arimoto, che trova la capacità di un canale qualunque iterando sulla distribuzione d'ingresso senza sapere nulla di simmetrie. Le funzioni info_mutua e blahut_arimoto accettano una matrice Q qualsiasi: per questo, nella seconda metà, le uso anche su due canali che non sono simmetrici.

import math
import numpy as np
import sympy as sp
from scipy.optimize import minimize_scalar


def h2(p):
    """Entropia binaria in bit, con la convenzione 0 log 0 = 0."""
    if p in (0.0, 1.0):
        return 0.0
    return -p * math.log2(p) - (1 - p) * math.log2(1 - p)


def info_mutua(px, Q):
    """I(X;Y) in bit dalla definizione: somma di p(x) Q(y|x) log2( Q(y|x) / p(y) )."""
    py = px @ Q
    total = 0.0
    for x in range(Q.shape[0]):
        for y in range(Q.shape[1]):
            if px[x] > 0 and Q[x, y] > 0:
                total += px[x] * Q[x, y] * math.log2(Q[x, y] / py[y])
    return total


def blahut_arimoto(Q, iterazioni=3000):
    """Capacita' di un canale discreto senza memoria, per iterazione (Blahut-Arimoto)."""
    n_x = Q.shape[0]
    r = np.full(n_x, 1.0 / n_x)
    for _ in range(iterazioni):
        q = r @ Q
        c = np.ones(n_x)
        for x in range(n_x):
            for y in range(Q.shape[1]):
                if Q[x, y] > 0:
                    c[x] *= (Q[x, y] / q[y]) ** Q[x, y]
        r = r * c / np.sum(r * c)
    return info_mutua(r, Q), r


def bsc(f):
    return np.array([[1 - f, f], [f, 1 - f]])


def bec(f):  # uscite: 0, ?, 1
    return np.array([[1 - f, f, 0.0], [0.0, f, 1 - f]])


def canale_z(f):  # 0 arriva sempre come 0; 1 arriva come 0 con probabilita' f
    return np.array([[1.0, 0.0], [f, 1 - f]])


# 1) Formula chiusa con frazioni esatte (SymPy)
p = sp.symbols("p", positive=True)
C = 1 + p * sp.log(p, 2) + (1 - p) * sp.log(1 - p, 2)
chiusa = sp.Rational(3, 4) * sp.log(3, 2) - 1  # H2(1/4) = 2 - (3/4) log2 3
print("p = 1/4 : C - ((3/4) log2 3 - 1) =", sp.simplify(C.subs(p, sp.Rational(1, 4)) - chiusa), "; valore", sp.N(chiusa, 12))
print("p = 1/2 :", sp.simplify(C.subs(p, sp.Rational(1, 2))))
print("C(p) - C(1-p) a p = 1/10 :", sp.simplify(C.subs(p, sp.Rational(1, 10)) - C.subs(p, sp.Rational(9, 10))))

# 2) Tre modi indipendenti per lo stesso numero: formula, massimo su una griglia, Blahut-Arimoto
print()
print("   f   formula  griglia  Blahut-Arimoto")
for f in (0.01, 0.1, 0.15, 0.2, 0.5):
    formula = 1 - h2(f)
    Q = bsc(f)
    griglia = max(info_mutua(np.array([1 - q, q]), Q) for q in np.linspace(0, 1, 2001))
    ba, _ = blahut_arimoto(Q)
    print(f"{f:5.2f}   {formula:.6f}  {griglia:.6f}  {ba:.6f}")

# 3) Canali non simmetrici: cancellazione e canale Z, f = 0.15 (MacKay, esempi 9.11 e esercizio 9.13)
f = 0.15
cap_bec, _ = blahut_arimoto(bec(f))
print()
print(f"BEC f=0.15: Blahut-Arimoto {cap_bec:.6f}   formula 1-f = {1 - f:.6f}")
cap_z, r = blahut_arimoto(canale_z(f))
# Seconda via: massimo di H2(p1 (1-f)) - p1 H2(f), eq. 9.14 di MacKay, con un ottimizzatore scalare
res = minimize_scalar(lambda p1: -(h2(p1 * (1 - f)) - p1 * h2(f)), bounds=(0, 1), method="bounded",
                      options={"xatol": 1e-12})
print(f"Z   f=0.15: Blahut-Arimoto {cap_z:.6f} con P(X=1)={r[1]:.4f}   ottimizzatore {-res.fun:.6f} con P(X=1)={res.x:.4f}")
print(f"            con ingresso uniforme: {info_mutua(np.array([0.5, 0.5]), canale_z(f)):.6f}")

# Uscita:
# p = 1/4 : C - ((3/4) log2 3 - 1) = 0 ; valore 0.188721875541
# p = 1/2 : 0
# C(p) - C(1-p) a p = 1/10 : 0
#
#    f   formula  griglia  Blahut-Arimoto
#  0.01   0.919207  0.919207  0.919207
#  0.10   0.531004  0.531004  0.531004
#  0.15   0.390160  0.390160  0.390160
#  0.20   0.278072  0.278072  0.278072
#  0.50   0.000000  0.000000  0.000000
#
# BEC f=0.15: Blahut-Arimoto 0.850000   formula 1-f = 0.850000
# Z   f=0.15: Blahut-Arimoto 0.685418 con P(X=1)=0.4449   ottimizzatore 0.685418 con P(X=1)=0.4449
#             con ingresso uniforme: 0.678788

La prima riga dell'uscita mostra che la capacità a p = 1/4 è esattamente (3/4) log2 3 - 1, circa 0,1887, e la seconda che a p = 1/2 vale zero: un canale che capovolge metà dei bit non trasporta nulla. La terza dice che C(p) = C(1-p): un canale che sbaglia quasi sempre è buono quanto uno che sbaglia quasi mai, perché basta invertire ciò che ricevi. La tabella mostra che le tre colonne coincidono alla sesta cifra; i valori 0,919, 0,531 e 0,278 sono quelli di p uguale a 0,01, 0,1 e 0,2, e p = 0,15 dà 0,390, il numero 0,39 di MacKay (esempio 9.9). Il listato usa solo SymPy 1.14, NumPy 2.3 e SciPy 1.16 sotto Python 3.14, ed è deterministico.

Canali non simmetrici: cancellazione e canale Z

Nella seconda metà dell'uscita compaiono due canali con f = 0,15. Il canale a cancellazione (BEC, binary erasure channel) non capovolge mai un bit: con probabilità f lo sostituisce con un simbolo «?» che il ricevitore riconosce. La sua capacità è 1 - f = 0,85, e Blahut-Arimoto la ritrova a sei cifre. Il confronto con il BSC è istruttivo: un BSC con p = 0,15 arriva a 0,390 bit, il BEC con la stessa probabilità a 0,85, perché nel BEC sai dove l'informazione è andata persa e non devi indovinare quali bit siano sbagliati.

Il canale Z non è simmetrico: lo 0 arriva sempre come 0, l'1 arriva come 0 con probabilità f. Qui l'ingresso uniforme non è ottimale: l'informazione mutua vale 0,6788 con P(X=1) = 0,5 e sale a 0,6854 con P(X=1) ≈ 0,445, valore che coincide con quello di MacKay (esempio 9.11, 0,685 con 0,445) e che due procedure diverse, Blahut-Arimoto e un ottimizzatore scalare sulla formula (9.14), trovano entrambe. La lezione è che «l'uniforme è ottimale» è una proprietà del BSC e del BEC, non della capacità: la massimizzazione sull'ingresso fa parte della definizione e non va saltata.

Che cosa afferma il secondo teorema di Shannon

Shannon lo enuncia nel paragrafo 13 del suo articolo del 1948 (teorema 11); MacKay (§10.1) lo scrive in tre parti per un canale discreto senza memoria:

  1. per ogni ε > 0 e ogni velocità R < C, per N abbastanza grande esiste un codice di lunghezza N e velocità almeno R, con una decodifica per cui la probabilità massima di errore sul blocco è minore di ε;
  2. se accetti una probabilità di errore sul bit pb, sono raggiungibili velocità fino a R(pb) = C / (1 - H2(pb));
  3. per ogni pb, velocità superiori a R(pb) non sono raggiungibili.

La prima parte è la garanzia; la terza è il limite. La seconda è la parte che si dimentica ed è la più utile in pratica: accettare un errore di bit dell'1% porta il limite da 0,531 a 0,578 bit per uso, e un errore del 5% a 0,744. Questo non contraddice il converso: è la teoria della compressione con perdita che incontri nell'articolo 6 della serie, perché ammettere errori significa buttare informazione. Dall'ultima riga dell'uscita del listato si vede anche che, con pb = p = 0,1, il limite vale esattamente 1: puoi usare il canale senza codice, e ricevi proprio il 10% di errori.

Altrettanto importante è che cosa il teorema non dice:

  • quanto deve essere grande N perché l'errore scenda sotto una soglia data, né come N dipende dalla distanza C - R;
  • come si costruisce il codice: la dimostrazione di Shannon è per scelta casuale, e il paragrafo 14 del suo articolo osserva che, a parte casi banali, non si conosce una descrizione esplicita di codici che si avvicinino al limite;
  • che l'errore diventi zero a lunghezza finita: diventa piccolo a piacere, mai nullo, per il BSC o il BEC;
  • nulla su ritardo e complessità di codifica e decodifica, che crescono con N.

Una conseguenza pratica è che la capacità serve a misurare quanto sei lontano dal meglio possibile, non a progettare. Quando un codice reale lavora a una velocità dichiarata e a una certa probabilità d'errore, il confronto con C dice quanto margine teorico resta, e nulla più: i codici costruiti con vincoli di complessità si valutano con i loro parametri, che è il tema dell'articolo successivo.

Perché la ripetizione non basta: il prezzo dell'affidabilità

Il codice a ripetizione RN invia ogni bit N volte e decide a maggioranza; con N = 3 l'errore sul bit è 3p² - 2p³ (MacKay, eq. 1.36), cioè 7/250 = 0,028 per p = 0,1. Il listato verifica la formula in tre modi: la frazione esatta, la somma binomiale e una simulazione a seme fisso di un milione di bit, e ricava quanto deve crescere N per portare l'errore sotto una soglia. La simulazione serve a confrontare la frequenza misurata con quella teorica: l'errore standard di una frequenza su n prove è √(p(1-p)/n), e lo scarto va letto in quelle unità.

import math
from fractions import Fraction
import numpy as np

SEME = 20261113
p = Fraction(1, 10)
C = 1 + 0.1 * math.log2(0.1) + 0.9 * math.log2(0.9)  # capacita' del BSC con p = 0.1


def pb_ripetizione(N, p):
    """Probabilita' esatta di errore su un bit con codice a ripetizione R_N (N dispari), decodifica a maggioranza."""
    return sum(math.comb(N, k) * p**k * (1 - p) ** (N - k) for k in range((N + 1) // 2, N + 1))


# 1) Il canale simulato: frequenza dei bit capovolti contro p
rng = np.random.default_rng(SEME)
n = 1_000_000
flip = rng.random(n) < 0.1
freq = flip.mean()
sigma = math.sqrt(0.1 * 0.9 / n)
print(f"bit capovolti: {freq:.5f} su {n}; teorico 0.1; errore standard {sigma:.5f}; scarto {abs(freq - 0.1) / sigma:.2f} sigma")

# 2) Codice a ripetizione R3: formula chiusa 3p^2 - 2p^3 (MacKay, eq. 1.36), esatta e simulata
print("R3 formula 3p^2-2p^3 =", 3 * p**2 - 2 * p**3, "=", float(3 * p**2 - 2 * p**3))
print("R3 somma binomiale   =", pb_ripetizione(3, p))
bit = rng.integers(0, 2, n)
rx = np.stack([bit ^ (rng.random(n) < 0.1) for _ in range(3)])
decod = (rx.sum(axis=0) >= 2).astype(int)
sim = (decod != bit).mean()
sigma3 = math.sqrt(0.028 * 0.972 / n)
print(f"R3 simulato          = {sim:.5f}; errore standard {sigma3:.5f}; scarto {abs(sim - 0.028) / sigma3:.2f} sigma")

# 3) Quanto costa la ripetizione: il piu' piccolo N dispari con pb < 1e-9, e la sua velocita'
for soglia in (Fraction(1, 10**3), Fraction(1, 10**6), Fraction(1, 10**9)):
    N = 1
    while pb_ripetizione(N, p) >= soglia:
        N += 2
    print(f"pb < {float(soglia):.0e}: N = {N:3d}, velocita' 1/N = {1 / N:.4f}, capacita' {C:.4f}")

# Uscita:
# bit capovolti: 0.09984 su 1000000; teorico 0.1; errore standard 0.00030; scarto 0.52 sigma
# R3 formula 3p^2-2p^3 = 7/250 = 0.028
# R3 somma binomiale   = 7/250
# R3 simulato          = 0.02800; errore standard 0.00016; scarto 0.00 sigma
# pb < 1e-03: N =   9, velocita' 1/N = 0.1111, capacita' 0.5310
# pb < 1e-06: N =  23, velocita' 1/N = 0.0435, capacita' 0.5310
# pb < 1e-09: N =  35, velocita' 1/N = 0.0286, capacita' 0.5310

Il canale simulato capovolge il 9,984% dei bit contro il 10% teorico, a 0,52 errori standard di distanza, quindi compatibile. L'errore di R3 misurato, 0,02800, coincide con 7/250 entro l'errore standard (0,00016). La parte importante è l'ultima: per scendere sotto 10-9 la ripetizione richiede N = 35 e quindi una velocità di 0,0286 bit per uso, circa diciannove volte meno della capacità. Più affidabile significa più lento, con la ripetizione; il secondo teorema afferma che questo scambio non è obbligatorio: la velocità può restare vicina a 0,531 mentre l'errore scende, a patto di accettare blocchi molto più lunghi e codici molto meno ingenui.

Perché il numero è 2nC: contare i rumori

Non dimostro il teorema, che richiede le sequenze congiuntamente tipiche (MacKay §10.2-10.3), ma c'è un conteggio che rende naturale la formula. Su n bit trasmessi, il rumore capovolge circa np posizioni, e i modi di sceglierle sono binom(n, np), circa 2nH2(p). Perché due parole diverse non si confondano, le «nuvole» di 2nH2(p) uscite possibili intorno a ciascuna parola non devono sovrapporsi in modo sistematico, e le uscite totali sono 2n: il numero di parole non può superare circa 2n / 2nH2(p) = 2n(1 - H2(p)). Questo è un argomento di plausibilità, non una dimostrazione, e il listato ne controlla la parte numerica.

import math
import sympy as sp


def h2(p):
    return -p * math.log2(p) - (1 - p) * math.log2(1 - p)


p = 0.1
C = 1 - h2(p)

# 1) Quanti schemi di rumore ci sono: (1/n) log2 binom(n, pn) -> H2(p), e la somma fino a pn ha lo stesso limite
print("   n    (1/n)log2 C(n,pn)   (1/n)log2 V(n,pn)   H2(0.1)")
for n in (10, 100, 1000, 10000):
    t = round(p * n)
    comb = math.comb(n, t)
    vol = sum(math.comb(n, j) for j in range(t + 1))
    print(f"{n:6d}   {math.log2(comb) / n:.6f}          {math.log2(vol) / n:.6f}           {h2(p):.6f}")

# 2) Il limite di Hamming con t = pn tende a 1 - H2(p): stesso valore della capacita'
print()
print("   n    (1/n) log2( 2^n / V(n,pn) )   capacita' 1 - H2(0.1)")
for n in (10, 100, 1000, 10000):
    t = round(p * n)
    vol = sum(math.comb(n, j) for j in range(t + 1))
    print(f"{n:6d}   {(n - math.log2(vol)) / n:.6f}                      {C:.6f}")

# 3) Il converso debole: Fano + dati processati danno nR <= nC + 1 + Pe nR. Si risolve in Pe con SymPy.
n_, R_, C_, Pe = sp.symbols("n R C Pe", positive=True)
soluzione = sp.solve(sp.Eq(n_ * R_, n_ * C_ + 1 + Pe * n_ * R_), Pe)[0]
print()
print("Pe >=", sp.simplify(soluzione))
R = 0.8
for n in (100, 1000, 10000):
    print(f"R = 0.8, C = {C:.4f}, n = {n:5d}:  Pe >= {1 - C / R - 1 / (n * R):.4f}")

# 4) Con un errore di bit accettato, si puo' superare la capacita' (MacKay, eq. 10.2): R(pb) = C / (1 - H2(pb))
print()
for pb in (0.0, 0.001, 0.01, 0.05, 0.1):
    hb = h2(pb) if pb > 0 else 0.0
    print(f"pb = {pb:5.3f}:  R(pb) = {C / (1 - hb):.4f}")

# Uscita:
#    n    (1/n)log2 C(n,pn)   (1/n)log2 V(n,pn)   H2(0.1)
#     10   0.332193          0.345943           0.468996
#    100   0.439767          0.441423           0.468996
#   1000   0.464423          0.464592           0.468996
#  10000   0.468372          0.468389           0.468996
#
#    n    (1/n) log2( 2^n / V(n,pn) )   capacita' 1 - H2(0.1)
#     10   0.654057                      0.531004
#    100   0.558577                      0.531004
#   1000   0.535408                      0.531004
#  10000   0.531611                      0.531004
#
# Pe >= -C/R + 1 - 1/(R*n)
# R = 0.8, C = 0.5310, n =   100:  Pe >= 0.3237
# R = 0.8, C = 0.5310, n =  1000:  Pe >= 0.3350
# R = 0.8, C = 0.5310, n = 10000:  Pe >= 0.3361
#
# pb = 0.000:  R(pb) = 0.5310
# pb = 0.001:  R(pb) = 0.5371
# pb = 0.010:  R(pb) = 0.5777
# pb = 0.050:  R(pb) = 0.7441
# pb = 0.100:  R(pb) = 1.0000

La prima tabella mostra che (1/n) log2 binom(n, pn) si avvicina a H2(0,1) = 0,469 dal basso, 0,4684 a n = 10000, e che sommare tutti i modi fino a pn errori cambia pochissimo, perché a p < 1/2 l'ultimo termine domina la somma. La seconda tabella confronta il limite di Hamming, che incontri nell'articolo 5, con la capacità: con t = pn il tasso massimo della sfera di Hamming tende, dall'alto, a 0,531, lo stesso numero. Questa coincidenza numerica non rende i due enunciati equivalenti: il limite di Hamming riguarda codici che correggono ogni schema di t errori, la capacità riguarda il rumore tipico. Resta un indizio coerente con il conteggio.

Il converso: perché sopra la capacità l'errore non scende

Il lato negativo del teorema ha una dimostrazione breve, che ricavo qui (è la dimostrazione standard, non una citazione). Scegli un messaggio W uniforme tra 2nR; la disuguaglianza di Fano dà H(W|Ŵ) ≤ 1 + Pe nR, e il fatto che il canale è senza memoria dà I(W;Ŵ) ≤ nC. Allora nR = H(W) = H(W|Ŵ) + I(W;Ŵ) ≤ 1 + Pe nR + nC, da cui Pe ≥ 1 - C/R - 1/(nR). Il terzo blocco dell'uscita lo risolve con SymPy e lo valuta per R = 0,8: l'errore resta sopra circa 0,336 al crescere di n, mai vicino a zero. Questa è la forma corretta del converso debole; la frase «Pe ≥ (R - C) / log2|A|» che si trova in alcuni appunti non è la disuguaglianza di Fano.

Per molti canali vale anche il converso forte: sopra la capacità l'errore tende a 1, non soltanto a una costante positiva. Polyanskiy e Wu lo enunciano nel teorema 22.1 (§22.1) per i canali stazionari senza memoria con alfabeto d'ingresso o d'uscita finito, quindi per il BSC e il BEC, e attribuiscono il converso debole alla disuguaglianza di Fano (teorema 17.3). Il paragrafo 22.2 costruisce invece un canale con ingresso numerabile dove il converso forte non vale. Ho letto gli enunciati e le frasi di commento, non le dimostrazioni, che non riporto.

L'esponente di affidabilità

MacKay (§10.7) dà una versione con dipendenza esplicita da N: esistono codici con pB ≤ exp(-N Er(R)), dove Er(R) è l'esponente di codifica casuale (random-coding exponent) del canale, una funzione convessa, decrescente e positiva per 0 ≤ R < C. Si annulla quando R → C: più ti avvicini alla capacità, più il blocco deve essere lungo per ottenere lo stesso errore. MacKay precisa anche che, perfino per il BSC, non esiste un'espressione semplice di Er(R); la base del logaritmo è una convenzione, che il testo fissa a e. Un limite inferiore analogo, con l'esponente di impacchettamento di sfere Esp(R), mostra che l'errore non può decrescere più in fretta di una certa esponenziale.

Errori frequenti

  • Scrivere C = 1 - p. Per p = 0,01 darebbe 0,99, mentre la capacità è 0,919; la differenza è l'entropia dell'errore.
  • Leggere «sotto la capacità» come «senza errori». Il teorema garantisce errore piccolo a piacere con blocchi lunghi, non nullo.
  • Dimenticare la massimizzazione sull'ingresso. Sul canale Z l'ingresso uniforme dà 0,6788 invece di 0,6854.
  • Sommare le capacità senza ipotesi. Per k canali senza memoria usati in parallelo la capacità è la somma (proposizione 19.10 di Polyanskiy e Wu); se i canali non sono indipendenti o c'è memoria, va riderivata.
  • Confondere il teorema con un algoritmo. L'enunciato è di esistenza: per N finito non dice quale codice usare né quanto deve valere N.

Il filo comune è che ogni errore nasce dall'aver trasformato un enunciato asintotico, con un massimo da calcolare, in una regola da applicare a un blocco finito. Ricordare quali ipotesi hai usato (canale senza memoria, ingresso ottimizzato, blocco che tende all'infinito) evita tutti e cinque.

Che cosa sai fare adesso

Sai calcolare la capacità di un canale discreto senza memoria con tre metodi che si controllano a vicenda, e sai che per il BSC vale 1 - H2(p) mentre per il BEC vale 1 - f e per il canale Z va cercato un ingresso non uniforme. Sai enunciare il secondo teorema con le sue tre parti e dire che cosa non promette. Sai che la ripetizione paga l'affidabilità con la velocità (35 ripetizioni per scendere sotto 10-9) e che esiste una distanza fra questo e il limite. Il prossimo passo è vedere che cosa fanno davvero i codici costruiti, a partire dalla distanza di Hamming, nell'articolo 5; il capitolo precedente, sulla compressione senza perdita, è nell'articolo 3, e per i prerequisiti l'informazione mutua è nell'articolo 2 e l'entropia nell'articolo 1; l'indice della serie le raccoglie tutte. Il limite di compressione con perdita che questo teorema anticipa è nell'articolo 6.

Domande frequenti

La capacità è la velocità massima di un codice reale?

No: è il limite superiore per qualunque codice, raggiungibile solo in senso asintotico con blocchi sempre più lunghi. Un codice reale ha una lunghezza finita, un errore residuo e una velocità inferiore a C; il margine rimasto si misura confrontando i suoi parametri con la capacità del canale.

Perché la capacità del BSC con p = 0,5 è zero?

Perché l'uscita è indipendente dall'ingresso: H(Y|X) = H2(1/2) = 1, uguale al massimo di H(Y), e l'informazione mutua vale zero qualunque sia la distribuzione dell'ingresso. Ricevere un bit non ti dice nulla su quello trasmesso.

Si può trasmettere sopra la capacità?

Solo accettando errori: la parte 2 del teorema dà velocità fino a C / (1 - H2(pb)) per una probabilità d'errore di bit pb. Con errore di blocco piccolo a piacere, invece, sopra C non si può, e il converso fissa un errore che non scende.

Fonti

Tutti i listati sono stati eseguiti con Python 3.14 (python3 -I), SymPy 1.14, NumPy 2.3 e SciPy 1.16, due volte ciascuno con uscita identica. La simulazione usa il seme 20261113. La disuguaglianza Pe ≥ 1 - C/R - 1/(nR) è ricavata nel testo e non attribuita a una fonte; la sua risoluzione algebrica è verificata con SymPy.

Commenti

Caricamento commenti...

Accedi per commentare

Discuti questo articolo nella community

Unisciti al gruppo Telegram per discutere con altri sviluppatori, fare domande e condividere le tue esperienze.

Ti è piaciuto questo articolo?

Esplora altri contenuti sul blog o scopri i miei progetti