Unidad 6 · Ecualizadores adaptativos · el descenso por gradiente sobre el MSE, sus modos de convergencia y el paso
Las ecuaciones de Wiener-Hopf dan el mejor ecualizador de un saque, , pero piden invertir . El algoritmo MSEG (minimum square error gradient) llega al mismo punto de otra manera: arranca en cualquier lado y baja por el tazón del MSE dando pasos contra el gradiente. Si llega y cuánto tarda lo decide la forma del tazón, o sea los autovalores de . Cada uno aporta un modo que se achica como : el autovalor más grande pone el techo del paso, y el más chico, la velocidad. En la cadena canal → AGC → ecualizador → slicer, es la regla con la que el ecualizador movería sus taps si conociera la estadística de su entrada. El LMS es la misma regla sin conocerla.
La filmina de introducción a la optimización ordena los métodos por dos preguntas: cuántas variables tiene la función y si se dispone de sus derivadas. Con una sola variable están la sección áurea, la interpolación cuadrática y el método de Newton. Con varias hay métodos directos, que sólo evalúan la función —búsqueda por malla, búsqueda aleatoria, univariadas, Powell—, y métodos con gradiente, que usan las derivadas para elegir hacia dónde moverse: el steepest ascent para máximos y el steepest descent para mínimos.
El gradiente apunta hacia donde la función crece más rápido y es perpendicular a las curvas de nivel. El steepest descent da un paso en la dirección contraria, vuelve a evaluar el gradiente y repite. La filmina distingue dos maneras de elegir el largo del paso: uno arbitrario y fijo, o el que minimiza la función a lo largo de esa dirección, que es una búsqueda unidimensional en cada paso. El MSEG es el primero: descenso por gradiente con paso fijo sobre el MSE de un ecualizador de taps. Un método directo no es opción: una malla de 10 valores por tap sobre 11 taps son 10¹¹ evaluaciones.
El MSE del ecualizador es una forma cuadrática en los taps. De dónde sale, y por qué tiene un solo mínimo, está en el criterio MSE:
con y . Con señales reales —PAM-2, o la entrada de MSEG.m— los asteriscos y la parte real no hacen nada, y queda . El gradiente es el vector de las derivadas parciales respecto de cada tap , y sale término por término.
Paso 1: el término constante. no depende de los taps: su gradiente es cero.
Paso 2: el término lineal. . Cada tap aparece una sola vez, multiplicado por su , así que la derivada respecto de es , y el gradiente es entero.
Paso 3: el término cuadrático. Escrito como doble suma, aparece dos veces, una como índice de fila y otra como índice de columna:
Las dos sumas son iguales porque es simétrica: la correlación entre los taps y es la misma que entre y . Juntando los tres pasos:
Es el gradiente que escribe la filmina 4, que vale igual con señales complejas. Se puede leer de dos maneras. Igualado a cero da las ecuaciones de Wiener-Hopf, : es el camino B de la filmina hacia . Y como , el gradiente es veces la correlación entre el error y las muestras de la línea. Esa correlación se puede medir sobre las señales, y de ahí sale el LMS.
Hay una tercera forma del MSE que conviene tener a mano. Con , completar el cuadrado da . Las curvas de nivel son elipses centradas en , con los ejes sobre los autovectores de : empinadas en la dirección del autovalor más grande, casi planas en la del más chico.
Partiendo de un cualquiera, el MSEG da un paso contra el gradiente evaluado donde está:
es el paso de adaptación, y el está para que se vaya el 2 del gradiente. El índice cuenta iteraciones del algoritmo, no símbolos: el tiempo del canal es , y el MSEG no lo mira, porque trabaja con la esperanza. Como y se suponen conocidas, el gradiente es exacto y el algoritmo es determinístico: la misma da siempre la misma trayectoria. La versión que estima el gradiente con cada símbolo es el LMS.
Cada iteración cuesta un producto y ninguna inversión. El método de Newton de la filmina de optimización hace lo contrario: multiplica el gradiente por la inversa del Hessiano, que acá es , y cae en el fondo en un paso, . Newton sobre una cuadrática es Wiener-Hopf con otro nombre. El MSEG cambia esa inversa por un número, , y lo paga en iteraciones. Cuántas, depende de cuánto se parezca a un múltiplo de la identidad.
Paso 1: medir desde el fondo. Se define el error de coeficientes . Como , el término independiente de la actualización es , y al restar de los dos lados desaparece:
Una recursión lineal homogénea: todo depende de las potencias de .
Paso 2: diagonalizar. es hermítica, así que sus autovalores son reales y sus autovectores ortonormales; es definida positiva, así que los son positivos. Es la descomposición espectral de la filmina, . tiene los mismos autovectores, con autovalores , y elevarla a la es elevar cada uno:
Paso 3: mirar el error en esa base. La coordenada dice cuánto error queda a lo largo del autovector , y con la suma de arriba evoluciona sola:
Son los modos de convergencia de la filmina. Un sistema de ecuaciones acopladas se vuelve geométricas sueltas, cada una con su razón , y la trayectoria de es la suma de las . El MSE también se separa, porque :
En dB, el exceso de MSE de cada modo baja por iteración: una recta, que es lo que dibuja MSEG.m en su figura «Avance del MSE» (sección 08).
Con , y el gradiente, , apunta derecho al fondo desde cualquier lado. Los dos modos tienen la misma razón, las dos rectas de abajo son paralelas y la trayectoria es una recta; con llega en un paso, que es el paso de Newton. Al subir las elipses se estiran sobre la dirección de y el gradiente deja de apuntar al fondo: apunta a la pared más cercana. El modo de se va en pocos pasos y lo que queda es recorrer el valle con la razón de , por eso la trayectoria dobla: primero cae a lo ancho del valle y después camina a lo largo. Con entre y el modo rápido cambia de signo en cada paso y la trayectoria zigzaguea de pared a pared, como en la figura de la filmina. Arriba de cada rebote es más grande que el anterior. En el widget , así que y el paso óptimo de la sección 06 vale 1 para cualquier .
tiende a cero para cualquier punto de partida si y sólo si todos los modos se achican: para todo . Como los son positivos, eso es , y el más exigente es el del autovalor más grande:
La dirección más empinada del tazón es la primera que se pasa de largo. Si el paso es tan grande que en esa dirección el algoritmo salta más allá de la pared de enfrente, cada rebote es mayor que el anterior, aunque en todas las otras direcciones esté convergiendo: alcanza con un modo que crezca. Entre y converge oscilando; justo en rebota sin achicarse.
La filmina escribe primero la condición como . Ese es el caso de entrada blanca, donde y todos los autovalores valen ; con una entrada cualquiera la condición es sobre , que es la que la filmina da tres filminas después.
Hay una cota que no pide autovalores. Los autovalores suman la traza, y como son todos positivos, . Así, es seguro y sólo pide el largo del ecualizador y la potencia de entrada . Si la señal llega el doble de fuerte, se duplica y el paso máximo se parte a la mitad: por eso el control automático de ganancia va antes del ecualizador.
En MSEG.m la entrada es randn: blanca y de potencia 1, así que y hay un solo modo, con . El script actualiza c = c - beta*gradient, sin el de la filmina: su beta es la mitad del de la teoría. El beta = 0.001 de la clase es , con razón por iteración, y el límite es beta < 1 en el script. La filmina pide probar varios beta. Con el lazo de MSEG.m, sin tocar, lo que se achica el error en la primera iteración:
| beta del script | β | predicho |1 − β| | medido ‖q₁‖/‖q₀‖ | qué pasa |
|---|---|---|---|---|
| 0,01 | 0,02 | 0,98 | 0,980 | converge lento |
| 0,25 | 0,5 | 0,50 | 0,498 | converge |
| 0,5 | 1 | 0 | 0,039 | casi en un paso |
| 0,75 | 1,5 | 0,50 | 0,511 | converge oscilando |
| 0,95 | 1,9 | 0,90 | 0,913 | oscila, lento |
| 1,05 | 2,1 | 1,10 | 1,114 | diverge |
El único que se aparta es : la teoría dice que llega en un paso, y el script se queda a un 3,9 % del error inicial. Es que el script no tiene el gradiente exacto. Lo calcula sobre un lote de 1000 muestras, y la de un lote no es exactamente : en 200 lotes, su autovalor más chico promedia 0,916 y el más grande 1,075. Con lo único que queda es esa diferencia.
Dentro del rango estable, la velocidad la pone el modo que se achica más despacio:
Cada , como función de , es una V con el vértice en . Las V de los autovalores intermedios quedan entre las de los extremos, así que el máximo lo ponen y , que es el gráfico de la filmina. Con chico manda , la V que baja más despacio; con grande manda , la que primero vuelve a subir. El mínimo del máximo está donde se cruzan la rama que baja de una y la que sube de la otra:
Reemplazando, la mejor razón posible depende de un solo número, la dispersión de autovalores :
En los dos modos extremos empatan: el lento se acerca de un solo lado y el rápido oscilando, con la misma razón en módulo. Achicar el paso ayuda al rápido y frena al lento; agrandarlo, al revés. Ninguna elección de hace rápido un tazón alargado. Ni siquiera en el borde de estabilidad: si , entonces , y el modo lento nunca baja más de por iteración. Cuánto tarda la cota en bajar a 10⁻³ con el mejor paso:
| χ | ρ(βopt) | j con ρ^j = 10⁻³ |
|---|---|---|
| 1 | 0 | 1 (un paso) |
| 2 | 0,3333 | 6,3 |
| 4 | 0,6000 | 13,5 |
| 10 | 0,8182 | 34,4 |
| 13,41 | 0,8612 | 46,2 |
| 49,75 | 0,9606 | 171,8 |
| 126,8 | 0,9844 | 438,0 |
| 1000 | 0,9980 | 3454 |
Es , en forma cerrada. Para grande, y hacen falta unas iteraciones: el costo crece lineal con la dispersión. Las filas de 13,41, 49,75 y 126,8 son el canal de la sección siguiente con 5, 11 y 21 taps.
es la autocorrelación de lo que entra al ecualizador, o sea de lo que dejó el canal, y sus autovalores quedan encerrados por el espectro de esa señal. Para un autovector de norma 1, . Escribiendo cada como la antitransformada de la PSD de , la doble suma se vuelve el módulo al cuadrado de la DTFT de los componentes de :
La segunda igualdad es Parseval. Cada autovalor es un promedio de con pesos que suman 1, así que cae entre el mínimo y el máximo del espectro, y . Es lo que dice la filmina: un espectro casi plano converge rápido, uno con picos y pozos converge lento.
El caso más simple: símbolos blancos de potencia 1 por un canal [1 a], . Entonces , , y va de a . es tridiagonal y Toeplitz, y sus autovalores tienen forma cerrada:
que es muestrear en frecuencias. Contra eig difieren en 2·10⁻¹⁵ como máximo. La dispersión, según el eco y el largo del ecualizador:
| a | cota ((1+a)/(1−a))² | N = 2 | N = 5 | N = 11 | N = 21 |
|---|---|---|---|---|---|
| 0 | 1 | 1 | 1 | 1 | 1 |
| 0,3 | 3,45 | 1,76 | 2,82 | 3,27 | 3,39 |
| 0,5 | 9 | 2,33 | 5,51 | 7,80 | 8,61 |
| 0,7 | 32,1 | 2,77 | 9,74 | 20,6 | 27,6 |
| 0,9 | 361 | 2,98 | 13,4 | 49,7 | 126,8 |
Con el canal tiene un pozo de 25,6 dB en , y la cota es 361. Con más taps el ecualizador ve el espectro con más resolución y se acerca a la cota: 13,4 con 5 taps, 126,8 con 21. Con el mejor paso, el de 21 taps tarda 438 iteraciones en bajar la cota del error mil veces; con el canal plano, una. El canal que más necesita ecualización es el que más tarda en aprenderse, y no hay paso que lo arregle, porque es una propiedad de la entrada y no del algoritmo. Con dos taps, este canal no pasa de : las dispersiones más grandes del widget piden muestras vecinas más parecidas entre sí, como las que deja un canal más largo.
El script de la clase, MSEG.m, identifica un filtro de referencia h_ref = fir1(4, 0.3)' de 5 taps: la misma entrada blanca pasa por h_ref y por el filtro c que se adapta, y el error es la diferencia de las salidas. No usa ni : en cada iteración mide el MSE sobre un lote de 1000 muestras, suma Delta_tap = 1e-4 a un tap por vez y estima cada derivada parcial como un cociente incremental. Corre sin cambios en R2026a y tarda unos 5 s. Abajo, el script corrido con semilla fija, y después su mismo lazo con otros pasos y con la entrada coloreada. MSEG.m tiene que estar en la carpeta. Lo que figura como comentario es la salida real.
%% 1. El script de la clase, tal cual (tarda unos 5 s) rng(1) run('MSEG.m') % deja h_ref, c, beta, Niters, Ncoeff, Delta_tap, mse_logeo close all %% 2. La predicción. Entrada blanca de potencia 1: Phi = I, un solo modo con lambda = 1. % El script hace c = c - beta*gradient, sin el 1/2 de la filmina: % su beta es la mitad del beta de la teoría, así que el factor es 1 - 2*beta. factor = 1 - 2*beta; j = (1:Niters)'; mse_dB = 10*log10(mse_logeo); pred_dB = 10*log10(factor.^(2*(j-1)) * sum(h_ref.^2)); % MSE = ||q_j||^2 p = polyfit(j(200:3000), mse_dB(200:3000), 1); fprintf('pendiente: medida %.2f, predicha %.2f dB cada 1000 iteraciones\n', ... 1000*p(1), 1000*20*log10(factor)) fprintf('MSE en j = 1000: medido %.2f dB, predicho %.2f dB\n', mse_dB(1000), pred_dB(1000)) % pendiente: medida -17.28, predicha -17.39 dB cada 1000 iteraciones % MSE en j = 1000: medido -21.63 dB, predicho -21.86 dB %% 3. El piso no es el mínimo: la derivada hacia adelante corre el gradiente fprintf('c - h_ref = %s\n', mat2str((c - h_ref)', 3)) fprintf('piso: medido %.2f dB, N*(Delta/2)^2 = %.2f dB\n', ... mean(mse_dB(8001:end)), 10*log10(Ncoeff*(Delta_tap/2)^2)) % c - h_ref = [-5e-05 -5.01e-05 -5.01e-05 -5.01e-05 -5e-05] % piso: medido -79.05 dB, N*(Delta/2)^2 = -79.03 dB %% 4. Probar varios betas (lo que pide la filmina), con el lazo de MSEG.m h = fir1(4, 0.3)'; for b = [0.01 0.25 0.5 0.75 0.95 1.05] % beta del script rng(2) cl = mseg_clase(h, b, 40, 1); % entrada blanca nq = vecnorm(cl - h', 2, 2); % ||q_j||, j = 0..40 fprintf('beta script %.2f: ||q1||/||q0|| = %.3f, predicho |1-2beta| = %.2f\n', ... b, nq(2)/nq(1), abs(1 - 2*b)) end % beta script 0.01: ||q1||/||q0|| = 0.980, predicho |1-2beta| = 0.98 % beta script 0.25: ||q1||/||q0|| = 0.498, predicho |1-2beta| = 0.50 % beta script 0.50: ||q1||/||q0|| = 0.039, predicho |1-2beta| = 0.00 % beta script 0.75: ||q1||/||q0|| = 0.511, predicho |1-2beta| = 0.50 % beta script 0.95: ||q1||/||q0|| = 0.913, predicho |1-2beta| = 0.90 % beta script 1.05: ||q1||/||q0|| = 1.114, predicho |1-2beta| = 1.10 %% 5. Entrada coloreada: x pasa por [1 0.9] antes de entrar a = 0.9; N = 5; Phi = toeplitz([1+a^2, a, zeros(1, N-2)]); % autocorrelación exacta de x [V, L] = eig(Phi); lam = diag(L); fprintf('lambda = %s, dispersion %.2f\n', mat2str(lam', 4), max(lam)/min(lam)) % lambda = [0.2512 0.91 1.81 2.71 3.369], dispersion 13.41 beta_opt = 2/(min(lam) + max(lam)); for B = [0.2, beta_opt] % beta de la filmina rng(3) cl = mseg_clase(h, B/2, 120, [1 a]); % el script usa beta/2 nq = vecnorm(cl - h', 2, 2); u = (cl - h') * V; % coordenadas modales de q_j pl = polyfit((0:30)', log(abs(u(1:31, 1))), 1); % modo de lambda_min fprintf('beta %.4f: modo lento %.4f (pred %.4f), ||q|| baja 100 veces en %d iteraciones\n', ... B, exp(pl(1)), abs(1 - B*min(lam)), find(nq < nq(1)/100, 1) - 1) end % beta 0.2000: modo lento 0.9496 (pred 0.9498), ||q|| baja 100 veces en 48 iteraciones % beta 0.5525: modo lento 0.8677 (pred 0.8612), ||q|| baja 100 veces en 30 iteraciones B = 1.1*2/max(lam); % 10 % arriba del limite rng(3) cl = mseg_clase(h, B/2, 60, [1 a]); u = (cl - h') * V; pr = polyfit((20:60)', log(abs(u(21:61, end))), 1); % modo de lambda_max fprintf('beta %.4f > 2/lambda_max = %.4f: el modo rapido crece %.3f por iteracion (pred %.3f)\n', ... B, 2/max(lam), exp(pr(1)), abs(1 - B*max(lam))) % beta 0.6530 > 2/lambda_max = 0.5937: el modo rapido crece 1.162 por iteracion (pred 1.200) rng(3) cl = mseg_clase(h, 0.5, 20, 1); % entrada blanca, beta = 1 = su beta_opt nq = vecnorm(cl - h', 2, 2); fprintf('entrada blanca, beta = 1: ||q|| baja 100 veces en %d iteraciones\n', find(nq < nq(1)/100, 1) - 1) % entrada blanca, beta = 1: ||q|| baja 100 veces en 2 iteraciones function c_log = mseg_clase(h_ref, beta, Niters, g) % El lazo de MSEG.m, sin tocar, con la entrada pasada por g Ncoeff = length(h_ref); Lbatch = 1e3; Delta_tap = 1e-4; c = zeros(Ncoeff, 1); gradient = zeros(Ncoeff, 1); c_log = zeros(Niters+1, Ncoeff); for iter = 1:Niters x = filter(g, 1, randn(Lbatch, 1)); y_ref = filter(h_ref, 1, x); y = filter(c, 1, x); mse0 = mean(abs(y - y_ref).^2); for nc = 1:Ncoeff caux = c; caux(nc) = caux(nc) + Delta_tap; y = filter(caux, 1, x); mse1 = mean(abs(y - y_ref).^2); gradient(nc) = (mse1 - mse0)/Delta_tap; end c = c - beta*gradient; c_log(iter+1, :) = c; end end
El bloque 2 cruza la simulación contra la forma cerrada. Con y —el filtro de 5 taps puede copiar exactamente a h_ref—, el MSE es y cae como , desde (−4,49 dB): una recta de por iteración, −17,39 dB cada mil. Medida entre las iteraciones 200 y 3000 da −17,28. El bloque 5 hace lo mismo con la entrada coloreada del canal [1 0.9], : el modo lento se achica 0,9496 por iteración con (predicho ) y 0,8677 con (predicho 0,8612). Un 10 % por encima de el modo rápido crece 1,162 por iteración, contra 1,200 predicho. Para bajar el error cien veces hacen falta 30 iteraciones con el mejor paso; con entrada blanca, 2.
Cuatro detalles que muerden:
beta del script es la mitad del de la filmina. La filmina resta y el script beta*gradient. Con entrada blanca la razón es 1 - 2*beta y el límite, beta < 1/lambda_max. Probar beta = 1.5 «porque el límite es 2» diverge.(mse(c + Delta) - mse(c - Delta))/(2*Delta), el sesgo desaparece, porque para una cuadrática es exacta.mse1 - mse0 la dominaría lo que varía el MSE de un lote a otro, muchísimo más grande que el efecto de mover un tap en 10⁻⁴.MSEG.m, beta es , el gradiente sale de un lote de 1000 muestras, y el piso de −79 dB es el sesgo de la diferencia hacia adelante.