← Índice del material Práctica 1 — Señales, correlación y convolución

Práctica 1: Señales, correlación y convolución

Señales y Sistemas Lineales

1 Introducción

En esta práctica ponemos a trabajar con MATLAB las operaciones básicas sobre señales ya vistas en teoría: la correlación, la convolución y la autocorrelación. En las dos primeras comparamos antes el cálculo del ordenador con un resultado teórico conocido, y después aplicamos la misma herramienta a una señal real o con ruido, donde el papel ya no llega: un radar que detecta objetos invisibles en la señal recibida y un efecto eco sobre una grabación de voz. Con la autocorrelación comparamos señales muy distintas (un pulso, una senoidal, ruido blanco y un código Barker), y cerramos volviendo al radar para ver por qué ese código separa dos objetos que el pulso senoidal confundía.

Damos por supuesta la Práctica 0, así que manejas vectores, operaciones elemento a elemento, funciones propias en archivos .m y los comandos básicos de representación gráfica.

Como en el resto de prácticas, el documento está pensado para que lo sigas escribiendo tú mismo el código en un script: no basta con leerlo, tienes que reproducir cada ejercicio y experimentar cambiando valores.

1.1 Objetivos

Al terminar deberías ser capaz de:

  • Construir en MATLAB señales discretas (un vector de muestras, dibujado con stem) y señales continuas (un vector de tiempos muy denso, dibujado con plot), incluidas las definidas a trozos.
  • Calcular la convolución de dos señales con conv y construir a mano el vector de índices del resultado, que MATLAB no proporciona.
  • Calcular la correlación cruzada como una convolución con una de las señales dada la vuelta (fliplr), e interpretar la posición de su máximo como un retardo.
  • Modelar un efecto eco como la convolución con una respuesta impulsional formada por deltas.
  • Reconocer las propiedades de la autocorrelación y explicar por qué la del ruido blanco es prácticamente una delta.
  • Justificar, a partir de su autocorrelación, por qué un código Barker mejora la resolución de un radar frente a un pulso senoidal de la misma duración.

1.2 Estructura de la práctica

El documento se divide en dos partes:

  • El trabajo previo debes prepararlo antes de acudir al laboratorio. Repasa cómo se representan las señales en MATLAB y las herramientas que usarás en la sesión. Cada ejercicio va acompañado de su solución, que puedes desplegar para comprobar tu respuesta. Intenta resolverlos por tu cuenta antes de mirarla.
  • El trabajo de laboratorio es lo que realizarás durante la sesión, y aplica esas herramientas a problemas concretos. También aquí cada ejercicio trae una solución desplegable con el resultado que debes obtener. Si llegas con el previo hecho, la sesión te cundirá mucho más.
AdvertenciaRecomendaciones

Es altamente recomendable trabajar en una carpeta dedicada solo para esta práctica y crear un archivo ejercicioX.m individual por cada ejercicio. En esa misma carpeta debes guardar los dos ficheros que se proporcionan para el trabajo de laboratorio, para que MATLAB pueda encontrarlos:

AdvertenciaCuestionario previo

Recuerda completar el cuestionario en Aula Virtual antes de acudir al laboratorio, cuando termines el trabajo previo.

2 Trabajo previo

2.1 Senoidales discretas

Una senoidal discreta con \(N_0\) muestras por periodo es \[x[n] = \cos\left(\frac{2\pi}{N_0}\, n\right)\] y se repite cada \(N_0\) muestras: \(x[n + N_0] = x[n]\).

Nota

Un periodo completo son las muestras \(n = 0, 1, \dots, N_0 - 1\), es decir, \(N_0\) valores. La muestra \(n = N_0\) ya no pertenece a ese periodo sino que es la primera del siguiente. Por tanto, \(\mathbf{P}\) periodos completos tienen \(\mathbf{P \cdot N_0}\) muestras.

En MATLAB, generamos los índices de esta forma:

n = 0 : P*N0 - 1;     % correcto:   P*N0 muestras
n = 0 : P*N0;         % incorrecto: P*N0 + 1 muestras (sobra una)
Tip✏️ Ejercicio 1

Construye y dibuja con stem dos periodos completos de una senoidal discreta de cinco muestras por periodo.

2.2 Señales continuas

Un ordenador solo puede guardar una lista finita de números. Por eso en MATLAB toda señal es un vector, también las continuas. Una señal continua \(x(t)\) se representa por sus valores en una rejilla de instantes muy próximos entre sí:

