Unidad 6 · Ecualizadores adaptativos · realimentación de decisiones, ZF-DFE, propagación de errores y simulación en MATLAB
El ecualizador lineal zero forcing saca la ISI invirtiendo el canal, y donde el canal tiene un pozo levanta el ruido junto con la señal. El DFE —decision feedback equalizer, ecualizador por realimentación de decisiones— saca la misma ISI sin levantar el ruido, porque la parte que viene de símbolos pasados no la filtra: la resta, armando una réplica con los símbolos que el slicer ya decidió. En la cadena canal → AGC → ecualizador → slicer, el DFE pone el slicer adentro del ecualizador. Lo que paga a cambio es que, cuando una decisión sale mal, la réplica también sale mal.
El punto de partida es el modelo de la filmina: a la salida del filtro adaptado blanqueado (WMF) los símbolos ven un canal discreto causal y mónico, y el ruido es blanco.
El DFE le resta a la ISI que dejaron los símbolos anteriores, calculada con las decisiones que ya se tomaron sobre ellos, y recién ahí decide:
En diagrama es un lazo: la salida del slicer entra a un filtro y lo que sale se resta a la entrada, z_k → (+) → slicer → â_k, con â_k → M(z) − 1 → (−) cerrando la vuelta. Tiene dos piezas, y cada una se ocupa de una mitad de la ISI:
Que sea mónico no es un detalle: por , el filtro de realimentación no tiene tap en retardo cero, así que para calcular sólo necesita , que ya están. Con un tap en cero el lazo sería una ecuación en que depende de su propia decisión.
La muestra que el receptor usa para decidir lleva pedazos de los vecinos de los dos lados. Después del filtro adaptado, lo que cae en el instante es la autocorrelación del pulso, que es simétrica: si un símbolo pasado ensucia la muestra, un símbolo futuro la ensucia igual. Lo que viene de los pasados es la ISI causal, los poscursores; lo que viene de los futuros, la anticausal, los precursores.
Las dos no son el mismo problema, y la razón es de calendario. Cuando el receptor está por decidir , ya decidió : sabe, o cree saber, cuánto aportó. Un poscursor es un número conocido que se resta. De no sabe nada todavía, así que un precursor no se puede restar: hay que deshacerlo con un filtro, y un filtro no distingue señal de ruido. El DFE usa cada herramienta donde puede: filtro para la mitad que no se conoce, resta para la mitad que sí.
La filmina lo dice en una línea: la ISI residual a la entrada del slicer proviene sólo de símbolos pasados, y si conocemos los símbolos pasados podemos cancelarla restando una réplica.
La filmina llega al DFE en dos pasos, y el segundo es moverle un solo bloque al primero.
Paso 1: el ecualizador lineal también es un lazo. Si lo que se realimenta por es la propia salida , el lazo con realimentación negativa da con y :
Es el LE-ZF, escrito de otra manera. Lo que da vuelta por el lazo es , que trae ruido, así que el ruido se realimenta y sale filtrado por , igual que la señal.
Paso 2: meter el slicer adentro del lazo. Ahora lo que da vuelta es , un símbolo de la constelación, sin ruido. Si las decisiones pasadas son correctas, la resta cancela la ISI de término a término:
El ruido que llega al slicer es tal cual salió del WMF: no pasó por ningún filtro. El slicer, que al cuantizar tira el ruido de lo que decide, limpia justamente lo que se va a restar.
Paso 3: poner los dos ruidos lado a lado. Con varianza a la salida del WMF y la respuesta al impulso de :
La desigualdad sale de que (la inversa de un mónico es mónica), y es igualdad sólo sin ISI. Con un solo poscursor, , la inversa es y la suma es geométrica:
Con el canal tiene un pozo de −20 dB en , porque , y el LE paga 7,21 dB de relación señal a ruido en el slicer. El DFE, con decisiones correctas, no paga nada. Simulado en MATLAB con dB y símbolos PAM-2, la SNR medida a la entrada del slicer da 2,79 dB para el LE, contra 2,79 de la cuenta, y 10,00 dB para el DFE alimentado con los símbolos verdaderos. Por qué el LE levanta el ruido justo en el pozo, y cómo se ve en frecuencia, es tema de la nota del zero forcing.
El DFE de la filmina es un zero forcing: anula toda la ISI, la de adelante con el filtro y la de atrás con la resta. De dónde sale el reparto lo dice la factorización espectral de la Unidad 5. El canal que ven los símbolos a la salida del filtro adaptado, , se parte en una mitad causal y su espejo anticausal:
con mónico y de fase mínima. El filtro hacia adelante divide por la mitad anticausal y por ; lo que queda es , sólo poscursores, y eso es lo que la realimentación resta. El ruido en el slicer es el del WMF, . El LE-ZF, en cambio, divide por entero y deja un ruido de PSD . Con símbolos de energía 1, las dos relaciones señal a ruido, más la del filtro adaptado solo sin ISI (la cota de filtro adaptado, que es la energía del pulso), quedan como tres promedios del mismo espectro:
Cada una dividida por . Las desigualdades son las de siempre entre medias, por Jensen, y son igualdades sólo si es plano: sin ISI los tres receptores son el mismo. Para el canal los tres promedios salen cerrados: , y . Promediados numéricamente sobre 200 000 frecuencias con dan 1,810000, 1,000000 y 0,190000. En decibeles, contra el ZF-DFE: la cota está 2,58 dB arriba y el LE-ZF 7,21 dB abajo.
Por qué fase mínima. El reparto no es arbitrario: de los ceros de , que vienen en pares y , a le tocan los de adentro del círculo. Así el filtro hacia adelante, que invierte la mitad de afuera, es estable siendo anticausal. Y hay una razón más fina: de todas las maneras de escribir como con causal, la de fase mínima es la que pone más energía en el primer tap, , y el primer tap es el único con el que el DFE decide. Se ve con un canal de fase máxima, , donde el eco pesa el doble que el pulso principal. tiene ceros en −2 y −0,5; quedarse con el de adentro da con : el filtro hacia adelante da vuelta el canal y deja el tap grande primero. Simulado a 10 dB con símbolos, el ruido a la salida del WMF sigue blanco (varianza 0,1001 contra 0,1, correlación a un símbolo 0,0003), y el DFE con el filtro hacia adelante da una BER de 1,05·10⁻³. El mismo DFE aplicado directo sobre , decidiendo sobre un cursor de 0,5 y restando un poscursor de 1, da 1,02·10⁻¹: cien veces peor con el mismo ruido y la misma energía recibida. Las dos BER coinciden con la forma cerrada de la sección siguiente: 1,043·10⁻³ y 1,022·10⁻¹.
Todo lo anterior vale con decisiones correctas. Si una sale mal, la réplica que se resta está mal, y a la entrada del slicer queda
El último término es ISI que no estaba en el canal: la metió el propio ecualizador. En lugar de sacar la interferencia, una decisión equivocada inyecta otra, y eso sube la probabilidad de equivocarse en los símbolos siguientes. Los errores dejan de venir sueltos y vienen en ráfagas. Es lo que la filmina anota como «tiene errores de propagación».
Con un solo poscursor y PAM-2 la cuenta sale cerrada, y conviene hacerla porque dice cuánto cuesta. Un error en es , así que el término inyectado vale , el doble del eco:
La mitad de las veces tiene el signo de y el término lo aleja del umbral; la otra mitad lo acerca, a , y si lo cruza. Como es independiente de todo lo anterior, lo que pasa en depende de la historia sólo por si la decisión anterior estuvo bien o mal. Son dos probabilidades:
la de equivocarse después de un acierto y la de equivocarse después de un error. Es una cadena de Markov de dos estados, y de ahí sale todo:
Medido en MATLAB con , 10 dB y símbolos: 15 357 errores repartidos en 7767 ráfagas, de largo medio 1,977 contra 1,989 de la cuenta, y la más larga de 12. La probabilidad de equivocarse después de un error da 0,4942 contra 0,4971. Las fracciones de ráfagas de largo 1, 2, 3 y 4 o más dan 0,506 · 0,251 · 0,120 · 0,123, y la geométrica 0,503 · 0,250 · 0,124 · 0,123. El control es el genio sobre el mismo registro: de sus 7775 errores, sólo 3 vinieron pegados a otro, que es lo que da la independencia —se esperan unos 6—. Y una advertencia de método: con 2·10⁶ símbolos el histograma todavía baila de semilla a semilla; en una, las ráfagas de largo 3 y 4 salieron 140 y 122 contra 198 y 99 esperadas. La forma geométrica se ve con registros largos o no se ve.
En decibeles la propagación cuesta poco, y cada vez menos. Duplicar la BER en la cola de una gaussiana se compensa con una fracción de decibel, y cuanto más abajo se mira, más chica es esa fracción. Con , despejando de la forma cerrada, el DFE real necesita respecto del genio 0,54 dB más a BER 10⁻³, 0,39 a 10⁻⁴, 0,30 a 10⁻⁵ y 0,25 a 10⁻⁶. El LE-ZF necesita 7,21 dB más en los cuatro, exactos, porque lo único que le queda en el slicer es ruido gaussiano más grande: su penalidad sí es un corrimiento de la curva, a diferencia de la que deja la ISI sin ecualizar.
El techo de 2 es de este caso. Con más taps de realimentación, un error contamina tantos símbolos como taps tenga , y con más niveles un error puede valer más que el doble del eco; ahí la cuenta de Markov tiene más estados y las ráfagas pueden ser más largas.
El mismo canal , el mismo ruido, dB, y el eco creciendo. Las columnas del LE y del DFE son las formas cerradas; la medida es del DFE real, sobre 2·10⁶ símbolos PAM-2, con entre 1600 y 3100 errores por fila:
| m₁ | pozo en π | penalidad del LE | BER LE-ZF | BER DFE | DFE medido | ráfaga media |
|---|---|---|---|---|---|---|
| 0 | 0 dB | 0 dB | 7,827 · 10⁻⁴ | 7,827 · 10⁻⁴ | 7,990 · 10⁻⁴ | 1,00 |
| 0,3 | −3,10 dB | 0,41 dB | 1,278 · 10⁻³ | 8,245 · 10⁻⁴ | 8,370 · 10⁻⁴ | 1,05 |
| 0,5 | −6,02 dB | 1,25 dB | 3,085 · 10⁻³ | 1,043 · 10⁻³ | 1,061 · 10⁻³ | 1,33 |
| 0,7 | −10,46 dB | 2,92 dB | 1,196 · 10⁻² | 1,417 · 10⁻³ | 1,432 · 10⁻³ | 1,81 |
| 0,9 | −20,00 dB | 7,21 dB | 8,404 · 10⁻² | 1,554 · 10⁻³ | 1,555 · 10⁻³ | 1,99 |
| 0,95 | −26,02 dB | 10,11 dB | 1,617 · 10⁻¹ | 1,560 · 10⁻³ | 1,558 · 10⁻³ | 2,00 |
| 0,99 | −40,00 dB | 17,01 dB | 3,278 · 10⁻¹ | 1,561 · 10⁻³ | 1,562 · 10⁻³ | 2,00 |
Las dos columnas de BER cuentan historias opuestas. La del LE sigue al pozo: cada decibel que el canal se hunde en se lo cobra en ruido, y con el pozo a −40 dB se equivoca en uno de cada tres símbolos. La del DFE apenas se mueve: sube hasta duplicarse y ahí se queda, que es el techo de la sección anterior. La BER del DFE con genio no está en la tabla porque sería la misma en todas las filas, : con decisiones correctas el canal no entra en la cuenta. La simulación del LE reproduce su columna —8,423·10⁻² medido contra 8,404·10⁻² con —, y la primera fila es el control: sin eco, los tres receptores son el mismo.
Frente al detector de secuencias, el DFE es la versión barata de una idea que ya estaba en el slicer tira información que está ahí: lo que dicen las muestras vecinas sirve para decidir. El DFE lo aprovecha a medias. Usa las muestras pasadas para quitar interferencia, pero la energía de que cae en la trata como ruido a restar y no como evidencia, y además apuesta a su decisión sin guardar alternativas: es un Viterbi de un solo sobreviviente. Sobre el canal de aquel ensayo, contra la cota de filtro adaptado, las pérdidas asintóticas quedan ordenadas: 6,99 dB el slicer solo, 2,22 dB el LE-ZF, 0,97 dB el DFE con decisiones correctas, y nada el detector de secuencias. Las dos del medio son y , los promedios de la sección 04. Y si en vez de anular la ISI se busca minimizar ISI más ruido, el criterio es otro: el MSE.
Al subir el eco pasan dos cosas a velocidades muy distintas. La curva del LE se corre a la derecha, rígida, tantos decibeles como indica la penalidad; con el pozo a −20 dB ya está a siete decibeles. La del DFE se despega de la del genio apenas, y abajo aparecen las barras rojas: errores que no puso el ruido sino la resta equivocada. A 10 dB, con ya son el 45 % de las ráfagas las que tienen más de un error, y con 0,9 la mitad. Tildá el genio: las barras rojas desaparecen, porque la resta ya no puede equivocarse, y los errores vuelven a venir sueltos; los pocos que caen pegados los juntó el azar, no la resta. Lo que separa las dos curvas del DFE es todo lo que cuesta la propagación.
Ningún script de la clase tiene un DFE: los ecualizadores adaptativos de la cátedra son lineales. En MATLAB el DFE no se puede escribir con filter, porque el slicer está adentro del lazo; va un for sobre los símbolos. Lo que figura como comentario es la salida real de correrlo en R2026a.
%% 1. El canal del WMF, M(z) = 1 + m1 z^-1, con PAM-2 y ruido blanco rng(2); N = 1e7; m1 = 0.9; % pozo en pi: |M|^2 = (1-m1)^2, -20 dB SNRdB = 10; % 1/sigma^2 a la salida del WMF sigma = 10^(-SNRdB/20); a = 2*randi([0 1], N, 1) - 1; z = filter([1 m1], 1, a) + sigma*randn(N, 1); %% 2. LE-ZF: F(z) = 1/M(z) x_le = filter(1, [1 m1], z); a_le = 2*(x_le >= 0) - 1; %% 3. DFE-ZF con sus propias decisiones: el slicer adentro del lazo x_d = zeros(N, 1); a_d = zeros(N, 1); previa = 0; for k = 1:N x_d(k) = z(k) - m1*previa; % resta la réplica del poscursor a_d(k) = 2*(x_d(k) >= 0) - 1; previa = a_d(k); end %% 4. DFE-ZF con el genio: realimenta los símbolos verdaderos x_g = z - m1*[0; a(1:end-1)]; a_g = 2*(x_g >= 0) - 1; %% 5. BER medida contra forma cerrada p0 = qfunc(1/sigma); % error sin error previo p1 = qfunc((1+2*m1)/sigma)/2 + qfunc((1-2*m1)/sigma)/2; % error tras un error e_le = a_le ~= a; e_d = a_d ~= a; e_g = a_g ~= a; fprintf('LE-ZF %.4e cerrada %.4e\n', mean(e_le), qfunc(sqrt(1-m1^2)/sigma)) fprintf('DFE genio %.4e cerrada %.4e\n', mean(e_g), p0) fprintf('DFE real %.4e cerrada %.4e\n', mean(e_d), p0/(1 - p1 + p0)) % LE-ZF 8.4101e-02 cerrada 8.4039e-02 % DFE genio 7.7750e-04 cerrada 7.8270e-04 % DFE real 1.5357e-03 cerrada 1.5541e-03 %% 6. SNR a la entrada del slicer fprintf('SNR LE %.2f dB cerrada %.2f dB\n', 10*log10(1/var(x_le - a)), SNRdB + 10*log10(1 - m1^2)) fprintf('SNR DFE %.2f dB (real) %.2f dB (genio)\n', 10*log10(1/var(x_d - a)), 10*log10(1/var(x_g - a))) % SNR LE 2.79 dB cerrada 2.79 dB % SNR DFE 9.79 dB (real) 10.00 dB (genio) %% 7. Las ráfagas: corridas de errores consecutivos borde = diff([0; e_d; 0]); largo = find(borde == -1) - find(borde == 1); fprintf('%d errores en %d ráfagas, largo medio %.3f (cerrada %.3f), máximo %d\n', ... sum(e_d), numel(largo), mean(largo), 1/(1 - p1), max(largo)) fprintf('P(error | error previo) real %.4f (cerrada %.4f) genio %.5f\n', ... sum(e_d(2:end) & e_d(1:end-1))/sum(e_d(1:end-1)), p1, ... sum(e_g(2:end) & e_g(1:end-1))/sum(e_g(1:end-1))) frac = histcounts(largo, [0.5 1.5 2.5 3.5 Inf]) / numel(largo); fprintf('largo 1, 2, 3, 4+: medido %s geométrica %s\n', mat2str(frac, 3), ... mat2str([(1-p1)*p1.^(0:2), p1^3], 3)) % 15357 errores en 7767 ráfagas, largo medio 1.977 (cerrada 1.989), máximo 12 % P(error | error previo) real 0.4942 (cerrada 0.4971) genio 0.00039 % largo 1, 2, 3, 4+: medido [0.506 0.251 0.12 0.123] geométrica [0.503 0.25 0.124 0.123] %% 8. Cuánto cuesta en dB, a BER 1e-4 Pe_real = @(s) qfunc(1/s) / (1 - qfunc((1+2*m1)/s)/2 - qfunc((1-2*m1)/s)/2 + qfunc(1/s)); s_g = fzero(@(s) log(qfunc(1/s)) - log(1e-4), 0.3); s_d = fzero(@(s) log(Pe_real(s)) - log(1e-4), s_g); fprintf('a 1e-4: genio %.2f dB, DFE real %.2f dB (+%.2f), LE-ZF +%.2f dB\n', ... -20*log10(s_g), -20*log10(s_d), 20*log10(s_g/s_d), -10*log10(1 - m1^2)) % a 1e-4: genio 11.41 dB, DFE real 11.80 dB (+0.39), LE-ZF +7.21 dB %% 9. El filtro hacia adelante: un canal de fase máxima, h = [0.5 1] h = [0.5 1]; rho = conv(h, fliplr(h)); % S_h(z): [0.5 1.25 0.5] c = roots(rho); % ceros en pares recíprocos M = poly(c(abs(c) < 1)); % la mitad de adentro: mónica, fase mínima g2 = rho(2) / sum(M.^2); % gamma^2 fprintf('ceros %s -> M = %s, gamma^2 = %.4f\n', mat2str(c.', 3), mat2str(M, 3), g2) % ceros [-2 -0.5] -> M = [1 0.5], gamma^2 = 1.0000 r = filter(h, 1, a) + sigma*randn(N, 1); y = filter(fliplr(h), 1, r); y = y(2:end); % filtro adaptado (anticausal) w = flipud(filter(1, g2*M, flipud(y))); % precursor 1/(g2 M*(1/z*)), anticausal w = w(1:end-100); b = a(1:end-101); % fuera el borde del anticausal ruido = w - filter(M, 1, b); fprintf('ruido a la salida del WMF: varianza %.4f, correlación a un símbolo %.4f\n', ... var(ruido), corr(ruido(2:end), ruido(1:end-1))) % ruido a la salida del WMF: varianza 0.1001, correlación a un símbolo 0.0003 entradas = {w, r(1:numel(b))}; canales = {M, h}; nombres = {'con filtro hacia adelante', 'sin filtro hacia adelante'}; for caso = 1:2 v = entradas{caso}; m = canales{caso}; ad = zeros(numel(b), 1); previa = 0; for k = 1:numel(b) ad(k) = 2*((v(k) - m(2)*previa) >= 0) - 1; previa = ad(k); end fprintf('%s: BER %.4e\n', nombres{caso}, mean(ad ~= b)) end % con filtro hacia adelante: BER 1.0509e-03 % sin filtro hacia adelante: BER 1.0246e-01
Cuatro detalles que muerden si no se los conoce:
a verdaderos, que se conocen de antemano, y sale en una línea. El bloque 3 necesita la decisión anterior antes de calcular la actual. Con símbolos el for tarda un segundo o dos: se puede.sign no es un slicer. sign(0) da 0, que no es un símbolo, y realimentado resta cero en vez de . Por eso el script decide con 2*(x >= 0) - 1, que siempre devuelve ±1.filter sólo hace causales: el bloque 9 da vuelta la señal, filtra y la vuelve a dar vuelta. El filtro arranca desde el final con estado cero, así que las últimas muestras están mal y se descartan cien. Y el filtro adaptado, , sale de filter(fliplr(h), 1, r) corrido una muestra.for, no con filter, y el slicer tiene que devolver siempre un símbolo.