9- código matlab. - bibing.us.esbibing.us.es/proyectos/abreproy/11014/fichero/volumen+1%2f9... ·...
TRANSCRIPT
Código Matlab
Escuela Superior de Ingenieros 108
9- Código Matlab.
Para realizar las distintas funciones que hemos usado en el presente proyecto
se ha empleado el programa Matlab. Matlab es una lengua técnica de cálculo de alto
nivel y un ambiente interactivo para el desarrollo de algoritmos, la visualización de
datos, el análisis de datos y el cómputo numérico [31].
En esta sección vamos a mostrar las distintas rutinas que hemos implementado
para obtener las gráficas y los resultados que aparecen en la sección 6.
Hemos subdividido la presente sección en tres subapartados distintos, el
primero contiene funciones que se usan tanto para el caso radix-2 como para el caso
radix-4; el segundo contiene funciones que solo se usan para el caso radix-2; y el
tercero contiene funciones que se usan solo en el caso radix-4.
Por último decir que siempre que se han encontrado dificultades a la hora de
usar Matlab se ha acudido a [32].
9.1.- Funciones generales
stringOut=bit_reversed(STRING)
%%
%% FUNCION QUE PONE LA CADENA EN EL ORDEN CORRECTO
%%
%% ENTRADAS:
%% string -> Cadena que le paso
%%
%% SALIDA:
%% stringOut -> Cadena en el orden correcto
%%
function stringOut=bit_reversed(STRING)
Leng=length(STRING);
N=1; % siempre la longitude de la cadena es un multiplo de 2^N
Código Matlab
Escuela Superior de Ingenieros 109
while 2^N < Leng
N=N+1;
end
stringOut=STRING;
for index=0:(Leng-1)
newIndex=dec2bin(index,N);
newIndex=invert(newIndex);
newIndex=bin2dec(newIndex);
newIndex=newIndex+1;
stringOut(newIndex,:)=STRING(index+1,:);
end
y= c2sat
%%
%% FUNCION QUE REALIZA LA SATURACION DE UN NUMERO
%%
%% ENTRADAS:
%% num -> numero a saturar. Sera la parte real o la imaginaria del
%% numero num [-1,1)
%% NB_DI -> numero de bits de la saturaci´on
%% DEBUG -> sera 1 o 0. Si vale 1 aparecera el mensaje, si vale 0 no
%%
%% SALIDA:
%% y -> numero saturado.
%%
function y= c2sat ( num, NB_DI,DEBUG)
Q_DI=2^(NB_DI-1);
id=find(num>1);
num(id)=(Q_DI-1)/Q_DI;
Código Matlab
Escuela Superior de Ingenieros 110
Nmodif=length(id);
id=find(num<=-1);
num(id)=-1;
Nmodif=Nmodif+length(id);
if ((DEBUG==1) & (Nmodif~=0))
fprintf ('\n se ha realizado saturacion\n');
end
y=num;
xq=gen_rnd_data(N_PTS,NB_DI)
%%
%% CREO UNA SEÑAL ALEATORIA ENTRE [-1,1] Y LA CUANTIZO
%%
%% ENTRADAS:
%% N_PTS -> numero de puntos de la señal aleatoria
%% NB_DI -> numero de bits de cuantizacion de la señal de entrada
%%
%% SALIDA:
%% xq -> señal entre [-1,1] cuantizada a NB_DI bits.
%%
function xq=gen_rnd_data(N_PTS,NB_DI)
format long;
Q_DI=2^(NB_DI-1);
x=rand(N_PTS,1);
x=-2*x+1;
xq=floor(Q_DI*x)/Q_DI;
idx=find(xq==1);
xq(idx)=(Q_DI-1)/Q_DI;
Código Matlab
Escuela Superior de Ingenieros 111
xq=gen_rnd_data(N_PTS,NB_DI)
%%
%% INVIERTE UNA CADENA
%%
%% ENTRADAS:
%% string -> cadena que le paso
%%
%% SALIDAS:
%% string -> cadena original invertida
function string=invert(string)
Leng=length(string);
for index=1:(Leng/2)
top=string(index);
bot=string(Leng-index+1);
string(index)=bot;
string(Leng-index+1)=top;
end
y=multiplic(b,w,NB_TRMUL)
%%
%% REALIZO LA MULTIPLICACION DE DOS NUMEROS Y CUANTIZO
%%
%% ENTRADAS:
%% b -> numero a multiplicar
%% w -> numero a multiplicar
%% NB_TRMUL -> numero de bits de cuantizacion en la multiplicacion
%%
%% SALIDA:
%% y -> valor de b*w cuantizado
%%
function y=multiplic(b,w,NB_TRMUL)
Q_TRMUL = 2^(NB_TRMUL-1);
Código Matlab
Escuela Superior de Ingenieros 112
b_rel = real (b);
b_img = imag (b);
w_rel = real (w);
w_img = imag (w);
br_wr = floor(Q_TRMUL *(b_rel*w_rel)); % multiplico b_real y w_real
idbr_wr = find(br_wr==Q_TRMUL);
br_wr(idbr_wr) = (Q_TRMUL-1);
bi_wi = floor(Q_TRMUL *(b_img*w_img)); % multiplico b_imag y w_imag
idbi_wi = find(bi_wi==Q_TRMUL);
bi_wi(idbi_wi) = (Q_TRMUL-1);
br_wi = floor(Q_TRMUL *(b_rel*w_img)); % multiplico b_real y w_imag
idbr_wi = find(br_wi==Q_TRMUL);
br_wi(idbr_wi) = (Q_TRMUL-1);
bi_wr = floor(Q_TRMUL *(b_img*w_rel)); % multiplico b_imag y w_real
idbi_wr = find(bi_wr==Q_TRMUL);
bi_wr(idbi_wr) = (Q_TRMUL-1);
br_wr = br_wr/(Q_TRMUL);
bi_wi = bi_wi/(Q_TRMUL);
br_wi = br_wi/(Q_TRMUL);
bi_wr = bi_wr/(Q_TRMUL);
bw_rel = (br_wr - bi_wi); % parte real del resultado
bw_img = (br_wi + bi_wr); % parte imaginaria del resultado
y = bw_rel + i*bw_img;
matriz=rnd_vect_in(num,N_PTS,NB_DI)
%%
%% GENERA EL COMJUNTO DE VECTORES ALEATORIOS DE ENTRADA
%%
%% Entradas:
%% num -> numero de vectores que genero
%% N_PTS -> longitud de los vectores
Código Matlab
Escuela Superior de Ingenieros 113
%% NB_DI -> Numero de bits de los datos de entrada
%%
%% Salida:
%% matriz-> matriz de entradas aleatorias. El número de columnas se corresponde
%% con el número de vectores, y el número de filas con la longitud de los
%% vectores
function matriz=rnd_vect_in(num,N_PTS,NB_DI)
aux = num*2; % tengo que crear el doble de vectores porque tenemos parte
% real y parte imaginaria.
matriz=zeros(N_PTS,aux); % en matriz es donde vamos a almacenar el
% resultado.
% el numero de columnas corresponde con el
% numero de vectores, mientras que el numero de
% filas con la longitud de los mismos.
for i=1:aux
matriz(:,i)=gen_rnd_data(N_PTS,NB_DI);
end
numOut = RotL (num, nBit, mBit)
%%
%% VALOR DE num ROTADO mBIT A LA IZQUIERDA USANDO nBITS
%%
%% Entradas:
%% num -> numero a rotar
%% nBit -> numero de bits que uso
%% mBit -> numero de bits que roto a la izquierda
%%
%% Salida:
%% numOut -> valor de num rotado mBit a la izquierda usando nBit
function numOut = RotL (num, nBit, mBit)
tmp=2^(nBit-mBit);
lsb=floor(num/tmp);
msb=rem(num,tmp);
numOut=(msb*2^mBit)+lsb;
Código Matlab
Escuela Superior de Ingenieros 114
SnrDB = snr_calc (Yi,Yiq)
%%
%% CALCULA LA SNR DE DOS VECTORES
%%
%% ENTRADAS:
%% Yi -> Vector original
%% Yiq -> Vector cuantizado
%%
%% SALIDA:
%% SnrDB -> valor de la SNR de los 2 vectores de entrada.
function SnrDB = snr_calc (Yi,Yiq)
Yerr=Yi-Yiq;
Psig=var(Yi);
Perr=var(Yerr);
if (Perr==0)
SnrDB=inf;
else
Snr=Psig/Perr;
SnrDB=10*log10(Snr);
End
9.2.- Funciones Radix-2
error_fft_no_cuant(datos_in)
%%
%% CALCULA LA SNR ENTRE MI FFT SIN CUANTIZAR Y LA DE MATLAB
%%
%% Entradas:
%% datos_in -> vector de entrada
%%
function error_fft_no_cuant(datos_in)
Código Matlab
Escuela Superior de Ingenieros 115
aux = size(datos_in);
n_filas = aux(1); % se corresponde con la longitud de los vectores
n_colum = aux(2); % numero de veces que repito la prueba partido por 2
%(hay parte real e imaginaria)
NUM = n_colum/2; % numero de veces que repito la prueba;
long_max = log(n_filas)/log(2); % longitud maxima de los vectores
for exp=5:long_max % vario la longitud
long_sec = 2^exp; % longitud de la secuencia.
for rep=1:NUM % vario el numero de pruebas
vector(:,1) = datos_in(:,(rep*2)-1); % en vector almaceno las columnas
% correspondientes a datos_in
vector(:,2) = datos_in(:,rep*2);
x = vector(1:long_sec,:); % vector con la longitud exacta de la FFT
xfft = x(1:long_sec,1) + i*x(1:long_sec,2); % vector de entrada de la FFT
mat_fft = fft(xfft); % Matlab FFT
fft_sp = my_fft(x); % Mi FFT
mi_fft=(fft_sp(1:long_sec,1)+i*fft_sp(1:long_sec,2)); % Mi FFT en el mismo
% formato que la de matlab
SNRlog(rep,exp)=snr_calc(mat_fft,mi_fft); % Calculamos la SNR en dB
% Almaceno la SNR en dB en una matriz llamada SNRlog
% las filas se corresponde con el Numero de la prueba
% la columna se corresponde con la longitud
end
end
SNR_total=zeros(1,long_max);
hold on;
Código Matlab
Escuela Superior de Ingenieros 116
t=5:long_max;
for j=1:NUM
plot(t,SNRlog(j,5:long_max),'k.');
end
for i=1:long_max
for j=1:NUM
SNR_total(i)=SNRlog(j,i)+SNR_total(i);
end
SNR_total(i)=SNR_total(i)/NUM;
end
for index=5:long_max
fprintf('\n nb_dat= %6d SNR=%16.6f \n',2^index,SNR_total(index))
end
t=5:long_max;
SNR_total=SNR_total(5:long_max); %me quedo con las muestras distintas de cero
plot(t,SNR_total,'ko-')
grid on
xlabel('exponente de la longitud de la secuencia de entrada (2^e^x^p)');
ylabel('SNR (dB)');%
hold off
error_graf (vector,NB_DI,NB_TWE,NB_TRMUL,NB_DO)
%%
%% GRAFICA DE LA SNR RESPECTO A LA LONGITUD DEL VECTOR DE
%% ENTRADA
%%
%% ENTRADAS:
%% vector -> vector de entrada % el vector de entrada tiene que ser
%% % mayor que 512
%% NB_DI -> Numero de bits de la resolucion del vector de entrada
%% NB_TWE -> Numero de bits de la resolucion de los tweddles
%% NB_TRMUL-> Numero de bits de la resolucion de los multiplicadores
%% NB_DO -> Numero de bits de la resolucion de salida
%%
%% FUNCION:
Código Matlab
Escuela Superior de Ingenieros 117
%% Toma el vector de entrada (de longitud > 512 ) y calcula la FFT de las
%% primeras 32 muestras, 64, 128, y asi sucesivamente hasta 512. Calcula
%% la SNR de ellas y las representa graficamente respecto a la longitud
%% del vector de entrada.
%%
function error_graf (vector,NB_DI,NB_TWE,NB_TRMUL,NB_DO)
Q_DI = 2^(NB_DI-1); % Resolucion vector de entrada
Q_TWE = 2^(NB_TWE-1); % Resolucion de los tweedles
Q_TRMUL = 2^(NB_TRMUL-1); % Truncamiento de los multiplicadores (reales)
Q_D0 = 2^(NB_DO-1); % Resolucion de salida
for indice=5:9
long_sec=2^indice; % Longitud de la secuencia de entrada
Xi=vector(1:long_sec,:); % vector de entrada para nuestra FFT
xfft=vector(1:long_sec,1) + i*vector(1:long_sec,2); % vector de entrada de la
% FFT de Matlab
X=fft(xfft)/long_sec; %Matlab FFT
Yorig=fft_trunc(Xi,NB_DI,NB_TWE,NB_TRMUL,NB_DO); % FFT con truncamiento
Y=Yorig(1:long_sec,1)+i*Yorig(1:long_sec,2);
SNRlog(indice)=snr_calc(X,Y); % Calculamos la SNR en dB
% La columna corresponde a la longitud de la secuencia
fprintf('\n longitud= %5d SNR= %4.6f dB \n', long_sec, SNRlog(indice) );
end
t=5:9;
SNR_total=SNRlog(5:9); %me quedo con las muestras distintas de cero%
plot(t,SNR_total,'ko-')
xlabel('Longitud de la secuencia de entrada');
ylabel('SNR (dB)');
Código Matlab
Escuela Superior de Ingenieros 118
error_mem (datos_in,longit,NB_TWE,NB_TRMUL,NB_DO)
%%
%% ERROR DEBIDO A LA CUANTIZACION DE LA MEMORIA INTERNA
%%
%% ENTRADAS:
%% datos_in-> vector de entrada
%% longit -> longitud de la muestra de entrada
%% NB_TWE -> numero de bits de cuantizacion de los tweedle
%% NB_TRMUL-> numero de bits de cuantizacion de la multiplicacion
%% NB_D0 -> numero de bits de cuantizacion de la salida
%%
%% FUNCION.-
%% Le paso la matriz de datos de entrada y solo se queda con la
%% longitud deseada. Calcula la SNR de la FFT variando el numero
%% de bits de la memoria interna.
%%
function error_mem (datos_in,longit,NB_TWE,NB_TRMUL,NB_DO)
aux = size(datos_in);
n_colum = aux(2); % numero de veces que repito la prueba partido por 2
% (hay parte real e imaginaria)
NUM = n_colum/2; % numero de veces que repito la prueba;
long_max = log(longit)/log(2); % longitud maxima de los vectores
for NB_MEM = 4:16 % vario el numero de bits de la memoria interna
long_sec = longit; % longitud de la secuencia.
for rep=1:NUM % vario el numero de pruebas
vector(:,1) = datos_in(:,(rep*2)-1); % en vector almaceno las columnas
% correspondientes a datos_in
vector(:,2) = datos_in(:,rep*2);
x = vector(1:long_sec,:); % vector con la longitud exacta de la FFT
xfft = x(1:long_sec,1) + i*x(1:long_sec,2); % vector de entrada de la FFT
mat_fft = fft(xfft)/long_sec; % Matlab FFT
Código Matlab
Escuela Superior de Ingenieros 119
fft_sp = fft_trunc(x,NB_MEM,NB_TWE,NB_TRMUL,NB_DO); % Mi FFT
mi_fft=(fft_sp(1:long_sec,1)+i*fft_sp(1:long_sec,2)); % Mi FFT en el mismo
% formato que la de matlab
SNRlog(rep,NB_MEM)=snr_calc(mat_fft,mi_fft); % Calculamos la SNR en dB
% Almaceno la SNR en dB en una matriz llamada SNRlog
% las filas se corresponde con el Numero de la prueba
% la columna se corresponde con el numero de bits de TWE
end
end
SNR_total=zeros(1,16); %por que NB_TWE varia de 4:15
hold on;
t=4:16;
for j=1:NUM
plot(t,SNRlog(j,4:16),'k.');
end
for i=1:16
for j=1:NUM
SNR_total(i)=SNRlog(j,i)+SNR_total(i);
end
SNR_total(i)=SNR_total(i)/NUM;
end
fprintf('\n Longitud de la secuencia de entrada = %4d \n',longit)
fprintf('\n Nº bits datos de los tweedle = %4d \n',NB_TWE)
fprintf('\n Nº bits trunc multipli = %4d \n',NB_TRMUL)
fprintf('\n Nº bits trunc datos salida = %4d \n',NB_DO)
for index=4:16
fprintf('\n NB_MEM= %6d SNR=%16.6f \n',index,SNR_total(index))
end
SNR_total=SNR_total(4:16); %me quedo con las muestras distintas de cero%
Código Matlab
Escuela Superior de Ingenieros 120
plot(t,SNR_total,'ko-')
grid on
xlabel('Numero de bits de cuantizacion de la memoria interna');
ylabel('SNR (dB)');%
hold off;
error_mul (datos_in,longit,NB_DI,NB_TWE,NB_DO)
%%
%% ERROR DEBIDO A LA CUANTIZACION DE LA MULTIPLICACION
%%
%% ENTRADAS:
%% datos_in -> vector de entrada
%% longit -> longitud de la muestra de entrada
%% NB_DI -> numero de bits de cuantizacion de la señal de entrada/memoria
%% interna
%% NB_TWE -> numero de bits de cuantizacion de los tweedle
%% NB_D0 -> numero de bits de cuantizacion de la salida
%%
%% FUNCION.-
%% Le paso la matriz de datos de entrada y solo se queda con la
%% longitud deseada.Calcula la SNR de la FFT variando el numero
%% de bits de la multiplicacion
%%
function error_mul (datos_in,longit,NB_DI,NB_TWE,NB_DO)
aux = size(datos_in);
n_colum = aux(2); % numero de veces que repito la prueba partido por 2
% (hay parte real e imaginaria)
NUM = n_colum/2; % numero de veces que repito la prueba;
long_max = log(longit)/log(2); % longitud maxima de los vectores
for NB_TRMUL = 4:16 % vario el numero de bits de la multiplicacion
long_sec = longit; % longitud de la secuencia.
for rep=1:NUM % vario el numero de pruebas
Código Matlab
Escuela Superior de Ingenieros 121
vector(:,1) = datos_in(:,(rep*2)-1); % en vector almaceno las columnas
% correspondientes a datos_in
vector(:,2) = datos_in(:,rep*2);
x = vector(1:long_sec,:); % vector con la longitud exacta de la FFT
xfft = x(1:long_sec,1) + i*x(1:long_sec,2); % vector de entrada de la FFT
mat_fft = fft(xfft)/long_sec; % Matlab FFT
fft_sp = fft_trunc(x,NB_DI,NB_TWE,NB_TRMUL,NB_DO); % Mi FFT
mi_fft=(fft_sp(1:long_sec,1)+i*fft_sp(1:long_sec,2)); % Mi FFT en el mismo
% formato que la de matlab
SNRlog(rep,NB_TRMUL)=snr_calc(mat_fft,mi_fft); % Calculamos la SNR en dB
% Almaceno la SNR en dB en una matriz llamada SNRlog
% las filas se corresponde con el Numero de la prueba
% la columna se corresponde con el numero de bits de TRMUL
end
end
SNR_total=zeros(1,16); %por que NB_TWE varia de 4:15
hold on;
t=4:16;
for j=1:NUM
plot(t,SNRlog(j,4:16),'k.');
end
for i=1:16
for j=1:NUM
SNR_total(i)=SNRlog(j,i)+SNR_total(i);
end
SNR_total(i)=SNR_total(i)/NUM;
end
fprintf('\n Longitud de la secuencia de entrada = %4d \n',longit)
fprintf('\n Nº bits datos de la memoria interna = %4d \n',NB_DI)
Código Matlab
Escuela Superior de Ingenieros 122
fprintf('\n Nº bits datos de los tweedle = %4d \n',NB_TWE)
fprintf('\n Nº bits trunc datos salida = %4d \n',NB_DO)
for index=4:16
fprintf('\n NB_TRMUL = %6d SNR=%16.6f \n',index,SNR_total(index))
end
t=4:16;
SNR_total=SNR_total(4:16); %me quedo con las muestras distintas de cero%
plot(t,SNR_total,'ko-')
grid on
xlabel('Numero de bits de cuantizacion de la multiplicacion');
ylabel('SNR (dB)');%
hold off;
error (datos_in,NB_DI,NB_TWE,NB_TRMUL,NB_DO)
%%
%% ERROR DEBIDO A LA CUANTIZACIÓN TOTAL
%%
%% ENTRADAS:
%% datos_in -> vector de entrada
%% NB_DI -> numero de bits de cuantizacion de la señal de entrada/memoria
%% interna
%% NB_TWE -> numero de bits de cuantizacion de los twiddle
%% NB_TRMUL -> numero de bits de cuantizacion de la multiplicacion
%% NB_D0 -> numero de bits de cuantizacion de la salida
%%
%% FUNCION:
%% Calcula la SNR del vector de entrada. Despues hace la media entre
%% los distintos vectores y nos da el resultado. Solo lo hace para la
%% longitud de los vectores de entrada.
%%
function error (datos_in,NB_DI,NB_TWE,NB_TRMUL,NB_DO)
aux = size(datos_in);
n_filas = aux(1); % se corresponde con la longitud de los vectores
n_colum = aux(2); % numero de veces que repito la prueba partido por 2
Código Matlab
Escuela Superior de Ingenieros 123
% (hay parte real e imaginaria)
NUM = n_colum/2; % numero de veces que repito la prueba;
for rep=1:NUM % vario el numero de pruebas
vector(:,1) = datos_in(:,(rep*2)-1); % en vector almaceno las columnas
% correspondientes a datos_in
vector(:,2) = datos_in(:,rep*2);
x = vector(1:n_filas,:); % vector con la longitud de la FFT
xfft = x(1:n_filas,1) + i*x(1:n_filas,2); % vector de entrada de la FFT
mat_fft = fft(xfft)/n_filas; % Matlab FFT
fft_sp = fft_trunc(x,NB_DI,NB_TWE,NB_TRMUL,NB_DO); % Mi FFT
mi_fft=(fft_sp(1:n_filas,1)+i*fft_sp(1:n_filas,2)); % Mi FFT en el mismo formato
% que la de matlab
SNRlog(rep)=snr_calc(mat_fft,mi_fft); % Calculamos la SNR en dB
% Almaceno la SNR en dB en una matriz llamada SNRlog
% las filas se corresponde con el Numero de la prueba
% la columna se corresponde con la longitud
end
SNR_total=0;
for j=1:NUM
SNR_total=SNRlog(j)+SNR_total;
end
SNR_total=SNR_total/NUM;
fprintf('\n Nº pruebas = %6d \n',NUM)
fprintf('\n Nº bits datos de entrada = %4d \n',NB_DI)
fprintf('\n Nº bits trunc tweddle = %4d \n',NB_TWE)
fprintf('\n Nº bits trunc multipli = %4d \n',NB_TRMUL)
fprintf('\n Nº bits trunc datos salida = %4d \n',NB_DO)
Código Matlab
Escuela Superior de Ingenieros 124
fprintf('\n longitud=%5d SNR=%4.6f \n',n_filas,SNR_total)
error_trunc (datos_in,NB_DI,NB_TWE,NB_TRMUL,NB_DO)
%%
%% ERROR DEBIDO A LA CUANTIZACION TOTAL
%%
%% ENTRADAS:
%% datos_in -> vector de entrada
%% NB_DI -> numero de bits de cuantizacion de la señal de entrada
%% NB_TWE -> numero de bits de cuantizacion de los twiddle
%% NB_TRMUL -> numero de bits de cuantizacion de la multiplicacion
%% NB_D0 -> numero de bits de cuantizacion de la salida
%%
%% FUNCION:
%% Calcula la SNR del vector de entrada. Despues hace la media entre
%% los distintos vectores y nos da el resultado.Lo hace para todas las
%% longitudes del vector de entrada.
%%
function error_trunc (datos_in,NB_DI,NB_TWE,NB_TRMUL,NB_DO)
aux = size(datos_in);
n_filas = aux(1); % se corresponde con la longitud de los vectores
n_colum = aux(2); % numero de veces que repito la prueba partido por 2
% (hay parte real e imaginaria)
NUM = n_colum/2; % numero de veces que repito la prueba;
long_max = log(n_filas)/log(2); % longitud maxima de los vectores
for exp=5:long_max % vario la longitud
long_sec = 2^exp; % longitud de la secuencia.
for rep=1:NUM % vario el numero de pruebas
vector(:,1) = datos_in(:,(rep*2)-1); % en vector almaceno las columnas
% correspondientes a datos_in
vector(:,2) = datos_in(:,rep*2);
x = vector(1:long_sec,:); % vector con la longitud exacta de la FFT
Código Matlab
Escuela Superior de Ingenieros 125
xfft = x(1:long_sec,1) + i*x(1:long_sec,2); % vector de entrada de la FFT
mat_fft = fft(xfft)/long_sec; % Matlab FFT
fft_sp = fft_trunc(x,NB_DI,NB_TWE,NB_TRMUL,NB_DO); % Mi FFT
mi_fft=(fft_sp(1:long_sec,1)+i*fft_sp(1:long_sec,2)); % Mi FFT en el mismo
% formato que la de matlab
SNRlog(rep,exp)=snr_calc(mat_fft,mi_fft); % Calculamos la SNR en dB
% Almaceno la SNR en dB en una matriz llamada SNRlog
% las filas se corresponde con el Numero de la prueba
% la columna se corresponde con la longitud
end
end
SNR_total=zeros(1,long_max);
hold on;
t=5:long_max;
for j=1:NUM
plot(t,SNRlog(j,5:long_max),'k.');
end
for i=1:long_max
for j=1:NUM
SNR_total(i)=SNRlog(j,i)+SNR_total(i);
end
SNR_total(i)=SNR_total(i)/NUM;
end
fprintf('\n Nº bits datos de entrada = %4d \n',NB_DI)
fprintf('\n Nº bits trunc tweddle = %4d \n',NB_TWE)
fprintf('\n Nº bits trunc multipli = %4d \n',NB_TRMUL)
fprintf('\n Nº bits trunc datos salida = %4d \n',NB_DO)
for index=5:long_max
fprintf('\n nb_dat= %6d SNR=%16.6f \n',2^index,SNR_total(index))
Código Matlab
Escuela Superior de Ingenieros 126
end
t=5:long_max;
SNR_total=SNR_total(5:long_max); %me quedo con las muestras distintas de 0
plot(t,SNR_total,'ko-')
grid on
xlabel('exponente de la longitud de la secuencia de entrada (2^e^x^p)');
ylabel('SNR (dB)');%
hold off
error_trunc (datos_in,NB_DI,NB_TWE,NB_TRMUL,NB_DO)
%%
%% ERROR DEBIDO A LA CUANTIZACION DE LOS TWEDDLE
%%
%% ENTRADAS:
%% datos_in -> vector de entrada
%% longit -> longitud de la muestra de entrada
%% NB_DI -> numero de bits de cuantizacion de la señal de entrada
%% NB_TRMUL -> numero de bits de cuantizacion de la multiplicacion
%% NB_D0 -> numero de bits de cuantizacion de la salida
%%
%% FUNCION:
%% Le paso la matriz de datos de entrada y solo se queda con la
%% longitud deseada. Calcula la SNR de la FFT variando el numero
%% de bits de los tweddle
%%
function error_twe (datos_in,longit,NB_DI,NB_TRMUL,NB_DO)
aux = size(datos_in);
n_colum = aux(2); % numero de veces que repito la prueba partido por 2
% (hay parte real e imaginaria)
NUM = n_colum/2; % numero de veces que repito la prueba;
long_max = log(longit)/log(2); % longitud maxima de los vectores
for NB_TWE = 4:16 % vario el numero de bits de los TWE
long_sec = longit; % longitud de la secuencia.
Código Matlab
Escuela Superior de Ingenieros 127
for rep=1:NUM % vario el numero de pruebas
vector(:,1) = datos_in(:,(rep*2)-1); % en vector almaceno las columnas
% correspondientes a datos_in
vector(:,2) = datos_in(:,rep*2);
x = vector(1:long_sec,:); % vector con la longitud exacta de la FFT
xfft = x(1:long_sec,1) + i*x(1:long_sec,2); % vector de entrada de la FFT
mat_fft = fft(xfft)/long_sec; % Matlab FFT
fft_sp = fft_trunc(x,NB_DI,NB_TWE,NB_TRMUL,NB_DO); % Mi FFT
mi_fft=(fft_sp(1:long_sec,1)+i*fft_sp(1:long_sec,2)); % Mi FFT en el mismo
% formato que la de matlab
SNRlog(rep,NB_TWE)=snr_calc(mat_fft,mi_fft); % Calculamos la SNR en dB
% Almaceno la SNR en dB en una matriz llamada SNRlog
% las filas se corresponde con el Numero de la prueba
% la columna se corresponde con el numero de bits de TWE
end
end
SNR_total=zeros(1,16); %por que NB_TWE varia de 4:15
hold on;
t=4:16;
for j=1:NUM
plot(t,SNRlog(j,4:16),'k.');
end
for i=1:16 % Calculo la media de todas las SNR
for j=1:NUM
SNR_total(i)=SNRlog(j,i)+SNR_total(i);
end
SNR_total(i)=SNR_total(i)/NUM;
end
Código Matlab
Escuela Superior de Ingenieros 128
fprintf('\n Longitud de la secuencia de entrada = %4d \n',longit)
fprintf('\n Nº bits datos de entrada = %4d \n',NB_DI)
fprintf('\n Nº bits trunc multipli = %4d \n',NB_TRMUL)
fprintf('\n Nº bits trunc datos salida = %4d \n',NB_DO)
for index=4:16
fprintf('\n NB_TWE= %6d SNR=%16.6f \n',index,SNR_total(index))
end
SNR_total=SNR_total(4:16); %me quedo con las muestras distintas de cero%
plot(t,SNR_total,'ko-')
grid on
xlabel('Numero de bits de cuantizacion de los tweddle');
ylabel('SNR (dB)');%
hold off;
vector = fft_trunc(vector,NB_DI,NB_TWE,NB_TRMUL,NB_DO)
%%
%% FFT RADIX-2. Esquema de COHEN con truncamiento
%%
%% ENTRADAS:
%% vector -> vector de entrada
%% NB_DI -> numero de bits de cuantizacion de la señal de entrada
%% NB_TWE -> numero de bits de cuantizacion de los twiddle
%% NB_TRMUL -> numero de bits de cuantizacion de la multiplicacion
%% NB_D0 -> numero de bits de cuantizacion de la salida
%%
%% SALIDA:
%% vector -> valor de la FFT.
function vector = fft_trunc(vector,NB_DI,NB_TWE,NB_TRMUL,NB_DO)
Leng=length(vector);
numBit=log(Leng)/log(2); % Leng=2^numBit
Q_DI = 2^(NB_DI-1); % Resolucion vector de entrada y de la memoria interna
Q_TWE = 2^(NB_TWE-1); % Resolucion de los tweedles
Código Matlab
Escuela Superior de Ingenieros 129
Q_TRMUL = 2^(NB_TRMUL-1); % Truncamiento de los multiplicadores (reales)
Q_D0 = 2^(NB_DO-1); % Resolucion de salida
%vector(:,:)=vector(:,:)/(Q_DI);
vector=bit_reversed(vector);
for I=0:numBit-1
for J=0:(Leng/2)-1
J0=J*2;
J1=J*2+1;
dirA=rot_l(J0,numBit,I);
dirB=rot_l(J1,numBit,I);
dirTwi= 2^(numBit-1-I)*floor(J*(2^-(numBit-1-I)));
w=exp(-j*2*pi*dirTwi/Leng);
w_rel = round( (Q_TWE-1) * real (w) ); % parte real de w Cuantizada
w_img = round( (Q_TWE-1) * imag (w) ); % parte imaginaria de w Cuantizada
w_rel=w_rel/(Q_TWE);
w_img=w_img/(Q_TWE);
a_rel = vector(dirA+1,1); % parte real del primer dato
a_img = vector(dirA+1,2);
b_rel = vector(dirB+1,1); % parte real del segundo dato
b_img = vector(dirB+1,2);
% multiplico b y w
aux_mul= multiplic(b_rel+i*b_img, w_rel+i*w_img, NB_TRMUL);
bw_rel = real(aux_mul);
bw_img = imag(aux_mul);
%% SATURADOR
bw_rel = c2sat(bw_rel, NB_TRMUL,0);
bw_img = c2sat(bw_img, NB_TRMUL,0);
Código Matlab
Escuela Superior de Ingenieros 130
bw_rel = bw_rel;
bw_img = bw_img;
% sumo y resto los valores de: "a" y "b*w"
a_mas_bw_rel = a_rel + bw_rel;
a_mas_bw_img = a_img + bw_img;
a_men_bw_rel = a_rel - bw_rel;
a_men_bw_img = a_img - bw_img;
% almaceno la suma y la resta en el lugar correspondiente;
vector(dirA+1,1) = a_mas_bw_rel/2; % Se divide por 2 para normalizar
% el resultado.
vector(dirA+1,2) = a_mas_bw_img/2;
vector(dirB+1,1) = a_men_bw_rel/2;
vector(dirB+1,2) = a_men_bw_img/2;
% cuantizo
vector(:,1) = floor( Q_DI *vector(:,1));
idvector1 = find (vector(:,1)==Q_DI);
vector(idvector1,1)= (Q_DI-1);
vector(:,2) = floor( Q_DI *vector(:,2));
idvector2 = find (vector(:,2)==Q_DI);
vector(idvector2,2)= (Q_DI-1);
vector=vector/Q_DI;
end
end
% Cuantizo segun la resolucion de salida
vector(:,1) = floor( Q_D0 *vector(:,1));
idvector1 = find (vector(:,1)==Q_D0);
vector(idvector1,1)= (Q_D0-1);
vector(:,2) = floor( Q_D0 *vector(:,2));
idvector2 = find (vector(:,2)==Q_D0);
vector(idvector2,2)= (Q_D0-1);
Código Matlab
Escuela Superior de Ingenieros 131
vector=vector/Q_D0;
%for i=1:Leng
% fprintf('\n real= %14.16f imag= %14.16f \n', vector(i,1) , vector(i,2));
%end
9.3.- Funciones Radix-4.
error4_graf (vector,NB_MEM,NB_TWE,NB_TRMUL,NB_DO)
%%
%% GRAFICA DE LA SNR RESPECTO A LA LONGITUD DEL VECTOR
%% DE ENTRADA PARA RADIX 4
%%
%% ENTRADAS:
%% vector -> vector de entrada
%% NB_MEM -> Numero de bits de la resolucion del vector de entrada
%% NB_TWE -> Numero de bits de la resolucion de los tweddles
%% NB_TRMUL -> Numero de bits de la resolucion de los multiplicadores
%% NB_DO -> Numero de bits de la resolucion de salida
%%
%% FUNCION:
%% Toma el vector de entrada (de longitud > 16 ) y calcula la FFT de las
%% primeras 16 muestras, 64, 256, y asi sucesivamente hasta 4096. Calcula
%% la SNR de ellas y las representa graficamente respecto a la longitud
%% del vector de entrada.
%%
function error4_graf (vector,NB_MEM,NB_TWE,NB_TRMUL,NB_DO)
Q_MEM = 2^(NB_MEM-1); % Resolucion memoria interna
Q_TWE = 2^(NB_TWE-1); % Resolucion de los tweedles
Q_TRMUL = 2^(NB_TRMUL-1); % Truncamiento de los multiplicadores (reales)
Q_D0 = 2^(NB_DO-1); % Resolucion de salida
for indice=2:6
long_sec=4^indice; % Longitud de la secuencia de entrada
Código Matlab
Escuela Superior de Ingenieros 132
Xi=vector(1:long_sec,:); % vector de entrada para nuestra FFT
xfft=vector(1:long_sec,1) + i*vector(1:long_sec,2); % vector de entrada de la
% FFT de Matlab
X=fft(xfft)/long_sec; %Matlab FFT
Yorig=fft4_trunc(Xi,NB_MEM,NB_TWE,NB_TRMUL,NB_DO); % FFT con
% truncamiento
Y=Yorig(1:long_sec,1)+i*Yorig(1:long_sec,2);
SNRlog(indice)=snr_calc(X,Y); % Calculamos la SNR en dB
% La columna corresponde a la longitud de la secuencia
fprintf('\n longitud= %5d SNR= %4.6f dB \n', long_sec, SNRlog(indice) );
end
t=2:6;
SNR_total=SNRlog(2:6); %me quedo con las muestras distintas de cero%
plot(t,SNR_total,'ko-')
legend('SNR ',1);
xlabel('Longitud de la secuencia de entrada');
ylabel('SNR (dB)');
error4_mem (datos_in,longit,NB_TWE,NB_TRMUL,NB_DO)
%%
%% ERROR DEBIDO A LA CUANTIZACION DE LA MEMORIA INTERNA
%%
%% ENTRADAS:
%% datos_in -> vector de entrada
%% longit -> longitud de la muestra de entrada
%% NB_TWE -> numero de bits de cuantizacion de los tweedle
%% NB_TRMUL -> numero de bits de cuantizacion de la multiplicacion
%% NB_D0 -> numero de bits de cuantizacion de la salida
%%
%% FUNCION:
%% Le paso la matriz de datos de entrada y solo se queda con la
%% longitud deseada. Calcula la SNR de la FFT variando el numero
Código Matlab
Escuela Superior de Ingenieros 133
%% de bits de la memoria interna
%%
function error4_mem (datos_in,longit,NB_TWE,NB_TRMUL,NB_DO)
aux = size(datos_in);
n_colum = aux(2); % numero de veces que repito la prueba partido por 2
% (hay parte real e imaginaria)
NUM = n_colum/2; % numero de veces que repito la prueba;
long_max = log(longit)/log(2); % longitud maxima de los vectores
for NB_MEM = 4:16 % vario el numero de bits de la memoria interna
long_sec = longit; % longitud de la secuencia.
for rep=1:NUM % vario el numero de pruebas
vector(:,1) = datos_in(:,(rep*2)-1); % en vector almaceno las columnas
% correspondientes a datos_in
vector(:,2) = datos_in(:,rep*2);
x = vector(1:long_sec,:); % vector con la longitud exacta de la FFT
xfft = x(1:long_sec,1) + i*x(1:long_sec,2); % vector de entrada de la FFT
mat_fft = fft(xfft)/long_sec; % Matlab FFT
fft_sp = fft4_trunc(x,NB_MEM,NB_TWE,NB_TRMUL,NB_DO); % Mi FFT
mi_fft=(fft_sp(1:long_sec,1)+i*fft_sp(1:long_sec,2)); % Mi FFT en el mismo
% formato que la de matlab
SNRlog(rep,NB_MEM)=snr_calc(mat_fft,mi_fft); % Calculamos la SNR en dB
% Almaceno la SNR en dB en una matriz llamada SNRlog
% las filas se corresponde con el Numero de la prueba
% la columna se corresponde con el numero de bits de TWE
end
end
Código Matlab
Escuela Superior de Ingenieros 134
SNR_total=zeros(1,16); %por que NB_TWE varia de 4:15
hold on;
t=4:16;
for j=1:NUM
plot(t,SNRlog(j,4:16),'k.');
end
for i=1:16
for j=1:NUM
SNR_total(i)=SNRlog(j,i)+SNR_total(i);
end
SNR_total(i)=SNR_total(i)/NUM;
end
fprintf('\n Longitud de la secuencia de entrada = %4d \n',longit)
fprintf('\n Nº bits datos de los tweedle = %4d \n',NB_TWE)
fprintf('\n Nº bits trunc multipli = %4d \n',NB_TRMUL)
fprintf('\n Nº bits trunc datos salida = %4d \n',NB_DO)
for index=4:16
fprintf('\n NB_MEM= %6d SNR=%16.6f \n',index,SNR_total(index))
end
t=4:16;
SNR_total=SNR_total(4:16); %me quedo con las muestras distintas de cero%
plot(t,SNR_total,'ko-')
grid on
xlabel('Numero de bits de cuantizacion de la memoria interna');
ylabel('SNR (dB)');%
hold off
error4_mul (datos_in,longit,NB_MEM,NB_TWE,NB_DO)
%%
%% ERROR DEBIDO A LA CUANTIZACION DE LA MULTIPLICACION
%%
%% ENTRADAS:
Código Matlab
Escuela Superior de Ingenieros 135
%% datos_in -> vector de entrada
%% longit -> longitud de la muestra de entrada
%% NB_MEM -> numero de bits de cuantizacion de la memoria interna
%% NB_TWE -> numero de bits de cuantizacion de los tweedle
%% NB_D0 -> numero de bits de cuantizacion de la salida
%%
%% FUNCION:
%% Le paso la matriz de datos de entrada y solo se queda con la
%% longitud deseada.Calcula la SNR de la FFT variando el numero
%% de bits de la multiplicacion
%%
function error4_mul (datos_in,longit,NB_MEM,NB_TWE,NB_DO)
aux = size(datos_in);
n_colum = aux(2); % numero de veces que repito la prueba partido por 2
% (hay parte real e imaginaria)
NUM = n_colum/2; % numero de veces que repito la prueba;
long_max = log(longit)/log(2); % longitud maxima de los vectores
for NB_TRMUL = 4:16 % vario el numero de bits de la multiplicacion
long_sec = longit; % longitud de la secuencia.
for rep=1:NUM % vario el numero de pruebas
vector(:,1) = datos_in(:,(rep*2)-1); % en vector almaceno las columnas
% correspondientes a datos_in
vector(:,2) = datos_in(:,rep*2);
x = vector(1:long_sec,:); % vector con la longitud exacta de la FFT
xfft = x(1:long_sec,1) + i*x(1:long_sec,2); % vector de entrada de la FFT
mat_fft = fft(xfft)/long_sec; % Matlab FFT
fft_sp = fft4_trunc(x,NB_MEM,NB_TWE,NB_TRMUL,NB_DO); % Mi FFT
mi_fft=(fft_sp(1:long_sec,1)+i*fft_sp(1:long_sec,2)); % Mi FFT en el mismo
% formato que la de matlab
Código Matlab
Escuela Superior de Ingenieros 136
SNRlog(rep,NB_TRMUL)=snr_calc(mat_fft,mi_fft); % Calculamos la SNR en dB
% Almaceno la SNR en dB en una matriz llamada SNRlog
% las filas se corresponde con el Numero de la prueba
% la columna se corresponde con el numero de bits de TRMUL
end
end
SNR_total=zeros(1,16); %por que NB_TWE varia de 4:15
hold on;
t=4:16;
for j=1:NUM
plot(t,SNRlog(j,4:16),'k.');
end
for i=1:16
for j=1:NUM
SNR_total(i)=SNRlog(j,i)+SNR_total(i);
end
SNR_total(i)=SNR_total(i)/NUM;
end
fprintf('\n Longitud de la secuencia de entrada = %4d \n',longit)
fprintf('\n Nº bits datos de la memoria interna = %4d \n',NB_MEM)
fprintf('\n Nº bits datos de los tweedle = %4d \n',NB_TWE)
fprintf('\n Nº bits trunc datos salida = %4d \n',NB_DO)
for index=4:16
fprintf('\n NB_TRMUL = %6d SNR=%16.6f \n',index,SNR_total(index))
end
t=4:16;
SNR_total=SNR_total(4:16); %me quedo con las muestras distintas de cero%
plot(t,SNR_total,'ko-')
grid on
xlabel('Numero de bits de cuantizacion de la multiplicacion');
ylabel('SNR (dB)');%
Código Matlab
Escuela Superior de Ingenieros 137
hold off
error4_no_cuant(datos_in)
%%
%% CALCULA LA SNR ENTRE MI FFT SIN CUANTIZAR Y LA DE MATLAB
%%
%% ENTRADAS:
%% datos_in -> vector de entrada
%%
function error4_no_cuant(datos_in)
aux = size(datos_in);
n_filas = aux(1); % se corresponde con la longitud de los vectores
n_colum = aux(2); % numero de veces que repito la prueba partido por 2
% (hay parte real e imaginaria)
NUM = n_colum/2; % numero de veces que repito la prueba;
long_max = log(n_filas)/log(4); % longitud maxima de los vectores
for exp=2:long_max % vario la longitud
long_sec = 4^exp; % longitud de la secuencia.
for rep=1:NUM % vario el numero de pruebas
vector(:,1) = datos_in(:,(rep*2)-1); % en vector almaceno las columnas
% correspondientes a datos_in
vector(:,2) = datos_in(:,rep*2);
x = vector(1:long_sec,:); % vector con la longitud exacta de la FFT
xfft = x(1:long_sec,1) + i*x(1:long_sec,2); % vector de entrada de la FFT
mat_fft = fft(xfft); % Matlab FFT
fft_sp = myfft_4(x); % Mi FFT
mi_fft=(fft_sp(1:long_sec,1)+i*fft_sp(1:long_sec,2)); % Mi FFT en el mismo
% formato que la de matlab
Código Matlab
Escuela Superior de Ingenieros 138
SNRlog(rep,exp)=snr_calc(mat_fft,mi_fft); % Calculamos la SNR en dB
% Almaceno la SNR en dB en una matriz llamada SNRlog
% las filas se corresponde con el Numero de la prueba
% la columna se corresponde con la longitud
end
end
SNR_total=zeros(1,long_max);
hold on;
t=2:long_max;
for j=1:NUM
plot(t,SNRlog(j,2:long_max),'k.');
end
for i=1:long_max
for j=1:NUM
SNR_total(i)=SNRlog(j,i)+SNR_total(i);
end
SNR_total(i)=SNR_total(i)/NUM;
end
for index=2:long_max
fprintf('\n nb_dat= %6d SNR=%16.6f \n',4^index,SNR_total(index))
end
t=2:long_max;
SNR_total=SNR_total(2:long_max); %me quedo con las muestras distintas de 0
plot(t,SNR_total,'ko-')
grid on
xlabel('exponente de la longitud de la secuencia de entrada (4^e^x^p)');
ylabel('SNR (dB)');%
hold off
Código Matlab
Escuela Superior de Ingenieros 139
error4_sim (datos_in,NB_MEM,NB_TWE,NB_TRMUL,NB_DO)
%%
%% ERROR DEBIDO A LA CUANTIZACION TOTAL
%%
%% ENTRADAS:
%% datos_in -> vector de entrada
%% NB_DI -> numero de bits de cuantizacion de la señal de entrada/memoria
%% interna
%% NB_TWE -> numero de bits de cuantizacion de los twiddle
%% NB_TRMUL -> numero de bits de cuantizacion de la multiplicacion
%% NB_D0 -> numero de bits de cuantizacion de la salida
%%
%% FUNCION:
%% Calcula la SNR del vector de entrada. Despues hace la media entre
%% los distintos vectores y nos da el resultado. Solo lo hace para la
%% longitud del vector de entrada.
%%
function error4_sim (datos_in,NB_MEM,NB_TWE,NB_TRMUL,NB_DO)
aux = size(datos_in);
n_filas = aux(1); % se corresponde con la longitud de los vectores
n_colum = aux(2); % numero de veces que repito la prueba partido por 2
% (hay parte real e imaginaria)
NUM = n_colum/2; % numero de veces que repito la prueba;
for rep=1:NUM % vario el numero de pruebas
vector(:,1) = datos_in(:,(rep*2)-1); % en vector almaceno las columnas
% correspondientes a datos_in
vector(:,2) = datos_in(:,rep*2);
x = vector(1:n_filas,:); % vector con la longitud de la FFT
xfft = x(1:n_filas,1) + i*x(1:n_filas,2); % vector de entrada de la FFT
mat_fft = fft(xfft)/n_filas; % Matlab FFT
fft_sp = fft4_trunc(x,NB_MEM,NB_TWE,NB_TRMUL,NB_DO); % Mi FFT
Código Matlab
Escuela Superior de Ingenieros 140
mi_fft=(fft_sp(1:n_filas,1)+i*fft_sp(1:n_filas,2)); % Mi FFT en el mismo formato que
% la de matlab
SNRlog(rep)=snr_calc(mat_fft,mi_fft); % Calculamos la SNR en dB
% Almaceno la SNR en dB en una matriz llamada SNRlog
% las filas se corresponde con el Numero de la prueba
% la columna se corresponde con la longitud
end
SNR_total=0;
for j=1:NUM
SNR_total=SNRlog(j)+SNR_total;
end
SNR_total=SNR_total/NUM;
fprintf('\n Nº pruebas = %6d \n',NUM)
fprintf('\n Nº bits datos de entrada = %4d \n',NB_MEM)
fprintf('\n Nº bits trunc tweddle = %4d \n',NB_TWE)
fprintf('\n Nº bits trunc multipli = %4d \n',NB_TRMUL)
fprintf('\n Nº bits trunc datos salida = %4d \n',NB_DO)
fprintf('\n longitud=%5d SNR=%4.6f \n',n_filas,SNR_total)
error4_trunc (datos_in,NB_MEM,NB_TWE,NB_TRMUL,NB_DO)
%%
%% ERROR DEBIDO A LA CUANTIZACIÓN TOTAL
%%
%% ENTRADAS:
%% datos_in -> vector de entrada
%% NB_MEM -> numero de bits de cuantizacion de la señal de entrada
%% NB_TWE -> numero de bits de cuantizacion de los twiddle
%% NB_TRMUL -> numero de bits de cuantizacion de la multiplicacion
%% NB_D0 -> numero de bits de cuantizacion de la salida
%%
%% FUNCION:
%% Calcula la SNR del vector de entrada. Despues hace la media entre
Código Matlab
Escuela Superior de Ingenieros 141
%% los distintos vectores y nos da el resultado. Lo hace para la todas las
%% longitudes del vector de entrada.
%%
function error4_trunc (datos_in,NB_MEM,NB_TWE,NB_TRMUL,NB_DO)
aux = size(datos_in);
n_filas = aux(1); % se corresponde con la longitud de los vectores
n_colum = aux(2); % numero de veces que repito la prueba partido por 2
% (hay parte real e imaginaria)
NUM = n_colum/2; % numero de veces que repito la prueba;
long_max = log(n_filas)/log(4); % longitud maxima de los vectores
for exp=2:long_max % vario la longitud
long_sec = 4^exp; % longitud de la secuencia.
for rep=1:NUM % vario el numero de pruebas
vector(:,1) = datos_in(:,(rep*2)-1); % en vector almaceno las columnas
% correspondientes a datos_in
vector(:,2) = datos_in(:,rep*2);
x = vector(1:long_sec,:); % vector con la longitud exacta de la FFT
xfft = x(1:long_sec,1) + i*x(1:long_sec,2); % vector de entrada de la FFT
mat_fft = fft(xfft)/long_sec; % Matlab FFT
fft_sp = fft4_trunc(x,NB_MEM,NB_TWE,NB_TRMUL,NB_DO); % Mi FFT
mi_fft=(fft_sp(1:long_sec,1)+i*fft_sp(1:long_sec,2)); % Mi FFT en el mismo
% formato que la de matlab
SNRlog(rep,exp)=snr_calc(mat_fft,mi_fft); % Calculamos la SNR en dB
% Almaceno la SNR en dB en una matriz llamada SNRlog
% las filas se corresponde con el Numero de la prueba
% la columna se corresponde con la longitud
end
Código Matlab
Escuela Superior de Ingenieros 142
end
SNR_total=zeros(1,long_max);
hold on;
t=2:long_max;
for j=1:NUM
plot(t,SNRlog(j,2:long_max),'k.');
end
for i=1:long_max
for j=1:NUM
SNR_total(i)=SNRlog(j,i)+SNR_total(i);
end
SNR_total(i)=SNR_total(i)/NUM;
end
fprintf('\n Nº bits datos de entrada = %4d \n',NB_MEM)
fprintf('\n Nº bits trunc tweddle = %4d \n',NB_TWE)
fprintf('\n Nº bits trunc multipli = %4d \n',NB_TRMUL)
fprintf('\n Nº bits trunc datos salida = %4d \n',NB_DO)
for index=2:long_max
fprintf('\n nb_dat= %6d SNR=%16.6f \n',2^index,SNR_total(index))
end
t=2:long_max;
SNR_total=SNR_total(2:long_max); %me quedo con las muestras distintas de cero%
plot(t,SNR_total,'ko-')
grid on
xlabel('exponente de la longitud de la secuencia de entrada (4^e^x^p)');
ylabel('SNR (dB)');%
hold off
error4_twe (datos_in,longit,NB_DI,NB_TRMUL,NB_DO)
%%
%% ERROR DEBIDO A LA CUANTIZACIÓN DE LOS TWEDDLE
%%
Código Matlab
Escuela Superior de Ingenieros 143
%% ENTRADAS:
%% datos_in -> vector de entrada
%% longit -> longitud de la muestra de entrada
%% NB_DI -> numero de bits de cuantizacion de la señal de entrada
%% NB_TRMUL -> numero de bits de cuantizacion de la multiplicacion
%% NB_D0 -> numero de bits de cuantizacion de la salida
%%
%% FUNCION:
%% Le paso la matriz de datos de entrada y solo se queda con la
%% longitud deseada.Calcula la SNR de la FFT variando el numero
%% de bits de los tweddle
%%
function error4_twe (datos_in,longit,NB_DI,NB_TRMUL,NB_DO)
aux = size(datos_in);
n_colum = aux(2); % numero de veces que repito la prueba partido por 2 (hay parte
real e imaginaria)
NUM = n_colum/2; % numero de veces que repito la prueba;
long_max = log(longit)/log(2); % longitud maxima de los vectores
for NB_TWE = 4:16 % vario el numero de bits de los TWE
long_sec = longit; % longitud de la secuencia.
for rep=1:NUM % vario el numero de pruebas
vector(:,1) = datos_in(:,(rep*2)-1); % en vector almaceno las columnas
% correspondientes a datos_in
vector(:,2) = datos_in(:,rep*2);
x = vector(1:long_sec,:); % vector con la longitud exacta de la FFT
xfft = x(1:long_sec,1) + i*x(1:long_sec,2); % vector de entrada de la FFT
mat_fft = fft(xfft)/long_sec; % Matlab FFT
fft_sp = fft4_trunc(x,NB_DI,NB_TWE,NB_TRMUL,NB_DO); % Mi FFT
mi_fft=(fft_sp(1:long_sec,1)+i*fft_sp(1:long_sec,2)); % Mi FFT en el mismo
% formato que la de matlab
Código Matlab
Escuela Superior de Ingenieros 144
SNRlog(rep,NB_TWE)=snr_calc(mat_fft,mi_fft); % Calculamos la SNR en dB
% Almaceno la SNR en dB en una matriz llamada SNRlog
% las filas se corresponde con el Numero de la prueba
% la columna se corresponde con el numero de bits de TWE
end
end
SNR_total=zeros(1,16); %por que NB_TWE varia de 4:15
hold on;
t=4:16;
for j=1:NUM
plot(t,SNRlog(j,4:16),'k.');
end
for i=1:16
for j=1:NUM
SNR_total(i)=SNRlog(j,i)+SNR_total(i);
end
SNR_total(i)=SNR_total(i)/NUM;
end
fprintf('\n Longitud de la secuencia de entrada = %4d \n',longit)
fprintf('\n Nº bits datos de entrada = %4d \n',NB_DI)
fprintf('\n Nº bits trunc multipli = %4d \n',NB_TRMUL)
fprintf('\n Nº bits trunc datos salida = %4d \n',NB_DO)
for index=4:16
fprintf('\n NB_TWE= %6d SNR=%16.6f \n',index,SNR_total(index))
end
t=4:16;
SNR_total=SNR_total(4:16); %me quedo con las muestras distintas de cero%
plot(t,SNR_total,'ko-')
grid on
xlabel('Numero de bits de cuantizacion de los tweddle');
Código Matlab
Escuela Superior de Ingenieros 145
ylabel('SNR (dB)');%
hold off;
vector = fft4_trunc(vector,NB_MEM,NB_TWE,NB_TRMUL,NB_DO)
%%
%% FFT RADIX-4 CUANTIZADA. ESQUEMA DE COHEN
%%
%% ENTRADAS:
%% vector -> vector de entrada
%% NB_DI -> numero de bits de cuantizacion de la señal de entrada
%% NB_TWE -> numero de bits de cuantizacion de los twiddle
%% NB_TRMUL -> numero de bits de cuantizacion de la multiplicacion
%% NB_D0 -> numero de bits de cuantizacion de la salida
%%
%% SALIDA:
%% vector -> valor de la FFT.
%%
function vector = fft4_trunc(vector,NB_MEM,NB_TWE,NB_TRMUL,NB_DO)
Leng=length(vector);
Expon = log(Leng)/log(4); % Leng=4^Expon
LongBitRot= log(Leng)/log(2); % Longitud del numero de bits que tengo que rotar
Q_MEM = 2^(NB_MEM-1); % Resolucion de la memoria interna
Q_TWE = 2^(NB_TWE-1); % Resolucion de los tweedles
Q_TRMUL = 2^(NB_TRMUL-1); % Truncamiento de los multiplicadores (reales)
Q_D0 = 2^(NB_DO-1); % Resolucion de salida
vector=bit_reversed(vector);
for I=0:Expon-1
for J=0:(Leng/4)-1
J0=J*2*2;
J1=J*2*2+1;
J2=J*2*2+2;
J3=J*2*2+3;
Código Matlab
Escuela Superior de Ingenieros 146
dirA=rot_l(J0,LongBitRot,2*I);
dirB=rot_l(J1,LongBitRot,2*I);
dirC=rot_l(J2,LongBitRot,2*I);
dirD=rot_l(J3,LongBitRot,2*I);
dirTwi= 2^(2*(Expon-1-I))*floor(J*(2^-(2*(Expon-1-I))));
TwiA= dirTwi*0; % con la direccion base dirTwi obtengo el resto de direcciones
% de los twiddle
TwiB= dirTwi*2; % notese como TwiA siempre es cero.
TwiC= dirTwi*1;
TwiD= dirTwi*3;
wB=exp(-j*2*pi*TwiB/Leng);
wC=exp(-j*2*pi*TwiC/Leng);
wD=exp(-j*2*pi*TwiD/Leng);
wB_r = round( (Q_TWE-1) * real(wB))/Q_TWE;
wB_i = round( (Q_TWE-1) * imag(wB))/Q_TWE;
wC_r = round( (Q_TWE-1) * real(wC))/Q_TWE;
wC_i = round( (Q_TWE-1) * imag(wC))/Q_TWE;
wD_r = round( (Q_TWE-1) * real(wD))/Q_TWE;
wD_i = round( (Q_TWE-1) * imag(wD))/Q_TWE;
a_r = vector(dirA+1,1);
a_i = vector(dirA+1,2);
b_r = vector(dirB+1,1);
b_i = vector(dirB+1,2);
c_r = vector(dirC+1,1);
c_i = vector(dirC+1,2);
d_r = vector(dirD+1,1);
d_i = vector(dirD+1,2);
% hago las multiplicaciones de los datos por los twiddle
awA_r = a_r;
awA_i = a_i;
mulB = multiplic(b_r+i*b_i,wB_r+i*wB_i,NB_TRMUL); % b*w_B
bwB_r = real(mulB);
bwB_i = imag(mulB);
mulC = multiplic(c_r+i*c_i,wC_r+i*wC_i,NB_TRMUL); % c*w_C
cwC_r = real(mulC);
cwC_i = imag(mulC);
Código Matlab
Escuela Superior de Ingenieros 147
mulD = multiplic(d_r+i*d_i,wD_r+i*wD_i,NB_TRMUL); % d*w_D
dwD_r = real(mulD);
dwD_i = imag(mulD);
% Saturador
bwB_r = c2sat(bwB_r,NB_TRMUL,0);
bwB_i = c2sat(bwB_i,NB_TRMUL,0);
cwC_r = c2sat(cwC_r,NB_TRMUL,0);
cwC_i = c2sat(cwC_i,NB_TRMUL,0);
dwD_r = c2sat(dwD_r,NB_TRMUL,0);
dwD_i = c2sat(dwD_i,NB_TRMUL,0);
% computo los valores para almacenarlos
Aux_1r = (awA_r + bwB_r)/2;
Aux_1i = (awA_i + bwB_i)/2;
Aux_2r = (awA_r - bwB_r)/2;
Aux_2i = (awA_i - bwB_i)/2;
Aux_3r = (cwC_r + dwD_r)/2;
Aux_3i = (cwC_i + dwD_i)/2;
Aux_4r = (cwC_r - dwD_r)/2;
Aux_4i = (cwC_i - dwD_i)/2;
NewA_r = Aux_1r + Aux_3r; % real( (a+b)+(c+d) );
NewA_i = Aux_1i + Aux_3i; % imag( (a+b)+(c+d) );
NewB_r = Aux_2r + Aux_4i; % real( (a-b)+(-i)*(c-d) );
NewB_i = Aux_2i - Aux_4r; % imag( (a-b)+(-i)*(c-d) );
NewC_r = Aux_1r - Aux_3r; % real( (a+b)-(c+d) );
NewC_i = Aux_1i - Aux_3i; % imag( (a+b)-(c+d) );
NewD_r = Aux_2r - Aux_4i; % real( (a-b)-(-i)*(c-d) );
NewD_i = Aux_2i + Aux_4r; % imag( (a-b)-(-i)*(c-d) );
% Almaceno los valores en el lugar correspondiente
vector(dirA+1,1) = NewA_r/2;
vector(dirA+1,2) = NewA_i/2;
vector(dirB+1,1) = NewB_r/2;
vector(dirB+1,2) = NewB_i/2;
vector(dirC+1,1) = NewC_r/2;
vector(dirC+1,2) = NewC_i/2;
Código Matlab
Escuela Superior de Ingenieros 148
vector(dirD+1,1) = NewD_r/2;
vector(dirD+1,2) = NewD_i/2;
% cuantizo la memoria interna
vector(:,1) = floor( Q_MEM *vector(:,1));
idvector1 = find (vector(:,1)==Q_MEM);
vector(idvector1,1)= (Q_MEM-1);
vector(:,2) = floor( Q_MEM *vector(:,2));
idvector2 = find (vector(:,2)==Q_MEM);
vector(idvector2,2)= (Q_MEM-1);
vector=vector/Q_MEM;
end
end
% Cuantizo segun la resolucion de salida
vector(:,1) = floor( Q_D0 *vector(:,1));
idvector1 = find (vector(:,1)==Q_D0);
vector(idvector1,1)= (Q_D0-1);
vector(:,2) = floor( Q_D0 *vector(:,2));
idvector2 = find (vector(:,2)==Q_D0);
vector(idvector2,2)= (Q_D0-1);
vector=vector/Q_D0;
%for i=1:Leng
% fprintf('\n real= %14.16f imag= %14.16f \n', vector(i,1) , vector(i,2));
%end