N  = 1000;                  % número de puntos
t  = linspace(0, 2, N);     % N instantes equiespaciados entre 0 y 2 s
x  = cos(2*pi*t);           % x(t) = cos(2πt) evaluada en esos instantes
plot(t, x)                  % plot une los puntos con líneas

Técnicamente, el vector x es una señal discreta, pero si el número de puntos \(N\) es suficientemente grande, los puntos están tan juntos que plot, al unirlos con líneas, dibuja una curva indistinguible de la señal continua.

Diferencias de uso respecto a las señales discretas:

Señal discreta \(x[n]\) Señal continua \(x(t)\)
Eje horizontal n = 0 : N-1 t = linspace(t_ini, t_fin, N)
Cada elemento es una muestra de la señal es un punto de la aproximación
Representación stem plot
Número de puntos lo fija la propia señal lo elegimos “suficientemente grande”
Nota

Toda señal en MATLAB es un vector y por tanto tiene un número finito de puntos. Cuando hablamos de señales continuas, nos referimos a que el número de puntos es suficientemente alto como para que la curva dibujada por plot sea indistinguible de la señal continua.

Tip✏️ Ejercicio 2

Dibuja la señal \(x(t) = \cos(2\pi t)\) con N = 1000 y con N = 10. Muéstralas superpuestas en una misma figura usando plot(t, x) en el primer caso y plot(t, x, 'o-') en el segundo. ¿Qué observas?

Con N = 1000 la curva se ve suave, pero con N = 10 sale quebrada, a trozos rectos: plot se limita a unir con segmentos los pocos puntos que tiene, y ni siquiera llega a los mínimos del coseno porque ningún punto cae sobre ellos.

2.3 Señales continuas a trozos

Todas las señales se construyen sobre un eje temporal como el del apartado anterior. En los siguientes ejemplos vamos a usar este vector de tiempos:

N = 1000;
t = linspace(-1, 6, N);     % t en [-1, 6] s

La herramienta clave para dibujar señales continuas a trozos son las condiciones lógicas. El método es siempre el mismo:

  1. Empezar con un vector de ceros del tamaño de t.
  2. Para cada tramo, definir la condición que lo delimita.
  3. Asignar el valor de la señal en ese tramo.

Lo vemos con ejemplos concretos:

1) Pulso \(p(t) = u(t) - u(t-2)\)

Recuerda que, esto es equivalente a la siguiente función definida a trozos: \[ x(t) = \begin{cases} 1, & 0 \le t < 2 \\ 0, & \text{en otro caso} \end{cases} \]

En MATLAB se implementa así:

x_pulso = zeros(size(t));
tramo_pulso = (t >= 0) & (t < 2);
x_pulso(tramo_pulso) = 1;
  • Con zeros(size(t)) inicializamos la señal a cero, mismo tamaño que t.
  • La condición (t >= 0) & (t < 2) devuelve un vector lógico, con true en las posiciones donde la condición se cumple, y false en las demás. Ese vector se puede usar para indexar.
  • La asignación x_pulso(tramo_pulso) = 1 pone a 1 todos los elementos de x_pulso donde la condición es true.

2) Pulso triangular, definido a trozos: \[ x(t) = \begin{cases} t, & 0 \le t < 1 \\ 2 - t, & 1 \le t < 2 \\ 0, & \text{en otro caso} \end{cases} \]

x_tri = zeros(size(t));

tramo_subida = (t >= 0) & (t < 1);
x_tri(tramo_subida) = t(tramo_subida);

tramo_bajada = (t >= 1) & (t < 2);
x_tri(tramo_bajada) = 2 - t(tramo_bajada);
  • Fíjate en que se usa x_tri(tramo_subida) = t(tramo_subida)
  • Usar x_tri(tramo_subida) = t daría lugar a un error de dimensiones, porque cada lado de la asignación tiene un tamaño distinto.

3) Trapecio, también definido a trozos: \[ x(t) = \begin{cases} t, & 0 \le t < 1 \\ 1, & 1 \le t < 3 \\ 4 - t, & 3 \le t < 4 \\ 0, & \text{en otro caso} \end{cases} \]

x_trap = zeros(size(t));

tramo_subida = (t >= 0) & (t < 1);
x_trap(tramo_subida) = t(tramo_subida);

tramo_plano = (t >= 1) & (t < 3);
x_trap(tramo_plano) = 1;

tramo_bajada = (t >= 3) & (t < 4);
x_trap(tramo_bajada) = 4 - t(tramo_bajada);
NotaFunciones a trozos

Usando condiciones lógicas y asignaciones, podemos construir cualquier señal continua a trozos.

