Unidad 4 · Transmisión en banda base y banda pasante · de bits a símbolos y de vuelta, el código Gray, la tabla compartida y el demapper blando
El mapper traduce bits a símbolos y el demapper los traduce de vuelta. Entre los dos no se pierde nada: son una tabla y su inversa. Lo que la tabla sí decide es qué grupo de bits queda al lado de cuál en la constelación, y como el slicer, cuando se equivoca, casi siempre elige un vecino, de eso depende cuántos bits cuesta cada error. La respuesta de siempre es el código Gray. Tiene dos letras chicas: hay constelaciones donde no existe, y sólo sirve si el demapper usa la misma tabla que el mapper.
El mapper toma los bits de a grupos de y le asigna a cada grupo uno de los puntos del alfabeto :
Con grupos posibles y puntos, es una biyección: cada grupo tiene su punto y cada punto su grupo, la etiqueta del punto. El demapper es la inversa, aplicada a lo que decidió el slicer:
La cadena entera es bits → mapper → filtro Tx → canal → filtro Rx → slicer → demapper → bits. El demapper no decide nada: el que elige el punto es el slicer, y el demapper lee su etiqueta. Por eso los dos contadores de error se toman en lugares distintos: la SER a la salida del slicer, la BER a la salida del demapper.
Tablas posibles hay , una por cada manera de repartir las etiquetas entre los puntos: para 16-QAM son . Todas dan la misma SER, porque la SER depende sólo de dónde están los puntos. La BER cambia de una a otra.
El simulador de la cátedra nunca arma los bits. transmisor_MQAM.m sortea enteros con randi([0 M-1]) y los pasa por qammod, y my_ber_checker.m le pide los bits a qamdemod(…, 'OutputType', 'bit') dos veces: sobre los símbolos mandados y sobre los decididos. El mapper de ese conteo es el propio demapper aplicado del lado del transmisor, así que la tabla es la misma de los dos lados por construcción. Cuando los bits vienen de afuera —de una fuente o de un codificador de canal—, mapper y demapper son dos piezas separadas, y que usen la misma tabla deja de estar garantizado (sección 05).
Un código Gray es una lista de las palabras de bits en la que dos palabras consecutivas difieren en un solo bit. La construcción de siempre es la del código reflejado, y se hace de a un bit por vez.
Paso 1: arrancar con un bit. La lista es 0, 1.
Paso 2: reflejar. Debajo de la lista se escribe la misma lista al revés: 0, 1, 1, 0.
Paso 3: prefijar. A la primera mitad se le antepone un 0 y a la segunda un 1: 00, 01, 11, 10. Es el Gray de dos bits, el de la filmina de PAM-4. Repitiendo los pasos 2 y 3 sale el de tres:
000 001 011 010 │ 110 111 101 100
Funciona por inducción. Dentro de cada mitad, dos palabras vecinas tienen el mismo prefijo y la misma cola que en la lista anterior, donde ya diferían en un bit. En la costura, la reflexión pone una palabra al lado de sí misma —010 y 110 tienen la misma cola, 10— y lo único que cambia es el prefijo. Y por la misma razón la última y la primera también difieren en un bit: 100 y 000. El código reflejado es cíclico, y eso va a importar en PSK.
Paso 4: la forma cerrada. La etiqueta de la posición es
el o exclusivo de con él mismo corrido un lugar a la derecha, bitxor(n, bitshift(n, -1)). En MATLAB, la lista reflejada y la fórmula dan lo mismo para de 1 a 8. Por qué el corrimiento produce un solo cambio está en La modulación PAM, con la posición contada desde el nivel más alto.
Paso 5: la inversa, que es la que usa el demapper. Bit por bit, la fórmula dice , con arriba de todo. Despejando, , y bajando desde el bit más significativo:
Cada bit de la posición es la paridad de los bits de la etiqueta que tiene arriba. La ida es un solo o exclusivo; la vuelta, uno por bit.
Sea la cantidad de bits en que difieren la etiqueta mandada y la decidida, la distancia de Hamming entre las dos. Por definición, : cada error de símbolo cuesta bits de los que llevaba. Toda la cuestión es cuánto vale ese promedio.
Con relación señal a ruido alta, casi todos los errores son a un vecino a distancia mínima, y todos esos pares son igual de probables: la probabilidad de cruzar la frontera depende sólo de la distancia, que es la misma para todos. Así que el promedio tiende al costo medio sobre el conjunto de los pares de puntos a distancia mínima, que depende sólo de la tabla:
con la etiqueta del punto . Gray es exactamente , el mínimo posible, y de ahí la regla . Con el orden natural el costo del par depende de dónde está: en PAM es , que está derivado en La modulación PAM. En 16-QAM natural los vecinos están en la misma fila o en la misma columna, así que cada error cambia un solo eje, y cada eje es una PAM-4 natural: , con 8 de los 24 pares en dos bits.
Medido sobre la cadena entera —bits, qammod con 'gray' o 'bin', ruido blanco gaussiano, my_slicer.m de la cátedra y qamdemod con la misma opción—, con 10⁶ símbolos de 16-QAM y el mismo ruido para las dos tablas:
| Eb/N0 | BER Gray | berawgn | BER natural | natural ÷ Gray | SER Gray | SER natural |
|---|---|---|---|---|---|---|
| 6 dB | 2,791·10⁻² | 2,787·10⁻² | 3,723·10⁻² | 1,334 | 1,085·10⁻¹ | 1,085·10⁻¹ |
| 8 dB | 9,202·10⁻³ | 9,247·10⁻³ | 1,233·10⁻² | 1,340 | 3,648·10⁻² | 3,663·10⁻² |
| 10 dB | 1,773·10⁻³ | 1,754·10⁻³ | 2,378·10⁻³ | 1,341 | 7,073·10⁻³ | 7,128·10⁻³ |
| 12 dB | 1,292·10⁻⁴ | 1,387·10⁻⁴ | 1,727·10⁻⁴ | 1,337 | 5,170·10⁻⁴ | 5,230·10⁻⁴ |
La columna de berawgn es el control: la BER con Gray cae a menos del 1,1 % de la teoría hasta 10 dB. A 12 dB queda un 7 % abajo con 517 bits errados, y el desvío de Poisson con tan pocos eventos es del 4,4 %. Las dos SER son la misma dentro de esa misma dispersión —517 contra 523 símbolos a 12 dB—, y la razón entre las BER se queda entre 1,334 y 1,341 en todo el barrido, contra el de la cuenta. La tabla no cambió cuántos símbolos se decidieron mal: cambió cuántos bits costó cada uno. Que con Gray la razón SER/BER tarde en llegar a cuando la constelación es grande está medido en BER y SER no son la misma curva.
En una recta, Gray siempre existe: es la lista de la sección 02 puesta sobre los niveles. En el plano depende de la forma de la constelación, porque cada punto tiene más vecinos y todos tienen que diferir en un bit.
QAM cuadrada: Gray por eje. La etiqueta se parte en dos mitades, una para el nivel de I y otra para el de Q, y cada mitad es el Gray de una PAM de niveles. Dos vecinos a distancia mínima comparten fila o columna: cambia un solo eje, en un nivel, y por lo tanto un bit. Es lo que hace qammod, y en qué sentido recorre cada eje está en La modulación QAM.
PSK: Gray alrededor del círculo. Los puntos tienen dos vecinos cada uno, y la vuelta cierra: el último es vecino del primero. Ahí es donde sirve que el código reflejado sea cíclico, y con la etiqueta en el punto de fase todos los pares quedan en un bit. Es la tabla de pskmod(…, 'gray'). El natural, en cambio, paga la vuelta entera en el último par —111 contra 000 en 8-PSK— y su costo medio es : los bits del tramo abierto, como en PAM, más los del cierre.
La 32-QAM en cruz: no hay Gray. Con cinco bits no hay cuadrado; la cruz es una grilla de 6 × 6 sin las cuatro esquinas, con 52 pares a distancia mínima. Las filas no tienen todas el mismo largo, así que no se puede repartir la etiqueta por eje, y la filmina de la Unidad 5 lo dice a su manera: los mappers de las constelaciones en cruz son más complicados. Es más que eso. Una búsqueda exhaustiva —fijando la etiqueta de un punto, porque cualquier tabla Gray sigue siéndolo si se le invierte un bit a todas las etiquetas, y probando para cada vecino las etiquetas a un bit de las ya puestas— recorre 14 727 asignaciones parciales y no encuentra ninguna tabla con los 52 pares en un bit. La misma búsqueda encuentra una enseguida para la grilla rectangular de 8 × 4 y para 16-QAM, que es el control. qammod(…, 32) deja 8 pares en dos bits, todos entre las filas de los brazos y la fila siguiente: . No es lo mejor que se puede hacer: un recocido simulado de 40 arranques encontró tablas de , con dos pares en tres bits, y ninguna con menos de dos pares malos.
Todo junto, contando los pares a distancia mínima sobre las tablas de MATLAB; «malos» son los pares en más de un bit:
| constelación | pares | Gray, malos | Gray, | natural, malos | natural, |
|---|---|---|---|---|---|
| PAM-4 | 3 | 0 | 1,000 | 1 | 1,333 |
| PAM-8 | 7 | 0 | 1,000 | 3 | 1,571 |
| 16-QAM | 24 | 0 | 1,000 | 8 | 1,333 |
| 64-QAM | 112 | 0 | 1,000 | 48 | 1,571 |
| 8-PSK | 8 | 0 | 1,000 | 4 | 1,750 |
| 16-PSK | 16 | 0 | 1,000 | 8 | 1,875 |
| 32-QAM en cruz | 52 | 8 | 1,154 | 24 | 1,654 |
| 128-QAM en cruz | 232 | 16 | 1,069 | 96 | 1,741 |
Las columnas de Gray de las constelaciones cuadradas, de PAM y de PSK son un uno exacto por construcción, y no se miden: se verifican. Las del natural son cuentas cerradas y la tabla las reproduce: 64-QAM natural cuesta lo mismo que PAM-8 natural porque cada eje es una. La que hay que medir es la cruz, y la de 128 puntos, con más pares interiores, se acerca más al uno que la de 32.
En PAM-4 natural el par del medio se pone rojo, y con un solo intercambio —10 por 11— la tabla pasa a ser Gray. En 8-PSK natural los dos rojos más caros cuestan tres bits: el del medio, 011 contra 100, y el que cierra el círculo, 111 contra 000. En la cruz se puede intentar a mano: cualquier rojo que se arregla en el borde de un brazo aparece en otro lado, y ninguna secuencia de intercambios deja los 52 pares en azul, porque esa tabla no existe.
Que una tabla sea Gray depende de qué etiquetas quedan vecinas, no de cuáles son. Invertir un bit en todas las etiquetas, permutar las posiciones de los bits o recorrer un eje al revés da otra tabla igual de Gray. Lo último es la propiedad de la reflexión: la lista reflejada leída de atrás para adelante es la misma lista con el bit más significativo invertido. Para dos bits, 10 11 01 00 contra 00 01 11 10.
Por eso conviven varias convenciones y ninguna está mal. La filmina de PAM-4 pone 00 en el nivel más alto. qammod recorre el eje Q igual, de arriba abajo, y el eje I de izquierda a derecha. pammod pone el 00 abajo: es el espejo de la filmina, como está medido en La modulación PAM. Y las notas de la Unidad 5, como la de BER y SER, recorren los dos ejes de abajo arriba, que es la constelación de qammod espejada en Q. Las cuatro tienen y la misma BER.
Lo que no se puede es mezclarlas. Si el mapper usa una tabla y el demapper otra, el demapper traduce bien el punto equivocado de la tabla: el slicer acierta y los bits salen mal igual. Con 16-QAM de qammod en el transmisor y 10⁶ símbolos, cambiando sólo la tabla del demapper:
| Eb/N0 | SER | BER, misma tabla | BER, Q al revés | BER, natural en el receptor |
|---|---|---|---|---|
| sin ruido | 0 | 0 | 0,25000 | 0,24979 |
| 10 dB | 7,025·10⁻³ | 1,759·10⁻³ | 0,25115 | 0,25093 |
| 6 dB | 1,085·10⁻¹ | 2,788·10⁻² | 0,26850 | 0,25938 |
Sin ruido no hay un solo error de símbolo y la BER es un cuarto. Las dos columnas rojas valen un cuarto por razones distintas. Con Q al revés la cuenta es exacta: en cada símbolo se invierte el bit más significativo de Q, uno de cuatro, siempre; por eso da 0,25000 clavado. Con el natural en el receptor, cada eje se lee bien en sus dos primeros niveles y con un bit cambiado en los otros dos, o sea dos bits malos de cada ocho, y el 0,24979 es ese cuarto con la dispersión de los datos sorteados. Con ruido el piso no baja: a 10 dB la BER buena es 1,8·10⁻³ y las desparejas siguen en un cuarto. Una BER que no baja con la relación señal a ruido mientras la constelación recibida se ve limpia es una tabla, no un canal.
Con PAM-4 el efecto es el doble. Los bits mapeados con la tabla de la filmina y recuperados con pamdemod(…, 'gray') salen con BER 0,5000: el primer bit está mal en todos los símbolos y el segundo en ninguno. Es la reflexión otra vez, el espejo de un Gray reflejado es el mismo Gray con el bit de arriba invertido.
Hay una segunda convención escondida en el mismo lugar: cuál de los bits del grupo es el más significativo de la etiqueta. Las tablas de la filmina se escriben con el primer bit adelante, y así leen int2bit y bit2int, y así agrupa qammod(…, 'InputType', 'bit'). de2bi y bi2de, las funciones viejas, por omisión ponen el menos significativo primero; la diferencia entre bi2de([1 0]) y bit2int([1; 0], 2) está en La modulación PAM. Para el canal es una tabla distinta más. Con PAM-4, si el mapper agrupa con bit2int y el demapper devuelve los bits con de2bi, las etiquetas 01 y 10 se intercambian y la BER sin ruido es 0,5016: la mitad, con la dispersión de los datos. Leída al revés, una tabla Gray sigue siendo Gray; el problema, otra vez, es que no es la misma.
El demapper de las secciones anteriores es duro: recibe un punto ya decidido y devuelve bits. Si después viene un decodificador de canal, conviene más un demapper blando, que mira la muestra antes del slicer y devuelve por cada bit cuánto cree en un 0 contra un 1. Es el cociente de log-verosimilitudes, el LLR, ahora con un alfabeto de puntos. Con símbolos equiprobables y ruido blanco gaussiano de varianza en el plano:
donde son los puntos cuya etiqueta tiene un 0 en el bit , y los que tienen un 1. La tabla del mapper entra acá, en ese reparto: el demapper blando también tiene que usar la misma. Si de cada suma se conserva sólo el término más grande, queda la aproximación max-log:
Uno de los dos mínimos es la distancia al punto más cercano, el que elige el slicer, así que el signo del max-log es el bit que devuelve el demapper duro. Lo que el blando agrega es el módulo: cuánto más lejos está el mejor punto del bando contrario. En PAM-2, con y , cada suma tiene un solo término y la fórmula exacta queda , el LLR de la decisión blanda de la Unidad 3.
Medido en 16-QAM a 8 dB, sobre 8·10⁵ bits: el LLR de qamdemod(…, 'OutputType', 'llr') coincide con la suma de arriba hecha a mano con diferencia máxima de 4,3·10⁻¹⁴; el signo del exacto y el del max-log coinciden con el demapper duro en todos los bits, ninguno distinto. Y el módulo separa: la mediana de es 12,11 en los bits que el demapper duro acertó y 1,16 en los que erró. Los bits malos llegan marcados como dudosos, y el demapper duro les borra la marca. Un decodificador de canal que recibe los LLR puede pesar cada bit por su confianza; uno que recibe bits, no. Que la información para no equivocarse puede estar en las muestras y perderse en la decisión está medido, para el caso de la ISI, en El slicer tira información que está ahí.
El script arma el Gray, cuenta los pares de vecinos sobre las tablas de pammod, qammod y pskmod, corre la cadena con las dos tablas y con tablas desparejas, y saca los LLR. Usa my_slicer.m de la carpeta de scripts de la Unidad 4. Lo que figura como comentario es la salida real de correrlo en R2026a.
%% El mapper y el demapper: Gray contra natural, y tablas desparejas clear; close all; clc; %% 1. El código Gray: reflejado, y por la fórmula cerrada g = 0; for j = 1:4 g = [g, bitor(fliplr(g), 2^(j-1))]; % reflejar la lista y prender el bit nuevo end n = 0:15; fprintf('b = 3: %s\n', strjoin(cellstr(dec2bin(g(1:8), 3)), ' ')) fprintf('reflejado == n xor (n>>1): %d\n', isequal(g, bitxor(n, bitshift(n, -1)))) x = g; s = bitshift(g, -1); % la inversa, la que usa el demapper: while any(s), x = bitxor(x, s); s = bitshift(s, -1); end % n = g xor (g>>1) xor (g>>2) ... fprintf('inversa: %d\n', isequal(x, n)) % b = 3: 000 001 011 010 110 111 101 100 % reflejado == n xor (n>>1): 1 % inversa: 1 %% 2. Cuántos bits cuesta un error al vecino, con 'gray' y con 'bin' casos = {'PAM-4',4,'pam'; 'PAM-8',8,'pam'; '16-QAM',16,'qam'; '64-QAM',64,'qam'; ... '8-PSK',8,'psk'; '16-PSK',16,'psk'; '32-QAM',32,'qam'; '128-QAM',128,'qam'}; fprintf(' pares gray: >1 bit medio bin: >1 bit medio\n') for c = 1:size(casos, 1) M = casos{c,2}; k = (0:M-1).'; r = zeros(2, 2); for e = 1:2 et = {'gray', 'bin'}; et = et{e}; switch casos{c,3} case 'pam', p = pammod(k, M, 0, et); case 'qam', p = qammod(k, M, et); case 'psk', p = pskmod(k, M, 0, et); end [h, np] = costo_vecino(p, k); r(e,:) = [sum(h > 1), mean(h)]; end fprintf('%-8s %6d %10d %7.4f %10d %7.4f\n', casos{c,1}, np, r(1,1), r(1,2), r(2,1), r(2,2)) end % pares gray: >1 bit medio bin: >1 bit medio % PAM-4 3 0 1.0000 1 1.3333 % PAM-8 7 0 1.0000 3 1.5714 % 16-QAM 24 0 1.0000 8 1.3333 % 64-QAM 112 0 1.0000 48 1.5714 % 8-PSK 8 0 1.0000 4 1.7500 % 16-PSK 16 0 1.0000 8 1.8750 % 32-QAM 52 8 1.1538 24 1.6538 % 128-QAM 232 16 1.0690 96 1.7414 %% 3. La cadena: bits -> mapper -> ruido -> slicer -> demapper M = 16; b = log2(M); L = 1e6; rng(1) fprintf('\nEbN0 BER gray berawgn BER bin bin/gray SER gray SER bin bits mal (gray, bin)\n') for EbN0 = 6:2:12 bits = randi([0 1], L*b, 1); N0 = 10 / (b * 10^(EbN0/10)); % Ea = 10 para 16-QAM sin normalizar w = sqrt(N0/2) * (randn(L, 1) + 1j*randn(L, 1)); r = zeros(2, 3); for e = 1:2 et = {'gray', 'bin'}; et = et{e}; a = qammod(bits, M, et, 'InputType', 'bit'); % mapper ah = my_slicer(a + w, M); % slicer de la cátedra bh = qamdemod(ah, M, et, 'OutputType', 'bit'); % demapper, con la misma tabla r(e,:) = [mean(bh ~= bits), mean(ah ~= a), sum(bh ~= bits)]; end fprintf('%3d %.3e %.3e %.3e %.4f %.3e %.3e %d, %d\n', EbN0, r(1,1), ... berawgn(EbN0, 'qam', M), r(2,1), r(2,1)/r(1,1), r(1,2), r(2,2), r(1,3), r(2,3)) end % EbN0 BER gray berawgn BER bin bin/gray SER gray SER bin bits mal (gray, bin) % 6 2.791e-02 2.787e-02 3.723e-02 1.3340 1.085e-01 1.085e-01 111646, 148932 % 8 9.202e-03 9.247e-03 1.233e-02 1.3401 3.648e-02 3.663e-02 36808, 49326 % 10 1.773e-03 1.754e-03 2.378e-03 1.3412 7.073e-03 7.128e-03 7092, 9512 % 12 1.292e-04 1.387e-04 1.727e-04 1.3366 5.170e-04 5.230e-04 517, 691 %% 4. El demapper con otra tabla rng(2) fprintf('\nEbN0 SER BER misma BER conj(Q) BER bin en Rx\n') for EbN0 = [Inf 10 6] bits = randi([0 1], L*b, 1); a = qammod(bits, M, 'InputType', 'bit'); w = 0; if isfinite(EbN0), N0 = 10/(b*10^(EbN0/10)); w = sqrt(N0/2)*(randn(L,1) + 1j*randn(L,1)); end ah = my_slicer(a + w, M); b1 = qamdemod(ah, M, 'OutputType', 'bit'); % la misma tabla b2 = qamdemod(conj(ah), M, 'OutputType', 'bit'); % Q recorrido al revés b3 = qamdemod(ah, M, 'bin', 'OutputType', 'bit'); % natural en el receptor fprintf('%4g %.3e %.3e %.5f %.5f\n', EbN0, mean(ah ~= a), ... mean(b1 ~= bits), mean(b2 ~= bits), mean(b3 ~= bits)) end % PAM-4: la tabla de la filmina (00 arriba) leída con pamdemod (00 abajo) bits = randi([0 1], 2e5, 1); k = bit2int(bits, 2); tabla = [3 1 -3 -1]; % etiquetas 00 01 10 11 -> +3 +1 -3 -1 bh = int2bit(pamdemod(tabla(k+1).', 4, 0, 'gray'), 2); fprintf('filmina -> pamdemod: BER %.4f primer bit %.4f segundo %.4f\n', ... mean(bh ~= bits), mean(bh(1:2:end) ~= bits(1:2:end)), mean(bh(2:2:end) ~= bits(2:2:end))) % EbN0 SER BER misma BER conj(Q) BER bin en Rx % Inf 0.000e+00 0.000e+00 0.25000 0.24979 % 10 7.025e-03 1.759e-03 0.25115 0.25093 % 6 1.085e-01 2.788e-02 0.26850 0.25938 % filmina -> pamdemod: BER 0.5000 primer bit 1.0000 segundo 0.0000 %% 5. El orden de los bits bh = reshape(de2bi(k, 2).', [], 1); % de2bi entrega el bit menos significativo primero fprintf('bit2int -> de2bi: BER %.4f\n', mean(bh ~= bits)) % bit2int -> de2bi: BER 0.5016 %% 6. El demapper blando: un LLR por bit rng(3); L = 2e5; EbN0 = 8; bits = randi([0 1], L*b, 1); a = qammod(bits, M, 'InputType', 'bit'); N0 = 10/(b*10^(EbN0/10)); y = a + sqrt(N0/2)*(randn(L,1) + 1j*randn(L,1)); llr = qamdemod(y, M, 'OutputType', 'llr', 'NoiseVariance', N0); % ln P(0)/P(1) mlog = qamdemod(y, M, 'OutputType', 'approxllr', 'NoiseVariance', N0); % max-log dura = qamdemod(my_slicer(y, M), M, 'OutputType', 'bit'); P = qammod((0:M-1).', M); E = reshape(int2bit((0:M-1).', b), b, M).'; d2 = abs(y - P.').^2 / N0; mio = zeros(L, b); for j = 1:b % la suma de la definición, a mano mio(:,j) = log(sum(exp(-d2(:, E(:,j) == 0)), 2)) - log(sum(exp(-d2(:, E(:,j) == 1)), 2)); end mio = reshape(mio.', [], 1); fprintf('max |llr - a mano| = %.1e\n', max(abs(llr - mio))) fprintf('signo distinto de la dura: max-log %d, exacto %d (de %d bits)\n', ... sum((mlog < 0) ~= dura), sum((llr < 0) ~= dura), numel(dura)) ok = dura == bits; fprintf('mediana de |LLR|: bits bien %.2f, bits mal %.2f\n', median(abs(llr(ok))), median(abs(llr(~ok)))) % max |llr - a mano| = 4.3e-14 % signo distinto de la dura: max-log 0, exacto 0 (de 800000 bits) % mediana de |LLR|: bits bien 12.11, bits mal 1.16 %% La distancia de Hamming entre vecinos a distancia mínima function [h, np] = costo_vecino(p, k) D = abs(p - p.'); dmin = min(D(D > 1e-9)); [i1, i2] = find(triu(abs(D - dmin) < 1e-6*dmin)); h = arrayfun(@(q) sum(dec2bin(bitxor(k(i1(q)), k(i2(q)))) == '1'), 1:numel(i1)); np = numel(i1); end
Cuatro detalles que muerden si no se los conoce:
qammod y pskmod son Gray si no se les dice nada; pammod es natural. pammod(k, 8) da la tabla 'bin', y hay que pedir 'gray' explícitamente.qamdemod no sabe con qué tabla se mapeó: si el transmisor usó 'bin' y el receptor no lo dice, el demapper lee Gray y la BER queda en el piso de la sección 05. my_ber_checker.m no puede caer en esto porque demapea con qamdemod los dos vectores que compara.qamdemod es , así que un bit 1 es un LLR negativo. Y escala con 'NoiseVariance', que por omisión vale 1: con la constelación sin normalizar de qammod hay que pasarle la varianza verdadera. El signo no cambia; el módulo, sí, y el módulo es lo que usa el decodificador.de2bi y int2bit no ordenan igual. int2bit(6, 3) da [1 1 0] en columna, el más significativo primero; de2bi(6, 3) da [0 1 1] en fila. Mezclarlas entre el mapper y el demapper es el bloque 5.qammod deja 8 de 52 pares en dos bits, .int2bit/bit2int ponen el más significativo primero, de2bi/bi2de no.