Unidad 6 · Ecualizadores adaptativos · la inversión del canal, la ISI que anula y el ruido que amplifica
Un canal limitado en banda deja cada símbolo desparramado sobre sus vecinos: es la ISI que el coseno realzado evita cuando el canal es ideal y que vuelve apenas el canal no lo es. El ecualizador es el filtro que se pone entre el canal y el slicer para deshacerla, y el zero forcing es la respuesta más directa: si el canal es , se lo invierte. Anula la ISI entera. El precio lo paga el ruido, que pasa por el mismo inverso y sale amplificado justo donde el canal tenía un pozo.
En la cadena del receptor adaptativo —canal, control de ganancia, ecualizador, slicer, y el error que vuelve al ecualizador— el zero forcing es el ecualizador que se calcularía si el canal fuera conocido. Todo lo que sigue en la unidad existe porque este diseño choca con dos cosas: el canal no se conoce, y el ruido no se puede ignorar.
El modelo de la filmina es el que dejó el filtro adaptado blanqueado: los símbolos atraviesan un canal discreto a tasa de símbolo y se les suma ruido blanco :
Con ISI, no es más ruido: arrastra pedazos de los símbolos vecinos. El detector de secuencias los explica, pero su costo crece exponencialmente con la memoria del canal. Ecualizar es la salida barata: filtrar con un para que la salida se parezca a , y después decidir símbolo por símbolo con el slicer de siempre, como si el canal fuera ideal.
Lo que ven los símbolos de punta a punta es la respuesta combinada canal-ecualizador, la convolución de las dos:
A un ecualizador se lo juzga por , no por . Pero frente al slicer hay dos problemas, ISI y ruido, y un solo filtro para los dos. La filmina lo dice como dos criterios: el zero forcing elimina la ISI y no mira el ruido; el MMSE minimiza el error total y puede dejar algo de ISI. Y el ecualizador es fijo si el canal es conocido, adaptativo si cambia.
El criterio pide que la respuesta combinada sea un impulso, a lo sumo corrido muestras:
La filmina lo escribe con , , porque el que sale del filtro adaptado blanqueado es causal y mónico. El retardo hace falta en cuanto el canal no es de ese tipo (sección 03).
Paso 1: sin ruido. Con , en transformada Z la convolución es un producto:
El slicer recibe los símbolos limpios, con retardo. La ISI se forzó a cero.
Paso 2: leído en el tiempo. es : la respuesta combinada vale 1 en el cursor, , y 0 en todas las demás muestras. Las de son los precursores —lo que un símbolo ensucia antes de su turno— y las de , los poscursores. El zero forcing los anula a todos, pero sólo en los instantes de muestreo: entre muestras no dice nada, y no hace falta, porque el slicer mira sólo ahí. Es el criterio de Nyquist en el tiempo, cumplido por la cascada en lugar del pulso.
Paso 3: leído en frecuencia. Sobre el círculo unitario, , así que
Donde el canal atenúa 5 dB, el ecualizador levanta 5 dB, y la respuesta total queda plana en 0 dB hasta . Es el dibujo de la filmina: bajando a −5 dB, subiendo a +5 dB, y el producto sobre el eje.
Paso 4: con ruido. Por linealidad, el ecualizador trata por separado a la señal y al ruido:
con , la respuesta al impulso del ecualizador. La filmina lo escribe ; la cuenta de arriba dice dónde va el paréntesis: los símbolos pasaron por el canal y el ecualizador lo deshace, pero el ruido entró después del canal y sólo ve el ecualizador. Esa asimetría es toda la sección 05.
Los ceros de son los polos de . Un canal FIR tiene sólo ceros, así que su inverso es un IIR puro, y lo que decide si existe es dónde caen esos polos:
Un canal concreto: el de B_FSE_equalizer.m, el script de la clase. El transmisor pone la raíz del coseno realzado con y el canal es un fir1(10, 0.4) a dos muestras por símbolo. Con la otra raíz en el receptor y muestreado a tasa de símbolo, sin el fir1 la ISI no pasa de 6,4×10⁻⁴ (lo que deja truncar el coseno realzado a 25 símbolos). Con el fir1, el canal discreto que ve un ecualizador a tasa es, normalizado al cursor,
Se toman las trece muestras centrales; lo que queda afuera no pasa de 0,0024. El canal es simétrico, porque el fir1 y las dos raíces lo son, y eso tiene una consecuencia directa: sus ceros vienen en pares recíprocos, y , uno adentro y otro afuera. No es de fase mínima. El par más cercano al círculo es el real, en −0,6321 y −1,5820, y como está sobre el semieje negativo arma el pozo en , o sea en : vale +2,43 dB en continua y −9,61 dB en .
El inverso causal de este canal no sirve: filter(1, m, ...) con un impulso a la entrada da, en la muestra 100, un valor de 5,3×10⁴⁵. El polo en −1,5820 está afuera y la respuesta crece sin freno. El inverso estable existe, pero se extiende para los dos lados sin terminar nunca.
Aunque el canal sea FIR, su inverso es infinito —en un sentido o en los dos—. Lo que se implementa es un FIR de taps, un transversal, y con coeficientes no se puede cumplir en todas las muestras: la respuesta combinada tiene muestras y hay sólo perillas. Hay tres maneras de repartir lo que no alcanza.
Forzar a cero de verdad. Se eligen muestras de alrededor del cursor y se pide que valgan . Es un sistema cuadrado y se cumple exacto. Con , sobre el canal de arriba, los cinco precursores y los cinco poscursores más cercanos dan cero, y la ISI que no se controla aparece justo afuera de la ventana: −0,0277 a seis muestras del cursor y 0,0092 a siete, de los dos lados. Es el nombre del método tomado al pie de la letra.
Mínimos cuadrados. Se minimiza sobre todas las muestras, y se prueba cada . Ya no hay ceros exactos, pero la ISI total es menor: −28,1 dB contra −27,6 dB del forzado, con los mismos once taps. El mejor retardo sale siempre en el centro: los seis del canal más la mitad del ecualizador.
Truncar el inverso. Se calcula el inverso de dos lados —con una FFT larga, muestreado y vuelto al tiempo— y se lo corta a taps centrados. Es lo más directo y lo peor de los tres: con tres taps deja −11,8 dB de ISI contra −13,9 dB de mínimos cuadrados, y con once, −26,2 contra −28,1.
Barriendo con mínimos cuadrados, la ISI residual (potencia de los precursores y poscursores sobre la del cursor) y la ganancia de ruido , que es el tema de la sección que sigue:
| Nf | Δ | ISI residual | ganancia de ruido Σf² |
|---|---|---|---|
| 3 | 7 | −13,9 dB | 1,1773 · 0,71 dB |
| 5 | 8 | −18,0 dB | 1,4415 · 1,59 dB |
| 7 | 9 | −21,3 dB | 1,5938 · 2,02 dB |
| 11 | 11 | −28,1 dB | 1,7419 · 2,41 dB |
| 15 | 13 | −36,6 dB | 1,7882 · 2,52 dB |
| 21 | 16 | −48,5 dB | 1,7995 · 2,55 dB |
| 31 | 21 | −68,4 dB | 1,8007 · 2,55 dB |
| ∞ | — | 0 | 1,8008 · 2,55 dB |
Las dos columnas se mueven en sentido contrario. Cada tap de más baja la ISI, a un ritmo de unos 2 dB por tap, porque la cola del inverso decae geométricamente con el cero más cercano al círculo. Y cada tap de más sube el ruido, hasta clavarse en el valor del inverso infinito. El FIR corto amplifica menos ruido porque invierte menos: no llega a levantar del todo el pozo.
Con el cero en el origen no pasa nada: el canal es un cable y el ecualizador también. Al correrlo hacia −1 se abre un pozo en y se levanta como su imagen en el espejo. Hasta el costo es moderado. Después el pozo se hace hondo rápido y el ruido lo sigue; los taps del FIR decaen como , cada vez más despacio, y con cerca de 1 ni cuarenta taps alcanzan: el eco que queda en es casi tan alto como el cursor.
Por el camino de la señal, el zero forcing hace lo que se le pide: el canal tuerce el espectro de los símbolos y el ecualizador lo endereza. Por el camino del ruido no hay nada que enderezar. llega blanco, con densidad , y el ecualizador le aplica igual su curva:
Dos consecuencias, las dos de la filmina. El ruido ya no es blanco: tiene la forma del inverso del canal, con muestras vecinas correlacionadas. Y es más fuerte. Su potencia es el área bajo esa curva, que por Parseval es la energía de los taps:
Con el cursor normalizado a 1, es cuántas veces más ruido ve el slicer que si el canal fuera el cursor solo. La integral la decide el pozo, no el promedio: es chico donde el canal es fuerte y enorme donde es débil. Si un cero toca el círculo, la integral diverge.
Con el canal del widget la cuenta es cerrada. , una serie geométrica, y la energía de sus taps es otra:
La segunda es la del FIR truncado a taps, que además deja un eco de en la muestra . El pozo vale , y el ruido, contra lo hondo del pozo:
| ρ | pozo en π | ruido, ZF infinito | ruido, FIR de 8 taps | eco del FIR |
|---|---|---|---|---|
| 0 | 0 dB | 1 · 0 dB | 1 | 0 |
| 0,5 | −6,02 dB | 1,3333 · 1,25 dB | 1,3333 | 0,0039 |
| 0,9 | −20,00 dB | 5,2632 · 7,21 dB | 4,2879 | 0,4305 |
| 0,99 | −40,00 dB | 50,251 · 17,01 dB | 7,4644 | 0,9227 |
Cada décima que el cero se acerca al círculo cuesta más que la anterior. De 0,9 a 0,99 el pozo baja 20 dB más y el ruido del zero forcing se multiplica por 9,5. Y el FIR de ocho taps deja de ser un zero forcing: amplifica menos ruido, pero sólo porque deja un eco del 92 % del cursor sin tocar. En MATLAB, las cuatro filas coinciden con el promedio de sobre 65 536 frecuencias y con la energía de los taps de filter(1, [1 rho], ...).
Con el canal de la clase no hay forma cerrada, y se integra numéricamente: = 1,8008 para el inverso infinito, 2,55 dB más de ruido que sin ISI en el cursor. Una simulación con un millón de símbolos, ruido de y el FIR de 31 taps mide a la entrada del slicer una varianza de 1,8012 , contra 1,8007 que predicen sus taps.
El zero forcing de la filmina es un ecualizador lineal (LE): un filtro entre el canal y el slicer, que no usa decisiones. La filmina también lo dibuja como un lazo que le resta a la salida filtrada por , y es el mismo sistema:
Lo lineal es que el lazo toma , con su ruido. Si tomara las decisiones sería el DFE, que saca al ruido del lazo.
¿Contra qué se lo compara? El ideal es el receptor que no tiene ISI que deshacer: el filtro adaptado sobre un símbolo aislado, que junta toda la energía del canal, , contra el mismo ruido. El zero forcing entrega el cursor con ganancia 1 y ruido . La penalidad es el producto, y los dos factores son promedios sobre la banda:
La desigualdad es la de Cauchy-Schwarz: el promedio de una función positiva por el promedio de su inversa nunca baja de 1, y vale 1 sólo si la función es constante. O sea: el zero forcing empata con el ideal sólo si el canal es plano, y cualquier pozo lo aleja. Con el canal del widget vale , que da 2,22 dB con , 9,79 dB con 0,9 y 19,98 dB con 0,99. Con el canal de la clase, 3,00 dB.
La salida a este problema es dejar de perseguir el pozo: el criterio MMSE acepta algo de ISI a cambio de no levantar el ruido donde la señal ya se perdió, y es el tema de el criterio MSE y el ecualizador de Wiener. Ahí el mismo filtro cambia de nombre: la filmina del MSE llama a los taps que acá son , y así siguen el MSEG y el LMS.
Diseño y medición del zero forcing sobre el canal de B_FSE_equalizer.m, a tasa de símbolo. Lo que figura como comentario es la salida real de correrlo en R2026a. El script de la clase, por su parte, corre entero tal como está.
%% 1. El canal: el de B_FSE_equalizer.m, visto a tasa de símbolo N = 2; % muestras por símbolo, como el script g = rcosdesign(0.2, 25, N, 'sqrt'); g = g / sum(g); b = fir1(10, 0.4); % la ISI del script p = conv(conv(g, b), g); % RRC del Tx, canal, RRC del Rx [~, ip] = max(abs(p)); m = p(ip-12:N:ip+12); % 13 muestras a tasa T, centradas m = m / m(7); % cursor = 1 disp(round(m(4:10), 4)) % 0.0215 -0.0702 0.2190 1.0000 0.2190 -0.0702 0.0215 fprintf('lo que queda afuera: %.4f o menos\n', ... max(abs(p([mod(ip-1,N)+1:N:ip-14, ip+14:N:end]))) / p(ip)) % lo que queda afuera: 0.0024 o menos %% 2. Sin el fir1 no hay ISI q = conv(g, g); [~, iq] = max(q); fprintf('ISI del coseno realzado solo: %.1e\n', ... max(abs(q([iq-24:N:iq-2, iq+2:N:iq+24]))) / q(iq)) % ISI del coseno realzado solo: 6.4e-04 %% 3. El pozo, en frecuencia w = linspace(-pi, pi, 2^16+1); w(end) = []; Mw = freqz(m, 1, w); fprintf('|M| en 0: %+.2f dB en pi: %+.2f dB\n', ... 20*log10(abs(freqz(m, 1, [0 pi])))) % |M| en 0: +2.43 dB en pi: -9.61 dB %% 4. Los ceros: de a pares recíprocos, y uno cerca del círculo z = roots(m); [~, i] = sort(abs(abs(z) - 1)); disp(z(i(1:2)).') % -0.6321 -1.5820 %% 5. El ZF de largo infinito: ganancia de ruido y penalidad G_inf = mean(1 ./ abs(Mw).^2); % (1/2pi) * integral de 1/|M|^2 fprintf('ganancia de ruido %.4f (%.2f dB)\n', G_inf, 10*log10(G_inf)) fprintf('penalidad contra sin ISI: %.2f dB\n', 10*log10(sum(m.^2) * G_inf)) % ganancia de ruido 1.8008 (2.55 dB) % penalidad contra sin ISI: 3.00 dB %% 6. La inversa causal no sirve: tiene polos fuera del círculo h = filter(1, m, [1 zeros(1, 99)]); fprintf('|1/M| causal, muestra 100: %.1e\n', abs(h(end))) % |1/M| causal, muestra 100: 5.3e+45 %% 7. ZF FIR de Nf taps, por mínimos cuadrados, con el mejor retardo for Nf = [3 5 7 11 15 21 31] C = convmtx(m.', Nf); % (13+Nf-1) x Nf mejor = inf; for D = 1:size(C, 1) e = zeros(size(C, 1), 1); e(D) = 1; f = C \ e; % mínimos cuadrados t = C * f; if norm(t - e) < mejor, mejor = norm(t - e); fo = f; to = t; Do = D; end end isi = (sum(to.^2) - to(Do)^2) / to(Do)^2; fprintf('Nf = %2d Delta = %2d ISI %6.1f dB sum f^2 = %.4f (%.2f dB)\n', ... Nf, Do-1, 10*log10(isi), sum(fo.^2), 10*log10(sum(fo.^2))) end % Nf = 3 Delta = 7 ISI -13.9 dB sum f^2 = 1.1773 (0.71 dB) % Nf = 5 Delta = 8 ISI -18.0 dB sum f^2 = 1.4415 (1.59 dB) % Nf = 7 Delta = 9 ISI -21.3 dB sum f^2 = 1.5938 (2.02 dB) % Nf = 11 Delta = 11 ISI -28.1 dB sum f^2 = 1.7419 (2.41 dB) % Nf = 15 Delta = 13 ISI -36.6 dB sum f^2 = 1.7882 (2.52 dB) % Nf = 21 Delta = 16 ISI -48.5 dB sum f^2 = 1.7995 (2.55 dB) % Nf = 31 Delta = 21 ISI -68.4 dB sum f^2 = 1.8007 (2.55 dB) %% 8. Forzar a cero de verdad: Nf - 1 muestras nulas alrededor del cursor Nf = 11; C = convmtx(m.', Nf); D = 12; % cursor en la fila 12 filas = D-5:D+5; % las 11 muestras que se controlan e = zeros(Nf, 1); e(6) = 1; f = C(filas, :) \ e; % sistema cuadrado: se cumple exacto t = C * f; disp(round(t(D-7:D+7).', 4)) fprintf('ISI %.1f dB sum f^2 = %.4f\n', 10*log10((sum(t.^2)-t(D)^2)/t(D)^2), sum(f.^2)) % 0.0092 -0.0277 0 0 0 0 0 1.0000 0 0 0 0 0 -0.0277 0.0092 % ISI -27.6 dB sum f^2 = 1.7762 %% 9. Lo mismo, truncando la inversa de dos lados Nfft = 4096; finv = real(ifft(1 ./ fft(circshift([m zeros(1, Nfft-13)], -6)))); for Nf = [3 11 31] L = (Nf-1)/2; f = [finv(end-L+1:end) finv(1:L+1)]; % Nf taps centrados en 0 t = conv(m, f); [~, D] = max(abs(t)); isi = (sum(t.^2) - t(D)^2) / t(D)^2; fprintf('truncada Nf = %2d ISI %6.1f dB sum f^2 = %.4f\n', Nf, 10*log10(isi), sum(f.^2)) end % truncada Nf = 3 ISI -11.8 dB sum f^2 = 1.6600 % truncada Nf = 11 ISI -26.2 dB sum f^2 = 1.7963 % truncada Nf = 31 ISI -66.5 dB sum f^2 = 1.8008 %% 10. Monte Carlo: el ruido que llega al slicer rng(1); Ns = 1e6; sigma = 0.1; a = 2*randi([0 1], Ns, 1) - 1; zk = filter(m, 1, a) + sigma*randn(Ns, 1); C = convmtx(m.', 31); e = zeros(43, 1); e(22) = 1; f = C \ e; xk = filter(f, 1, zk); err = xk(100:end) - a(100-21:end-21); % retardo de la cascada: 21 fprintf('var medida / sigma^2 = %.4f sum f^2 = %.4f\n', var(err)/sigma^2, sum(f.^2)) % var medida / sigma^2 = 1.8012 sum f^2 = 1.8007
Cuatro detalles que muerden si no se los conoce:
ip y avanza de a N; empezar en la muestra 1 tomaría los puntos entre símbolos. El comentario de B_FSE_equalizer.m avisa lo mismo: con un fir1 de orden impar el pico se corre media muestra.filter(1, m, z) no es el ZF de cualquier canal. Aplica el inverso causal, que sólo es estable si todos los ceros de m están adentro del círculo. Con un canal simétrico nunca lo están: el bloque 6 lo muestra divergiendo sin ningún aviso.convmtx quiere una columna. Con m fila devuelve la matriz traspuesta y el \ resuelve otro problema. De ahí el m.'.C*f es la convolución completa , así que el que devuelve el bloque 7 es el retardo total, y es el que hay que usar para alinear xk con a en el bloque 10. Sumarle los seis del canal da 201,8 , que no es ruido: es la varianza de restar dos símbolos que no tienen nada que ver.