Tip✏️ Ejercicio 3

Construye en MATLAB las tres señales anteriores sobre el eje t = linspace(-1, 6, 1000) y dibújalas con plot en una misma figura, una debajo de otra, con subplot(3,1,k). Añade a cada gráfica su título y las etiquetas de los ejes.

2.4 Cómo normalizar una señal

Normalizar una señal es cambiar su escala para que su amplitud tome un valor de referencia, normalmente 1. Es útil por varios motivos:

  • Las señales reales (audio, medidas de un sensor…) llegan con amplitudes arbitrarias, que dependen del equipo que las registró.
  • Permite comparar a simple vista señales de amplitudes muy distintas.
  • Algunas funciones lo exigen: sound(x, Fs) solo reproduce bien valores entre −1 y 1, y recorta los que se salen.

La forma más habitual es dividir por el valor máximo en valor absoluto:

x = x / max(abs(x));      % ahora max(abs(x)) vale 1
NotaNormalización al intervalo \([-1, 1]\)

La normalización x = x / max(abs(x)) transforma los valores de una señal al rango \([-1, 1]\).

2.5 Convolución

La convolución de dos secuencias discretas se define como \[y[n] = x_1[n] * x_2[n] = \sum_{k} x_1[k]\, x_2[n-k]\]

En MATLAB se calcula con y = conv(x1, x2). Hay que tener en cuenta dos cosas:

  • Si \(x_1\) tiene \(N\) muestras y \(x_2\) tiene \(M\), el resultado tiene \(N + M - 1\) muestras.
  • La función conv solo trabaja con vectores, no sabe dónde está \(n = 0\), por tanto, hay que construir a mano el vector de índices del resultado (en caso de necesitarlo).
NotaÍndices de la convolución

Si \(x_1[n]\) empieza en \(n_{1,\text{ini}}\) y \(x_2[n]\) empieza en \(n_{2,\text{ini}}\), el resultado empieza en \[n_{\text{ini}} = n_{1,\text{ini}} + n_{2,\text{ini}}\] y tiene \(N_1 + N_2 - 1\) muestras.

Tip✏️ Ejercicio 4

Calcula con MATLAB, usando el comando conv, la convolución de \[x_1[n] = \{1,\, \underset{\uparrow}{-1},\, 2\} \qquad\qquad x_2[n] = \{2,\, 3,\, \underset{\uparrow}{1}\}\]

a) Dibuja con stem las dos señales y el resultado, cada una frente a su vector de índices, en una misma figura con tres subgráficas (subplot(3,1,k)). Añade a cada gráfica su título y las etiquetas de los ejes.

b) Si quieres practicar, calcula antes el resultado a mano y comprueba que coincide.

Deberías obtener

\[y[n] = x_1[n] * x_2[n] = \{2,\, 1,\, 2,\, \underset{\uparrow}{5},\, 2\}, \qquad n = -3, \dots, 1\]

Para dibujar, necesitas los índices de cada señal:

  • Para \(x_1[n]\), sus íncides serían n1 = [-1 0 1]
  • Para \(x_2[n]\), sus íncides serían n2 = [-2 -1 0]
  • Para \(y[n]\), sus íncides serían n = [-3 -2 -1 0 1], o alternativamente n = (-1 - 2) : (-1 - 2 + 3 + 3 - 1)

Desarrollo a mano por el método tabular:

\(n=-3\) \(n=-2\) \(n=-1\) \(n=0\) \(n=1\)
\(x_1[-1]=1\) \(2(2)\) \(3(3)\) \(1(1)\)
\(x_1[0]=-1\) \(-2(2)\) \(-3(3)\) \(-1(1)\)
\(x_1[1]=2\) \(4(2)\) \(6(3)\) \(2(1)\)
\(y[n]\) \(\mathbf{2}\) \(\mathbf{1}\) \(\mathbf{2}\) \(\mathbf{5}\) \(\mathbf{2}\)

2.6 Correlación

La correlación cruzada mide el parecido entre dos señales en función del desplazamiento \(l\). En esta asignatura la definimos como \[R_{xy}[l] = \sum_{n} x[n]\, y[n+l]\]

Es muy parecida a la convolución. De hecho, si le damos la vuelta a \(\mathbf{x}\), la correlación se convierte en una convolución. Por eso, la correlación \(R_{xy}[l]\) en MATLAB se calcula con R = conv(fliplr(x), y), donde el comando fliplr(x) simplemente le da la vuelta al vector x:

AdvertenciaLa correlación no es conmutativa

