9.- Codigo Matlab
Short Description
lab...
Description
Código Matlab
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) stringOut=bit_reversed(STRING) Leng=length(STRING); N=1;
% siempre la longitude de la cadena es un multiplo de 2^N
Escuela Superior de Ingenieros
108
Código Matlab while 2^N < Leng N=N+1; end stringOut=STRING;
for index=0:(Leng-1) 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 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;
Escuela Superior de Ingenieros
109
Código Matlab Nmodif=length(id); id=find(num 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,N xq=gen_rnd_data(N_PTS,NB_DI) B_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;
Escuela Superior de Ingenieros
110
Código Matlab 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) string=invert(string) Leng=length(string); for index=1:(Leng/2) 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 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 multiplicac ion %% %% SALIDA: %% y -> valor de b*w cuantizado %% function y=multiplic(b,w,NB_TRMU y=multiplic(b,w,NB_TRMUL) L) Q_TRMUL = 2^(NB_TRMU 2 ^(NB_TRMUL-1); L-1);
Escuela Superior de Ingenieros
111
Código Matlab 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)); idbr_wr = find(br_wr==Q_TRMUL); br_wr(idbr_wr) = (Q_TRMUL-1); bi_wi = floor(Q_TRMUL *(b_img*w_img)); idbi_wi = find(bi_wi==Q_TRMUL); bi_wi(idbi_wi) = (Q_TRMUL-1);
% multiplico b_real y w_real
% multiplico b_imag y w_imag
br_wi = floor(Q_TRMUL *(b_rel*w_img)); idbr_wi = find(br_wi==Q_TRMUL); br_wi(idbr_wi) = (Q_TRMUL-1);
% multiplico b_real y w_imag
bi_wr = floor(Q_TRMUL *(b_img*w_rel)); idbi_wr = find(bi_wr==Q_TRMUL); bi_wr(idbi_wr) = (Q_TRMUL-1);
% multiplico b_imag y w_real
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
Escuela Superior de Ingenieros
112
Código Matlab %% 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;
Escuela Superior de Ingenieros
113
Código Matlab 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)
Escuela Superior de Ingenieros
114
Código Matlab 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); mat_fft = fft(xfft);
% Matlab FFT
fft_sp = my_fft(x);
% Mi FFT
% vector de entrada de la 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;
Escuela Superior de Ingenieros
115
Código Matlab 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:
Escuela Superior de Ingenieros
116
Código Matlab %% %% %% %% %%
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)');
Escuela Superior de Ingenieros
117
Código Matlab 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
Escuela Superior de Ingenieros
118
Código Matlab
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 fprintf('\n fprintf('\n fprintf('\n
Longitud de la secuencia de entrada = %4d \n',longit) Nº bits datos de los tweedle = %4d \n',NB_TWE) Nº bits trunc multipli = %4d \n',NB_TRMUL) 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%
Escuela Superior de Ingenieros
119
Código Matlab 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
Escuela Superior de Ingenieros
120
Código Matlab 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)
Escuela Superior de Ingenieros
121
Código Matlab 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
Escuela Superior de Ingenieros
122
Código Matlab % (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 fprintf('\n fprintf('\n fprintf('\n
Nº bits datos de entrada = %4d \n',NB_DI) Nº bits trunc tweddle = %4d \n',NB_TWE) Nº bits trunc multipli = %4d \n',NB_TRMUL) Nº bits trunc datos salida = %4d \n',NB_DO)
Escuela Superior de Ingenieros
123
Código Matlab 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
Escuela Superior de Ingenieros
124
Código Matlab
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))
Escuela Superior de Ingenieros
125
Código Matlab 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.
Escuela Superior de Ingenieros
126
Código Matlab
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
Escuela Superior de Ingenieros
127
Código Matlab
fprintf('\n fprintf('\n fprintf('\n fprintf('\n
Longitud de la secuencia de entrada = %4d \n',longit) Nº bits datos de entrada = %4d \n',NB_DI) Nº bits trunc multipli = %4d \n',NB_TRMUL) 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
Escuela Superior de Ingenieros
128
Código Matlab 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);
Escuela Superior de Ingenieros
129
Código Matlab 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);
Escuela Superior de Ingenieros
130
Código Matlab vector=vector/Q_D0; %for i=1:Leng % fprintf('\n real= %14.16f %end
imag= %14.16f \n', vector(i,1) , vector(i,2));
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 Escuela Superior de Ingenieros
131
Código Matlab
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
Escuela Superior de Ingenieros
132
Código Matlab %% %%
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
Escuela Superior de Ingenieros
133
Código Matlab 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 fprintf('\n fprintf('\n fprintf('\n
Longitud de la secuencia de entrada = %4d \n',longit) Nº bits datos de los tweedle = %4d \n',NB_TWE) Nº bits trunc multipli = %4d \n',NB_TRMUL) 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:
Escuela Superior de Ingenieros
134
Código Matlab %% 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
Escuela Superior de Ingenieros
135
Código 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 fprintf('\n fprintf('\n fprintf('\n
Longitud de la secuencia de entrada = %4d \n',longit) Nº bits datos de la memoria interna = %4d \n',NB_MEM) Nº bits datos de los tweedle = %4d \n',NB_TWE) 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)');%
Escuela Superior de Ingenieros
136
Código Matlab 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); mat_fft = fft(xfft); fft_sp = myfft_4(x);
% vector de entrada de la FFT
% Matlab FFT % 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
Escuela Superior de Ingenieros
137
Código 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=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
Escuela Superior de Ingenieros
138
Código Matlab 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);
Escuela Superior de Ingenieros
% Mi FFT
139
Código Matlab 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 fprintf('\n fprintf('\n fprintf('\n
Nº bits datos de entrada = %4d \n',NB_MEM) Nº bits trunc tweddle = %4d \n',NB_TWE) Nº bits trunc multipli = %4d \n',NB_TRMUL) 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
Escuela Superior de Ingenieros
140
Código Matlab %% %% %%
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
Escuela Superior de Ingenieros
141
Código Matlab 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 %%
Escuela Superior de Ingenieros
142
Código Matlab %% 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
Escuela Superior de Ingenieros
143
Código 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 for j=1:NUM SNR_total(i)=SNRlog(j,i)+SNR_total(i); end SNR_total(i)=SNR_total(i)/NUM; end fprintf('\n fprintf('\n fprintf('\n fprintf('\n
Longitud de la secuencia de entrada = %4d \n',longit) Nº bits datos de entrada = %4d \n',NB_DI) Nº bits trunc multipli = %4d \n',NB_TRMUL) 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');
Escuela Superior de Ingenieros
144
Código Matlab 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;
Escuela Superior de Ingenieros
145
Código Matlab 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);
Escuela Superior de Ingenieros
146
Código Matlab 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;
Escuela Superior de Ingenieros
147
View more...
Comments