%% OFDM: Señales senoidales/cosenoidales y FFT
% Copyright (c) 2023 G.T.A.S. (Grupo Tratamiento Avanzado de Señal). Universidad de Cantabria.
%
% Ejemplo de la relación entre una señal senoidal/cosenoidal y la Transformada Discreta de Fourier (DFT, implementada mediante el algoritmo FFT: Fast Fourier Transform).
%
% Se trata de generar una señal exponencial compleja:
% x[n]=s_ke^{j \frac{2\pi k}{N} n}, para n=0,1,\ldots,N-1,
% siendo s_k=A_ke^{j\phi_k el valor complejo que representa la amplitud y fase de la señal y \omega_k=k/Nsu frecuencia discreta (en rad/s).
%
% Por relaciones trigonométricas básicas sabemos que una exponencial compleja es una señal compleja cosenoidal en su parte real y senoidal en su parte imaginaria:
% x[n]=s_ke^{j \frac{2\pi k}{N} n}=A\cos(2\pi\omega_kn+\phi_k)+jA\sin(2\pi\omega_kn+\phi_k) para n=0,1,\ldots,N-1.
%% Parámetros
% El alumno puede modificar estos parámetros, donde N es la longitud de la secuencia (el número de muestras de la señal y, como veremos, el número de subportadoras), k el índice de la subportadora (es decir, la señal tendrá una frecuencia discreta \omega_k=k/N, por lo que poseerá k periodos exactos en las N muestras) y s_k el valor complejo que representa la amplitud y fase de la señal.

N = 64;     % Longitud de la señal y número de subportadoras (tamaño de FFT)
k = 7;      % Índice de la Subportadora (0<=k<N). Su frecuencia discreta es k/N, es decir, posee k periodos en N muestras
s_k = 3*exp(1i*3*pi/4*0);   % Amplitud y fase de la subporetadora k-ésima

%% Construcción de la señal en el dominio del tiempo
% En esta sección construimos la señal x[n] en el dominio del tiempo.

n = 0:N-1;    % vector de índices temporales
x = s_k*exp(1i*2*pi*n*k/N)
subplot(411);plot(n,real(x),'r-o');legend('real(x[n])');xlabel('n');grid
title(sprintf('Señal generada en el dominio del tiempo (k=%i)',k));
subplot(412);plot(n,imag(x),'b-o');legend('imag(x[n])');xlabel('n');grid

%
%% Construcción de la señal mediante IFFT
% Ahora vamos a generar la señal x[n] partiendo de su representación en el dominio de la frecuencia y utilizando la IFFT (Inverse Fast Fourier Transform).
% La Transformada Discreta de Fourier (DFT) de una señal como x[n] (con un número exacto, k, de periodos en las N muestras) es un vector X[k] de N valores complejos nulos salvo el k-simo que tomará el valor s_k. Puedo formar con Matlab dicho vector (secuencia) X[k] y obtener a partir de él la señal x[n] mediante la DFT inversa
% x[n]=DFT^{-1}\{X[k]\}=IFFT\{X[k]\}N.

X = zeros(1,N);     % Vector de ceros en el dominio de la frecuencia
X(k+1) = s_k;       % La frecuencia (subportadora) k-ésima  toma (se modula por) el valor s_k
x2 = N*ifft(X);     % Calculamos la IFFT para obtener la secuencia temporal x2 cuya FFT es X
subplot(413);plot(n,real(x2),'r-o');legend('real(x[n])');xlabel('n');grid
title('Señal generada mediante IFFT');
subplot(414);plot(n,imag(x2),'b-o');legend('imag(x[n])');xlabel('n');grid

%
%% Prueba tú ahora
% Modifica los parámetros iniciales probando con distintos valores de k y distintas amplitudes y fases. Comprueba que siempre las señal generadas en el dominio del tiempo y en el dominio de la frecuencia son idénticas. Fíjate también que la señal de frecuencia \omega_k=k/N posee k periodos exactos en las N muestras.
% Añade más componentes (subportadoras) no nulas al vector X. Tendrás una señal suma de varias exponenciales complejas (cada una con su frecuencia, amplitud y fase). Por ejemplo, una subportadora adicional de frecuencia 2/N (2 periodos en N muestras), amplitud \sqrt2 y fase 45º  se podría añadir en el dominio de la frecuencia haciendo:

X = zeros(1,N);     % Vector de ceros en el dominio de la frecuencia
X(k+1) = s_k;       % La frecuencia (subportadora) k-ésima  toma (se modula por) el valor s_k
X(2+1) = +1+1i;     % Nueva subportadora adicional (k=2)
x2 = N*ifft(X);     % Calculamos la IFFT para obtener la secuencia temporal x2 cuya FFT es X
subplot(211);plot(n,real(x2),'r-o');legend('real(x[n])');xlabel('n');grid;subplot(212);plot(n,imag(x2),'b-o');legend('imag(x[n])');xlabel('n');grid