Recuerda que la correlación no es conmutativa, \(R_{xy}[l]\) no es igual a \(R_{yx}[l]\), y por tanto, en MATLAB, conv(fliplr(x), y) y conv(fliplr(y), x) dan resultados reflejados.

NotaDesplazamietos de la correlación

El primer desplazamiento es aquel en el que la última muestra de \(x_1\) se solapa con la primera de \(x_2\): \[l_{\text{ini}} = n_{2,\text{ini}} - n_{1,\text{fin}}\] y tiene \(N_1 + N_2 - 1\) valores.

Tip✏️ Ejercicio 5

Calcula con MATLAB, usando los comandos conv y fliplr, la correlación \(R_{x_1x_2}[l]\) de \[x_1[n] = \{1,\, \underset{\uparrow}{-1},\, 2\} \qquad\qquad x_2[n] = \{2,\, 3,\, \underset{\uparrow}{1}\}\]

a) Dibuja con stem las dos señales y el resultado, cada una frente a su vector de índices, en una misma figura con tres subgráficas (subplot(3,1,k)). Añade a cada gráfica su título y las etiquetas de los ejes.

b) Si quieres practicar, calcula antes el resultado a mano y comprueba que coincide.

Deberías obtener

\[R_{x_1x_2}[l] = \{4,\, 4,\, 1,\, \underset{\uparrow}{2},\, 1\}, \qquad l = -3, \dots, 1\]

Desarrollo a mano por el método tabular:

\(l=-3\) \(l=-2\) \(l=-1\) \(l=0\) \(l=1\)
\(x_1[-1]=1\) \(2(2)\) \(3(3)\) \(1(1)\)
\(x_1[0]=-1\) \(-2(2)\) \(-3(3)\) \(-1(1)\)
\(x_1[1]=2\) \(4(2)\) \(6(3)\) \(2(1)\)
\(R_{x_1x_2}[l]\) \(\mathbf{4}\) \(\mathbf{4}\) \(\mathbf{1}\) \(\mathbf{2}\) \(\mathbf{1}\)

2.7 Autocorrelación

La autocorrelación es simplemente la correlación de una señal consigo misma: \[R_{xx}[l] = \sum_{n} x[n]\, x[n+l]\]

En MATLAB:

  • se calcula igual que la correlación cruzada: r = conv(fliplr(x), x)
  • los índices son muy sencillos, l = -(N-1) : (N-1), donde \(N\) es el número de muestras de la señal.
NotaDesplazamietos de la autocorrelación

El vector de desplazamientos de la autocorrelación es simétrico, con \(N-1\) valores negativos, uno cero y \(N-1\) positivos, siendo \(N\) el número de muestras de la señal.

Recuerda sus principales propiedades:

  • Máximo en el origen. \(R_{xx}[0] = \sum_n x^2[n] = E_x\) es la energía de la señal, y se cumple \(|R_{xx}[l]| \le R_{xx}[0]\).
  • Simetría par. \(R_{xx}[-l] = R_{xx}[l]\).
  • Periodicidad. Si \(x[n]\) es periódica, su autocorrelación también lo es, con el mismo periodo.

2.8 Respuesta impulsional de un “efecto eco” en audio

Un eco consiste en escuchar la señal original y, un tiempo después, copias suyas más débiles. Se modela con la respuesta impulsional \[h[n] = \delta[n] + a_1\,\delta[n-n_1] + a_2\,\delta[n-n_2]\]

NotaConvolución con deltas

Recuerda que la convolución con una delta \(\delta[n-n_0]\) simplemente copia la señal y la desplaza \(n_0\) muestras, es decir:

\[ x[n] * \delta[n-n_0] = x[n-n_0]\]

Al convolucionar una señal \(x[n]\) con \(h[n]\) cada delta “copia” la señal en su posición:

\[y[n] = x[n] * h[n] = x[n] + a_1\,x[n-n_1] + a_2\,x[n-n_2]\]

Cada término tiene un significado:

  • \(x[n]\): la señal original, sin retardo ni atenuación.
  • \(a_1\,x[n-n_1]\): primer eco, retardado \(n_1\) muestras y multiplicado por \(a_1\).
  • \(a_2\,x[n-n_2]\): segundo eco, retardado \(n_2\) muestras y multiplicado por \(a_2\).

Relación entre retardo en muestras y retardo temporal

Con frecuencia de muestreo \(F_s\), cada muestra dura \(T_s = 1/F_s\) segundos, por tanto, la relación entre retardo en muestras \(n\) y retardo temporal \(\tau\) es: \[\tau = \frac{n}{F_s} \qquad \Longleftrightarrow \qquad n = \tau \cdot F_s\]

Por ejemplo, con \(F_s = 8000\) Hz, un retardo de 0.25 s corresponde a \(n_1 = 2000\) muestras.

Significado de los coeficientes

Los coeficientes \(a_1\) y \(a_2\) indican qué fracción de la amplitud original conserva cada eco. Deben cumplir \(0 < a_i < 1\) para que el eco sea más débil que el original. Así, un 30 % de atenuación correspondería a un coeficiente \(a = 0.7\).

Tip✏️ Ejercicio 6

Con una frecuencia de muestreo \(F_s = 1000\) Hz, construye en MATLAB la respuesta impulsional \(h[n]\) de un efecto eco en el que el primer eco llega con un retardo de 10 ms y una atenuación del 50 %, y el segundo con un retardo de 20 ms y una atenuación del 75 %.

a) Calcula los parámetros \(a_1, n_1, a_2, n_2\).

b) Construye h con zeros e introduce a mano sus tres elementos no nulos. Dibújala con stem, con el eje x en muestras.

a) Una atenuación del 50 % conserva la mitad de la amplitud, y una del 75 %, la cuarta parte: \(a_1 = 0.5\) y \(a_2 = 0.25\). Los retardos en muestras son \(n_1 = 0.010 \cdot 1000 = 10\) y \(n_2 = 0.020 \cdot 1000 = 20\), así que \[h[n] = \delta[n] + 0.5\,\delta[n-10] + 0.25\,\delta[n-20]\]

b) Como los vectores de MATLAB empiezan en 1, la muestra \(h[n]\) se guarda en h(n+1):

clear all; close all; clc;
Fs = 1000;               % frecuencia de muestreo (Hz)

% Primer eco:  10 ms -> 10 muestras
a1 = 0.5;  n1 = 0.010 * Fs;

% Segundo eco: 20 ms -> 20 muestras
a2 = 0.25; n2 = 0.020 * Fs;    

% Construcción de la respuesta impulsional
h = zeros(1, n2 + 1);    % n = 0..n2
h(1)      = 1;           % señal directa (n = 0, pero en MATLAB es el índice 1)
h(n1 + 1) = a1;          % primer eco    (n = n1, pero en MATLAB es el índice n1 + 1)
h(n2 + 1) = a2;          % segundo eco   (n = n2, pero en MATLAB es el índice n2 + 1)

n = 0 : n2;
stem(n, h, 'filled'); grid on; xlim([-1 n2 + 1]); ylim([0 1.2]);
xlabel('$n$', 'Interpreter', 'latex');
ylabel('$h[n]$', 'Interpreter', 'latex');
title('Respuesta impulsional de un filtro efecto eco');

2.9 Ruido blanco

El ruido blanco es una señal aleatoria en la que cada muestra es independiente de todas las demás.

En MATLAB se genera con randn:

rng(0);                   % semilla fija (opcional): el mismo ruido cada vez, permite reproducir resultados
N = 1000;
w = randn(1, N);          % N muestras gaussianas de media 0 y varianza 1
Advertenciarandn no es rand

El comando rand genera valores uniformemente aleatorios entre 0 y 1. El comando randngenera valores aleatorios gaussianos de media 0 y varianza 1. No es lo mismo. Para simular ruido blanco, hay que usar randn.

Si queremos pasar de media cero y desviación típica 1 a una media \(\mu\) y desviación típica \(\sigma\), podemos usar:

w = mu + sigma * randn(1, N);

La propiedad más importante del ruido blanco es que no está autocorrelado:

Nota

Como cada muestra es independiente de las demás, conocer \(w[n]\) no dice nada sobre \(w[n+l]\) para \(l \neq 0\). Idealmente, la autocorrelación del ruido blanco es una delta:

\[R_{ww}[l] = N\sigma^2\,\delta[l]\]

Podemos usar esta propiedad para detectar señales útiles en presencia de ruido. Al correlacionar una señal con ruido, el ruido solo aporta en \(l = 0\), mientras que la parte útil de la señal deja su huella en el resto de desplazamientos.

Puedes ejecutar el siguiente código en MATLAB para ver la autocorrelación de una secuencia de ruido blanco; deberías ver un pico central y valores muy pequeños en los desplazamientos distintos de cero:

w = randn(1, 1001);
r = conv(fliplr(w), w);
l = -1000 : 1000;
plot(l, r)

2.10 Código Barker

Un código Barker es una secuencia finita de \(N\) valores \(\pm 1\) cuya autocorrelación es “casi ideal”: \[R[0] = N, \qquad |R[l]| \le 1 \quad \text{para } l \neq 0\]

Es decir, el pico central es muy alto y los lóbulos laterales son como mucho de valor 1. Solo existen para las longitudes 2, 3, 4, 5, 7, 11 y 13.

Se usan en:

  • Radar (compresión de pulso). Se emite un pulso largo, que tiene más energía, modulado en fase con un código Barker. Al correlarlo en el receptor se obtiene un pico estrecho, que da buena resolución en distancia.
  • Comunicaciones. Se usan para sincronización de tramas. El estándar Wi-Fi 802.11b usa el código de longitud 11 para ensanchar el espectro.
  • En general, en cualquier sistema en el que haya que detectar con precisión cuándo llega una secuencia conocida, incluso con ruido.
\(N\) Código Lóbulo lateral máximo Relación pico/lóbulo
2 \(\{+1,\,-1\}\) ó \(\{+1,\,+1\}\) 1 2
3 \(\{+1,\,+1,\,-1\}\) 1 3
4 \(\{+1,\,+1,\,-1,\,+1\}\) ó \(\{+1,\,+1,\,+1,\,-1\}\) 1 4
5 \(\{+1,\,+1,\,+1,\,-1,\,+1\}\) 1 5
7 \(\{+1,\,+1,\,+1,\,-1,\,-1,\,+1,\,-1\}\) 1 7
11 \(\{+1,\,+1,\,+1,\,-1,\,-1,\,-1,\,+1,\,-1,\,-1,\,+1,\,-1\}\) 1 11
13 \(\{+1,\,+1,\,+1,\,+1,\,+1,\,-1,\,-1,\,+1,\,+1,\,-1,\,+1,\,-1,\,+1\}\) 1 13
Tip✏️ Ejercicio 7

Calcula a mano la autocorrelación de la secuencia Barker de longitud 7 usando el método tabular y verifica que su valor absoluto es menor o igual que uno para cualquier desplazamiento distinto de cero.

Secuencia: \(b[n] = \{1, 1, 1, -1, -1, 1, -1\}\), con la primera muestra en \(n = 0\). La autocorrelación es simétrica, \(R[-l] = R[l]\), así que basta con calcular la mitad de la tabla:

\(l=0\) \(l=1\) \(l=2\) \(l=3\) \(l=4\) \(l=5\) \(l=6\)
\(b[0]=1\) \(1(1)\) \(1(1)\) \(1(1)\) \(-1(-1)\) \(-1(-1)\) \(1(1)\) \(-1(-1)\)
\(b[1]=1\) \(1(1)\) \(1(1)\) \(-1(-1)\) \(-1(-1)\) \(1(1)\) \(-1(-1)\)
\(b[2]=1\) \(1(1)\) \(-1(-1)\) \(-1(-1)\) \(1(1)\) \(-1(-1)\)
\(b[3]=-1\) \(1(-1)\) \(1(-1)\) \(-1(1)\) \(1(-1)\)
\(b[4]=-1\) \(1(-1)\) \(-1(1)\) \(1(-1)\)
\(b[5]=1\) \(1(1)\) \(-1(-1)\)
\(b[6]=-1\) \(1(-1)\)
\(R[l]\) \(\mathbf{7}\) \(\mathbf{0}\) \(\mathbf{-1}\) \(\mathbf{0}\) \(\mathbf{-1}\) \(\mathbf{0}\) \(\mathbf{-1}\)

Los valores para \(l < 0\) son los mismos, reflejados respecto a \(l = 0\):

\[R[l] = \{-1, 0, -1, 0, -1, 0, \underset{\uparrow}{7}, 0, -1, 0, -1, 0, -1\}\]

2.11 Convolución y correlación de señales continuas

Un pequeño apunte en el caso de señales continuas. Con señales discretas, conv calcula exactamente la suma de la convolución o de la correlación. Con señales continuas, en cambio, estas operaciones son integrales, y conv solo calcula la suma de los puntos del vector (Sección 2.2). Una integral se aproxima por esa suma multiplicada por la separación entre puntos: \[\int x(t)\,dt \approx \sum_k x(t_k)\,\Delta t \qquad\Longrightarrow\qquad \texttt{sum(x)*dt}\]

Por tanto, en el caso continuo la única diferencia es que hay que multiplicar por dt el resultado de conv:

  • Convolución: y = conv(x, h) * dt
  • Correlación cruzada: r = conv(fliplr(x), y) * dt
  • Autocorrelación: r = conv(fliplr(x), x) * dt

3 Trabajo de laboratorio

3.1 Correlación

Tip✏️ Ejercicio 8

Considera las señales

\[f[n] = \left(\tfrac{1}{3}\right)^n u[n-1], \qquad g[n] = 2\, u[n-2]\]

cuya correlación cruzada teórica es

\[ R_{fg}[l] = \begin{cases} 3^{\,l-1}, & l \le 1 \\ 1, & l > 1 \end{cases} \]

a) Construye las dos señales y dibuja cada una con stem frente a su vector de índices en los dos primeros paneles de un subplot(3,1,k) (ver solución)

b) Calcula su correlación cruzada \(R_{fg}[l] = \sum_n f[n]\,g[n+l]\) y compárala con la correlación teórica en una misma gráfica, usando stem para la calculada y plot para la teórica (ver solución)

c) Explica qué observas. ¿Coincide la solución calculada con la teórica? ¿Por qué?

NOTA: Las dos señales son infinitas, así que en MATLAB hay que cortar en algún momento. Constrúyelas para n = 0:9, o sea \(N = 10\) muestras.

Tip✏️ Ejercicio 9

Un radar emite un pulso formado por cuatro periodos completos de una senoidal discreta de 10 muestras por ciclo: \[p[n] = \cos\left(\frac{2\pi}{10}\, n\right), \qquad n = 0, 1, \dots, 39\]

Dicho pulso se refleja en los objetos a su alcance y la señal rebotada se registra en un receptor. El eco de cada objeto llega con un retardo de \(D\) muestras que depende de su distancia. Debido a la frecuencia de la onda empleada y al periodo de muestreo del receptor, se sabe que cada muestra de retardo equivale a unos 150 m de distancia entre el radar y el objeto.

a) Dibuja el pulso completo con stem en el panel superior de una figura con 3 × 1 subplots, con el eje x en muestras.

b) Usa la función proporcionada x_n = senyal_radar(dist_obj1, dist_obj2, pulso) para generar una señal recibida ficticia y dibújala en el segundo panel de la misma figura, con el eje x en muestras. Las variables dist_obj1 y dist_obj2 deben ir en metros y pulso es el vector del apartado anterior. Si alguno de los tres no es el esperado, la función se detiene con un mensaje que explica qué hay que corregir. Elige sus valores para simular dos objetos a distancias de 15 km y 45 km.

c) Calcula la correlación cruzada \(R_{px}[l]\) entre el pulso y la señal recibida y dibújala en el panel inferior de la misma figura.

d) Calcula los máximos de la correlación y sus ubicaciones. A partir de esos datos, determina la distancia de los objetos al radar. Si quieres hacerlo de forma automática puedes usar [picos, pos] = findpeaks(r_px, 'NPeaks', 2, 'SortStr', 'descend','MinPeakDistance', length(pulso)), que devuelve el valor de los picos y sus índices.

e) Reduce la distancia entre los dos objetos, por ejemplo, 15 km y 16 km. ¿Qué ocurre con la correlación? ¿Se pueden distinguir los dos objetos? ¿Qué necesitaríamos en la correlación para poder distinguirlos?

Como ejemplo, colocamos los objetos a 15 km y a 45 km.

Objeto 1: retardo = 100 muestras, distancia = 15.00 km
Objeto 2: retardo = 300 muestras, distancia = 45.00 km

3.2 Convolución

Tip✏️ Ejercicio 10

Considera las mismas señales del ejercicio de correlación,

\[f[n] = \left(\tfrac{1}{3}\right)^n u[n-1], \qquad g[n] = 2\, u[n-2]\]

cuya convolución teórica es

\[ y[n] = \begin{cases} 1 - \left(\tfrac{1}{3}\right)^{n-2}, & n \ge 2 \\ 0, & n < 2 \end{cases} \]

a) Construye las dos señales y dibuja cada una con stem frente a su vector de índices en los dos primeros paneles de un subplot(3,1,k) (ver solución)

b) Calcula su convolución \(y[n] = f[n] * g[n]\) y compárala con la convolución teórica en una misma gráfica, usando stem para la calculada y plot para la teórica (ver solución)

c) Explica qué observas. ¿Coincide la solución calculada con la teórica? ¿Por qué?

NOTA: Las dos señales son infinitas, así que en MATLAB hay que cortar en algún momento. Constrúyelas para n = 0:9, o sea \(N = 10\) muestras.

Tip✏️ Ejercicio 11

Carga el fichero datos_voz.mat, que contiene una señal de audio (variable x) y su frecuencia de muestreo (variable Fs). Puedes escuchar el audio con el comando sound(x, Fs).

a) Normaliza la señal para que su valor máximo en valor absoluto sea 1, con x = x / max(abs(x)) (ver Sección 2.4). Después dibújala en el panel superior de una figura con 3 × 1 subplots, con el eje temporal en segundos.

b) Elige los parámetros \(a_1, n_1, a_2, n_2\) de la respuesta impulsional del efecto eco, \(h[n] = \delta[n] + a_1\,\delta[n-n_1] + a_2\,\delta[n-n_2]\), para que el primer eco esté retardado 0.25 s con una atenuación del 30 % y el segundo eco esté retardado 0.5 s con una atenuación del 60 %.

c) Construye la señal \(h[n]\). Inicialízala con zeros(n2 + 1, 1) e introduce a mano los elementos no nulos (la muestra de la señal directa y las dos de los ecos). Dibújala en el segundo panel de la figura, con el eje x en muestras.

d) Calcula la convolución de la señal con la respuesta impulsional y dibújala en el tercer panel de la figura, con el eje x en segundos. Por último, escucha el resultado y comprueba que el efecto es el esperado.

b) Una atenuación del 30 % conserva el 70 % de la amplitud, y una del 60 %, el 40 %: \(a_1 = 0.7\) y \(a_2 = 0.4\). Los retardos en muestras son \(n_1 = 0.25\,F_s\) y \(n_2 = 0.5\,F_s\) (ver Sección 2.8).

3.3 Autocorrelación

Tip✏️ Ejercicio 12

En este ejercicio las señales son continuas. Usa para las cuatro el mismo eje temporal:

  • Rango: \(t \in [0, 5]\) s
  • Número de puntos: \(N = 1001\), es decir, t = linspace(0, 5, 1001), con separación \(\Delta t = 5/1000 = 5\) ms

La autocorrelación de una señal continua es \[R_x(\tau) = \int x(t)\, x(t+\tau)\, dt\] y se aproxima según lo descrito en la Sección 2.11.

a) Genera una figura con 4 × 2 subplots. Dibuja con plot en la columna de la izquierda las siguientes señales y en la columna de la derecha su autocorrelación en función de \(\tau\):

  1. \(x_1(t) = u(t) - u(t - 2)\), un pulso que va de 0 a 2 s
  2. \(x_2(t) = \cos(4\pi t)\), de periodo 0.5 s
  3. \(x_3(t)\) = ruido blanco gaussiano de media nula y varianza unidad (randn(1, N), ver Sección 2.9)
  4. \(x_4(t)\) es un pulso codificado con código Barker que puedes construir con x4 = repelem(b, 77), siendo b el vector que contiene el código Barker de longitud 13.

NOTA: la función repelem repite cada elemento del vector b 77 veces, de manera que la señal resultante tiene 13 x 77 = 1001 puntos, igual que las demás.

b) Trata de explicar los siguientes aspectos:

  1. ¿Por qué todas tienen su máximo en el origen?
  2. ¿Por qué la autocorrelación de la senoidal oscila? ¿Por qué se estrecha en los extremos?
  3. ¿Por qué el ruido blanco tiene ese pico abrupto en el origen y es prácticamente cero en el resto? ¿Cómo podemos aprovechar esto para detectar periodicidades en señales muy ruidosas?
  4. ¿Qué diferencia la autocorrelación del código Barker respecto a la del pulso rectangular? ¿Por qué es puede ser útil en comunicaciones digitales?

a)

3.4 Radar con código Barker

Tip✏️ Ejercicio 13

En el ejercicio del radar, el pulso senoidal no permitía distinguir dos objetos a 15 km y 16 km. Vamos a sustituirlo por un pulso de casi la misma duración construido con un código Barker. Puedes reciclar casi todo el código del ejercicio del radar. Solamente cambia la construcción del pulso y dos detalles que dependían de él:

  • el pulso senoidal tenía 40 muestras; para una duración similar, usa un código Barker de longitud 13 con 3 muestras por símbolo (39 muestras), con repelem como en el ejercicio de autocorrelación.

  • el eje del pulso, que ahora será n_pulso = 0 : length(pulso)-1

  • la separación mínima entre picos de findpeaks, que pasa a 'MinPeakDistance', 3 porque el pico del código Barker es mucho más estrecho.

Objeto 1: retardo = 100 muestras, distancia = 15.00 km
Objeto 2: retardo = 107 muestras, distancia = 16.05 km