APPENDICE
SOFTWARE
//Allocazione della potenza in base alla tecnica water-filling. Sulle //portanti idonee alla trasmissione i bit vengono assegnati uniformemente //(2 bit per ogni sottoportante)
int potenza_waterPouring_bit_uniforme(int Ns,double power_required, double* mod_quad_can,unsigned char* bit_allocated, double*
power_allocated,
unsigned char* cost_vector,int& portanti)
{ int flag_bit_allocation; int useful_subset; int useful_subset_app; int total_bit; int i,indmin; double min; double channel_power_product; double water_level; int* no_subcarrier=alloc_int_vect(Ns); //inizializzazione di vettori
for (i=0; i<(Ns); i++) { no_subcarrier[i]=0; bit_allocated[i]=2; cost_vector[i]=4; } flag_bit_allocation=1; useful_subset_app=Ns;
//ciclo di allocazione potenza waterfilling while (flag_bit_allocation>0)
{
channel_power_product=0;
useful_subset=useful_subset_app;
for (i=0; i<Ns; i++)
if (no_subcarrier[i]==0) channel_power_product+=1.0/mod_quad_can[i]; water_level=((double)(Ns*power_required)/useful_subset)+ ((1.0/useful_subset)* channel_power_product); min=Ns*power_required;
for (i=0; i<Ns; i++)
if (no_subcarrier[i]==0) {
power_allocated[i]=water_level- (1/mod_quad_can[i]);
//calcolo il valore minimo di potenza allocata if (power_allocated[i]<min) { min=power_allocated[i]; indmin=i; } }
//se la minima potenza allocata è negativa escludo la //portante corrispondente dal set di portanti utili, ne //annullo la potenza e ricomincio il ciclo. Altrimenti //il ciclo termina
if(min<0) { no_subcarrier[indmin]=1; useful_subset_app=useful_subset_app-1; flag_bit_allocation++; bit_allocated[indmin]=0; cost_vector[indmin]=0; power_allocated[indmin]=0; } }
//calcolo numero di bit totali trasmessi
total_bit=2*useful_subset; portanti=useful_subset;
free((void*) no_subcarrier);
return total_bit;
//Allocazione di potenza waterfilling con SNR gap
int Water_SNRGap_no_distr1(int Ns,double SNR_required, double Dev, double
power_required,double* mod_quad_can, unsigned char* bit_allocated,
double* power_allocated,unsigned char* cost_vector,int& num_subcarr, double& err_medio) { int flag_bit_allocation; int useful_subset; int useful_subset_app; int total_bit; int i; double channel_power_product; double SNR_gap; double water_level; double min; int indmin; int* no_subcarrier=alloc_int_vect(Ns); double* bit_allocation_metric=alloc_double_vect(Ns); //inizializzo vettori
for (i=0; i<(Ns); i++) { no_subcarrier[i]=0; *(bit_allocated+i)=0; *(cost_vector+i)=0; bit_allocation_metric[i]=0; } flag_bit_allocation=1; useful_subset_app=Ns; SNR_gap=pow(10.0,(SNR_required)/10.0); //inizio ciclo di allocazione risorse
while (flag_bit_allocation>0) {
flag_bit_allocation=0; channel_power_product=0;
useful_subset=useful_subset_app;
for (i=0; i<Ns; i++)
if (no_subcarrier[i]==0) channel_power_product+=1.0/mod_quad_can[i];
water_level=((Ns*power_required)/useful_subset)+(((pow(Dev,2)*SNR_gap)/ useful_subset)*channel_power_product);
min=Ns*power_required;
for (i=0; i<Ns; i++)
{
power_allocated[i]=water_level-((pow(Dev,2)*SNR_gap)/mod_quad_can[i]);
//calcolo il valore minimo di potenza allocata if (power_allocated[i]<min) { min=power_allocated[i]; indmin=i; } }
//se il valore minimo e' negativo escludo la portante corrispondente dal //set di portanti utili e ne annullo la potenza
if(min<0) { no_subcarrier[indmin]=1; useful_subset_app=useful_subset_app-1; flag_bit_allocation=flag_bit_allocation+1; power_allocated[indmin]=0; bit_allocation_metric[indmin]=0; }
//altrimenti calcolo la metrica continua di bit su ogni sottoportante //utile else { min=1; for(i=0;i<Ns;i++) { if(no_subcarrier[i]==0) { bit_allocation_metric[i]=log(1+(power_allocated[i]*mod_quad_can[i]/ (pow(Dev,2)*SNR_gap)))/log(2.0); //calcolo il valore minimo di allocazione di bit if(bit_allocation_metric[i]<min) { min=bit_allocation_metric[i]; indmin=i; } } }
//se il minimo è minore di 1 la portante corrispondente non è idonea //alla trasmissione (sarebbe azzerata in sede di quantizzazione), quindi //la escludo e ricomincio il ciclo di allocazione da capo. Altrimenti il //ciclo termina. if(min<1) { no_subcarrier[indmin]=1; power_allocated[indmin]=0; useful_subset_app=useful_subset_app-1; flag_bit_allocation=flag_bit_allocation+1; bit_allocation_metric[indmin]=0; } } }
total_bit=0;
//se nessuna portante e' idonea alla trasmissione la funzione termina //restituendo 0 bit allocati
if( useful_subset==0 ) { err_medio=0; num_subcarr=0; free((void*) no_subcarrier); free((void*) bit_allocation_metric); return total_bit; } err_medio=0;
//effettuo la quantizzazione dei bit e il calcolo dell'errore di //quantizzazione medio
for (i=0; i<Ns; i++) { if (no_subcarrier[i]==0) { if (bit_allocation_metric[i]>=5.0) bit_allocated[i]=6; else {
if ((bit_allocation_metric[i]>=1.0) && (bit_allocation_metric[i]<3.0)) bit_allocated[i]=2;
if ((bit_allocation_metric[i]>=3.0) && (bit_allocation_metric[i]<5.0)) bit_allocated[i]=4; } total_bit+=bit_allocated[i]; cost_vector[i]=(int)((pow(2.0,bit_allocated[i]))+0.1); err_medio=err_medio+bit_allocation_metric[i]-bit_allocated[i]; } } num_subcarr=useful_subset; err_medio=err_medio/useful_subset; free((void*) no_subcarrier); free((void*) bit_allocation_metric); return total_bit; }
//come no_distr1, ma contestualmente all'operazione di quantizzazione dei //bit avviene un aggiustamento delle potenze. Viene recuperato un margine //di potenza dalle portanti sulle quali la quantizzazione ha significato //una approssimazione per difetto, e tale margine viene redistribuito //equamente fra le altre portanti utili (quelle approssimate per eccesso) int Water_SNRGap_equo1(int Ns,double SNR_required, double Dev, double
power_required,double* mod_quad_can, unsigned char* bit_allocated,
double* power_allocated,unsigned char* cost_vector,int& portanti, double&
err_medio) { int flag_bit_allocation; int useful_subset; int useful_subset_app; int total_bit; int i; double channel_power_product; double SNR_gap; double water_level; double min; int indmin; double margin; int Ndistr; double potenza; double var=pow(Dev,2); int* no_subcarrier=alloc_int_vect(Ns); int* distribuisci=alloc_int_vect(Ns); double* bit_allocation_metric=alloc_double_vect(Ns); double* delta=alloc_double_vect(Ns);
for (i=0; i<(Ns); i++) { no_subcarrier[i]=0; bit_allocation_metric[i]=0; bit_allocated[i]=0; cost_vector[i]=0; delta[i]=0; distribuisci[i]=0; } flag_bit_allocation=1; useful_subset_app=Ns; SNR_gap=pow(10.0,(SNR_required)/10.0); //ciclo di allocazione while (flag_bit_allocation>0) { flag_bit_allocation=0; channel_power_product=0;
useful_subset=useful_subset_app;
for (i=0; i<Ns; i++)
if (no_subcarrier[i]==0) channel_power_product+=1.0/mod_quad_can[i];
water_level=((Ns*power_required)/useful_subset)+(((pow(Dev,2)*SNR_gap)/ useful_subset)*channel_power_product);
min=Ns*power_required;
for (i=0; i<Ns; i++)
if (no_subcarrier[i]==0) { power_allocated[i]=water_level-((pow(Dev,2)*SNR_gap)/mod_quad_can[i]); if (power_allocated[i]<min) { min=power_allocated[i]; indmin=i; } } if(min<0) { no_subcarrier[indmin]=1; useful_subset_app=useful_subset_app-1; flag_bit_allocation=flag_bit_allocation+1; power_allocated[indmin]=0; bit_allocation_metric[indmin]=0; } else { min=1; for(i=0;i<Ns;i++) { if(no_subcarrier[i]==0) { bit_allocation_metric[i]=log(1+(power_allocated[i]*mod_quad_can[i]/ (pow(Dev,2)*SNR_gap)))/log(2.0); if(bit_allocation_metric[i]<min) { min=bit_allocation_metric[i]; indmin=i; } } } if(min<1)
{ no_subcarrier[indmin]=1; power_allocated[indmin]=0; useful_subset_app=useful_subset_app-1; flag_bit_allocation=flag_bit_allocation+1; bit_allocation_metric[indmin]=0; } } }
//fine ciclo di allocazione
total_bit=0; if( useful_subset==0 ) { err_medio=0; portanti=0; free((void*) no_subcarrier); free((void*) bit_allocation_metric); return total_bit; } margin=0; Ndistr=0;
//quantizzazione dei bit e recupero del margine for(i=0;i<Ns;i++)
{
if( (bit_allocation_metric[i]>=1)&&(bit_allocation_metric[i]<3) ) {
//in caso di quantizzazione per eccesso recupero margine di potenza if( bit_allocation_metric[i]>2 )
{
potenza=(3*var*SNR_gap)/mod_quad_can[i];//calcolo il //livello di potenza adeguato margin=margin+power_allocated[i]-potenza;//recupero //margine power_allocated[i]=potenza; } else {
// etichetto le portanti idonee a ricevere una aliquota di potenza //redistribuita
distribuisci[i]=1; Ndistr=Ndistr+1; }
//calcolo quantità di potenza in grado di fare aumentare la complessità //della modulazione
delta[i]=(15*var*SNR_gap)/mod_quad_can[i]- power_allocated[i]; //assegno i bit quantizzati
bit_allocated[i]=2; cost_vector[i]=4;
total_bit=total_bit+static_cast<int>(bit_allocated[i]); } if( (bit_allocation_metric[i]>=3)&&(bit_allocation_metric[i]<5) ) { if( bit_allocation_metric[i]>4 ) { potenza=(15*var*SNR_gap)/mod_quad_can[i]; margin=margin+power_allocated[i]-potenza; power_allocated[i]=potenza; } else { distribuisci[i]=1; Ndistr=Ndistr+1; } delta[i]=(63*var*SNR_gap)/mod_quad_can[i]-power_allocated[i]; bit_allocated[i]=4; cost_vector[i]=16; total_bit=total_bit+static_cast<int>(bit_allocated[i]); } if( bit_allocation_metric[i]>=5 ) {
if( bit_allocation_metric[i]>6 )//recupero margine di //potenza { potenza=(63*var*SNR_gap)/mod_quad_can[i]; margin=margin+power_allocated[i]-potenza; power_allocated[i]=potenza; } else { distribuisci[i]=1; Ndistr=Ndistr+1; } bit_allocated[i]=6; cost_vector[i]=64; total_bit=total_bit+static_cast<int>(bit_allocated[i]); } }
//fine quantizzazione di bit
//calcolo l'aliquota di potenza da assegnare ad ogni portante dividendo //equamente il margine recuperato
if(Ndistr!=0) margin=margin/Ndistr;
else {
//se nessuna portante e' stata approssimata per eccesso il margine //recuperato verrà ridistribuito equamente fra tutte le sottoportanti //utili
margin=margin/useful_subset; for(i=0;i<Ns;i++)
if(no_subcarrier[i]==0)distribuisci[i]=1 ; }
//distribuisco uniformemente il margine di potenza fra le portanti in cui //i bit erano stati quantizzati approssimando per eccesso
for(i=0;i<Ns;i++) {
if( distribuisci[i]==1 ) {
power_allocated[i]=power_allocated[i]+ margin;
//valuto se il margine aggiuntivo è tale da provocare un aumento di bit if( (margin>delta[i])&&(delta[i]!=0) ) { bit_allocated[i]=bit_allocated[i]+2; total_bit=total_bit+2; cost_vector[i]=static_cast<unsigned char>( pow(2,bit_allocated[i])); } } }
//calcolo errore di quantizzazione medio
err_medio=0;
for(i=0;i<Ns;i++)
if(no_subcarrier[i]==0) {
//ricalcolo la metrica di bit alla luce della nuova allocazione di //potenza seguita alla redistribuzione
bit_allocation_metric[i]=log(1+(power_allocated[i]*mod_quad_can[i]/ (pow(Dev,2)*SNR_gap)))/log(2.0); err_medio=err_medio+bit_allocation_metric[i]-bit_allocated[i]; } err_medio=err_medio/useful_subset; portanti=useful_subset; free((void*) no_subcarrier); free((void*) bit_allocation_metric); free((void*) distribuisci); free((void*) delta); return total_bit; }
//funzione che calcola allocazione bit-potenza con tecnica waterfilling //SNR gap, esclude le portanti con allocazione negativa una per volta, //contestualmente alla quantizzazione dei bit recupera un margine di //potenza e lo redistribuisce equamente fra le portanti che avevano //subito un arrotondamento dei bit per eccesso in sede si quantizzazione int Water_SNRGap_equo3(int Ns,double SNR_required, double Dev, double
power_required,double* mod_quad_can, unsigned char* bit_allocated,
double* power_allocated,unsigned char* cost_vector,int& portanti, double&
err_medio) { int flag_bit_allocation; int useful_subset; int useful_subset_app; int total_bit; int i; double channel_power_product; double SNR_gap; double water_level; double min; int indmin; double margin; int Ndistr; double potenza; double var=pow(Dev,2); int* no_subcarrier=alloc_int_vect(Ns); int* distribuisci=alloc_int_vect(Ns); double* bit_allocation_metric=alloc_double_vect(Ns); double* delta=alloc_double_vect(Ns);
for (i=0; i<(Ns); i++) { no_subcarrier[i]=0; bit_allocation_metric[i]=0; bit_allocated[i]=0; cost_vector[i]=0; delta[i]=0; distribuisci[i]=0; } flag_bit_allocation=1; useful_subset_app=Ns; SNR_gap=pow(10.0,(SNR_required)/10.0); //ciclo di allocazione while (flag_bit_allocation>0) { flag_bit_allocation=0; channel_power_product=0; useful_subset=useful_subset_app;
for (i=0; i<Ns; i++) if (no_subcarrier[i]==0) channel_power_product+=1.0/mod_quad_can[i]; water_level=((Ns*power_required)/useful_subset)+(((pow(Dev,2)*SNR_gap)/ useful_subset)*channel_power_product); min=Ns*power_required;
for (i=0; i<Ns; i++)
if (no_subcarrier[i]==0) { power_allocated[i]=water_level-((pow(Dev,2)*SNR_gap)/mod_quad_can[i]); if (power_allocated[i]<min) { min=power_allocated[i]; indmin=i; } } if(min<0) { no_subcarrier[indmin]=1; useful_subset_app=useful_subset_app-1; flag_bit_allocation=flag_bit_allocation+1; power_allocated[indmin]=0; } else { for(i=0;i<Ns;i++) if(no_subcarrier[i]==0) bit_allocation_metric[i]=log(1+(power_allocated[i]*mod_quad_can[i]/ (pow(Dev,2)*SNR_gap)))/log(2.0); } }
//fine ciclo di allocazione
total_bit=0; if( useful_subset==0 ) { err_medio=0; portanti=0; free((void*) no_subcarrier); free((void*) bit_allocation_metric); free((void*) distribuisci); free((void*) delta); return total_bit; }
margin=0; Ndistr=0;
//quantizzazione dei bit e recupero del margine for(i=0;i<Ns;i++)
{
if( (bit_allocation_metric[i]>0)&&(bit_allocation_metric[i]<1) )//recupero un margine di potenza
{ margin=margin+power_allocated[i]; power_allocated[i]=0; useful_subset=useful_subset-1; no_subcarrier[i]=1; } if( (bit_allocation_metric[i]>=1)&&(bit_allocation_metric[i]<3) ) { if( (bit_allocation_metric[i]>0)&&(bit_allocation_metric[i]<1) )
//recupero un margine di potenza { margin=margin+power_allocated[i]; power_allocated[i]=0; useful_subset=useful_subset-1; no_subcarrier[i]=1; }
//in caso di quantizzazione per eccesso recupero margine di potenza if( bit_allocation_metric[i]>2 )
{
potenza=(3*var*SNR_gap)/mod_quad_can[i];//calcolo il //livello di potenza adeguato
margin=margin+power_allocated[i]-potenza;//recupero //margine power_allocated[i]=potenza; } else {
// etichetto le portanti idonee a ricevere una aliquota di // potenza redistribuita
distribuisci[i]=1; Ndistr=Ndistr+1; }
//calcolo quantità di potenza in grado di fare aumentare la // complessità della modulazione
delta[i]=(15*var*SNR_gap)/mod_quad_can[i]- power_allocated[i]; //assegno i bit quantizzati bit_allocated[i]=2; cost_vector[i]=4; total_bit=total_bit+static_cast<int>(bit_allocated[i]); } if( (bit_allocation_metric[i]>=3)&&(bit_allocation_metric[i]<5) ) { if( bit_allocation_metric[i]>4 ) { potenza=(15*var*SNR_gap)/mod_quad_can[i]; margin=margin+power_allocated[i]-potenza;
power_allocated[i]=potenza; } else { distribuisci[i]=1; Ndistr=Ndistr+1; } delta[i]=(63*var*SNR_gap)/mod_quad_can[i]- power_allocated[i]; bit_allocated[i]=4; cost_vector[i]=16; total_bit=total_bit+static_cast<int>(bit_allocated[i]); } if( bit_allocation_metric[i]>=5 ) {
if( bit_allocation_metric[i]>6 )//recupero margine di //potenza { potenza=(63*var*SNR_gap)/mod_quad_can[i]; margin=margin+power_allocated[i]-potenza; power_allocated[i]=potenza; } else { distribuisci[i]=1; Ndistr=Ndistr+1; } bit_allocated[i]=6; cost_vector[i]=64; total_bit=total_bit+static_cast<int>(bit_allocated[i]); } }
//fine quantizzazione di bit
if( useful_subset==0 ) { err_medio=0; portanti=0; total_bit=0; free((void*) no_subcarrier); free((void*) bit_allocation_metric); free((void*) distribuisci); free((void*) delta); return total_bit; }
//calcolo l'aliquota di potenza da assegnare ad ogni portante dividendo //equamente il margine recuperato
if(Ndistr!=0) margin=margin/Ndistr;
else {
//se nessuna portante e' stata approssimata per eccesso il margine //recuperato verrà ridistribuito equamente fra tutte le sottoportanti //utili
margin=margin/useful_subset; for(i=0;i<Ns;i++)
if(no_subcarrier[i]==0)distribuisci[i]=1 ; }
//distribuisco uniformemente il margine di potenza fra le portanti in cui //i bit erano stati quantizzati approssimando per eccesso
for(i=0;i<Ns;i++) {
if( distribuisci[i]==1 ) {
power_allocated[i]=power_allocated[i]+ margin;
//valuto se il margine aggiuntivo è tale da provocare un aumento di bit if( (margin>delta[i])&&(delta[i]!=0) ) { bit_allocated[i]=bit_allocated[i]+2; total_bit=total_bit+2; cost_vector[i]=static_cast<unsigned char>( pow(2,bit_allocated[i])); } } }
//calcolo errore di quantizzazione medio
err_medio=0;
for(i=0;i<Ns;i++)
if(no_subcarrier[i]==0) {
//ricalcolo la metrica di bit alla luce della nuova allocazione //di potenza seguita alla redistribuzione
bit_allocation_metric[i]=log(1+(power_allocated[i]*mod_quad_can[i]/ (pow(Dev,2)*SNR_gap)))/log(2.0); err_medio=err_medio+bit_allocation_metric[i]-bit_allocated[i]; } err_medio=err_medio/useful_subset; portanti=useful_subset; free((void*) no_subcarrier); free((void*) bit_allocation_metric); free((void*) distribuisci); free((void*) delta); return total_bit; }
//funzione che calcola allocazione bit-potenza con tecnica waterfilling //SNR gap, esclude le portanti con allocazione negativa una per volta, //recupera margine e lo redistribuisce realizzando approssimazioni per //eccesso solo se e' disponibile la potenza opportuna
int Water_SNRGap_safe_quant(int Ns,double SNR_required, double Dev,
double power_required,double* mod_quad_can, unsigned char* bit_allocated, double* power_allocated,unsigned char* cost_vector,int& portanti,double&
err_medio) { int flag_bit_allocation; int useful_subset; int useful_subset_app; int total_bit; int i; double channel_power_product; double SNR_gap; double water_level; double min; double max; int indmin; int indmax; double margin; int Ndistr; double potenza; double deficit; double var=pow(Dev,2); int* no_subcarrier=alloc_int_vect(Ns); int* distribuisci=alloc_int_vect(Ns); double* bit_allocation_metric=alloc_double_vect(Ns); double* delta=alloc_double_vect(Ns);
for (i=0; i<(Ns); i++) { no_subcarrier[i]=0; bit_allocation_metric[i]=0; bit_allocated[i]=0; cost_vector[i]=0; delta[i]=0; distribuisci[i]=0; } flag_bit_allocation=1; useful_subset_app=Ns; SNR_gap=pow(10.0,(SNR_required)/10.0); //inizio ciclo di allocazione
while (flag_bit_allocation>0) {
flag_bit_allocation=0; channel_power_product=0;
useful_subset=useful_subset_app;
for (i=0; i<Ns; i++)
if (no_subcarrier[i]==0) channel_power_product+=1.0/mod_quad_can[i];
water_level=((Ns*power_required)/useful_subset)+(((pow(Dev,2)*SNR_gap)/ useful_subset)*channel_power_product);
min=Ns*power_required;
for (i=0; i<Ns; i++)
if (no_subcarrier[i]==0) { power_allocated[i]=water_level-((pow(Dev,2)*SNR_gap)/mod_quad_can[i]); if (power_allocated[i]<min) { min=power_allocated[i]; indmin=i; } } if(min<0) { no_subcarrier[indmin]=1; useful_subset_app=useful_subset_app-1; flag_bit_allocation=flag_bit_allocation+1; power_allocated[indmin]=0; bit_allocation_metric[indmin]=0; } else { min=1; for(i=0;i<Ns;i++) { if(no_subcarrier[i]==0) { bit_allocation_metric[i]=log(1+(power_allocated[i]*mod_quad_can[i]/ pow(Dev,2)*SNR_gap)))/log(2.0); if(bit_allocation_metric[i]<min) { min=bit_allocation_metric[i]; indmin=i;
} } } if(min<1) { no_subcarrier[indmin]=1; power_allocated[indmin]=0; useful_subset_app=useful_subset_app-1; flag_bit_allocation=flag_bit_allocation+1; bit_allocation_metric[indmin]=0; } } }
//fine ciclo di allocazione
total_bit=0; if( useful_subset==0 ) { err_medio=0; portanti=0; free((void*) no_subcarrier); free((void*) bit_allocation_metric); free((void*) distribuisci); free((void*) delta); return total_bit; } margin=0; Ndistr=0;
//quantizzazione dei bit e recupero del margine for(i=0;i<Ns;i++)
{
if( (bit_allocation_metric[i]>=1)&&(bit_allocation_metric[i]<3) ) {
//se la quantizzazione è una approssimazione per //difetto...
if( bit_allocation_metric[i]>2 )//recupero margine di //potenza
{
potenza=(3*var*SNR_gap)/mod_quad_can[i];//calcolo il //livello adeguato di potenza margin=margin+power_allocated[i]-potenza;//recupero //margine power_allocated[i]=potenza;//assegno potenza bit_allocated[i]=2;//assegno bit
cost_vector[i]=4;
total_bit=total_bit+static_cast<int>(bit_allocated[i]); }
//se invece la quantizzazione è una approssimazione per //eccesso...
else {
//calcolo la potenza mancante per raggiungere il livello adeguato alla //trasmissione di questo numero di bit
delta[i]=(3*var*SNR_gap)/mod_quad_can[i]- power_allocated[i];
//etichetto la portante come idonea a ricevere una aliquota di potenza //ridistribuita. Notare che non effettuo, per il momento, alcuna
//allocazione di bit.Valuterò in seguito se l'approssimazione per eccesso //e' possibile o meno, in base alla disponibilità di potenza
distribuisci[i]=1; Ndistr=Ndistr+1; } } if( (bit_allocation_metric[i]>=3)&&(bit_allocation_metric[i]<5) ) {
if( bit_allocation_metric[i]>4 )//recupero margine di //potenza { potenza=(15*var*SNR_gap)/mod_quad_can[i]; margin=margin+power_allocated[i]-potenza; power_allocated[i]=potenza; bit_allocated[i]=4; cost_vector[i]=16; total_bit=total_bit+static_cast<int>(bit_allocated[i]); } else { delta[i]=(15*var*SNR_gap)/mod_quad_can[i]- power_allocated[i]; distribuisci[i]=1; Ndistr=Ndistr+1; } } if( bit_allocation_metric[i]>=5 ) {
if( bit_allocation_metric[i]>6 )//recupero margine di //potenza { potenza=(63*var*SNR_gap)/mod_quad_can[i]; margin=margin+power_allocated[i]-potenza; power_allocated[i]=potenza; bit_allocated[i]=6; cost_vector[i]=64; total_bit=total_bit+static_cast<int>(bit_allocated[i]); } else { delta[i]=(63*var*SNR_gap)/mod_quad_can[i]- power_allocated[i];
distribuisci[i]=1; Ndistr=Ndistr+1; } }
}
//fine quantizzazione di bit
//se esiste qualche portante che necessita di approssimazione per eccesso if(Ndistr!=0)
{
deficit=0;
//calcolo la potenza totale mancante for(i=0;i<Ns;i++)
if(distribuisci[i]==1)
deficit=deficit+delta[i];
//se il margine totale da redistribuire non è in grado di colmare //il deficit entro in questo ciclo che serve per recuperare //ulteriore margine
while( (margin<deficit)&&(Ndistr>1) ) {
min=Ns*power_required; max=0;
//individuo la portante per la quale la potenza mancante rispetto //al livello adeguato alla trasmissione è maggiore
for(i=0;i<Ns;i++) if( distribuisci[i]==1 ) { if(delta[i]>max) { max=delta[i]; indmax=i; } }
//tale portante subisce una approssimazione dei bit per difetto anzichè //per eccesso e da essa recupero margine di potenza bit_allocated[indmax]=static_cast<unsigned char>(
floor( bit_allocation_metric[indmax] )-1);
//se l'approssimazione per difetto restituisce 0, tale portante esce dal //set di portanti utili
if(bit_allocated[indmax]==0) {
useful_subset=useful_subset-1; no_subcarrier[indmax]=1;
}
//aggiorno bit totali allocati
total_bit=total_bit+static_cast<int>(bit_allocated[indmax]);
cost_vector[indmax]=static_cast<unsigned char>( pow(2,bit_allocated[indmax]));
//calcolo il livello adeguato di potenza
potenza=((static_cast<double>(
pow(2,bit_allocated[indmax]))-1)*var*SNR_gap)/mod_quad_can[indmax];
margin=margin+power_allocated[indmax]-potenza;//recupero //margine power_allocated[indmax]=potenza;//assegno la potenza deficit=deficit-delta[indmax];//decremento il deficit distribuisci[indmax]=0;//escludo la portante dal set di //canali idonei alla redistribuzione //del margine
Ndistr=Ndistr-1; }
//fine ciclo while
//se sono riuscito a recuperare margine sufficiente a colmare tutto il //deficit
if(margin>=deficit)
{
//effettuo tranquillamente le approssimazioni per eccesso, assegnado ad //ogni portante l'aliquota di potenza necessaria a raggiungere il livello //adeguato alla costellazione utilizzata. Di volta in volta decremento il //margine for(i=0;i<Ns;i++) if(distribuisci[i]==1) { bit_allocated[i]=static_cast<unsigned char>( ceil( bit_allocation_metric[i])); total_bit=total_bit+static_cast<int>(bit_allocated[i]); cost_vector[i]=static_cast<unsigned char>( pow(2,bit_allocated[i])); power_allocated[i]= power_allocated[i]+delta[i]; margin=margin-delta[i]; Ndistr=Ndistr-1; distribuisci[i]=0; }
//se alla fine avanza un po' di margine lo redistribuisco equamente //fra tuttem le sottoportanti utili
if(margin>0) { margin=margin/useful_subset; for(i=0;i<Ns;i++) if(no_subcarrier[i]==0) power_allocated[i]=power_allocated[i]+margin; } }
//se sono uscito dal ciclo while di recupero margine senza essere //riuscito a colmare il deficit
else {
//notare che sara' rimasta una sola portante etichettata come idonea a //ricevere potenza redistribuita, in particolare è la portante con il //valore minimo di potenza mancante rispetto al livello ottimale
for(i=0;i<Ns;i++)
if(distribuisci[i]==1) indmin=i;
//assegno tutto il margine recuperato a questa portante, ma effettuo //ugualmente una approssimazione dei bit per difetto anzichè per
//eccesso, perche' il margine recuperato non è sufficiente power_allocated[indmin]= power_allocated[indmin]+margin; margin=0; bit_allocated[indmin]=static_cast<unsigned char>( floor( bit_allocation_metric[indmin] )-1); if(bit_allocated[indmin]==0) { useful_subset=useful_subset-1; no_subcarrier[indmin]=1; } total_bit=total_bit+static_cast<int>(bit_allocated[indmin]); cost_vector[indmin]=static_cast<unsigned char>( pow(2,bit_allocated[indmin])); } }
//se nessuna portante necessita di approssimazione per eccesso divido
//equamente il margine di potenza recuperato fra tutte le portanti utili else { margin=margin/useful_subset; for(i=0;i<Ns;i++) { if(no_subcarrier[i]==0)power_allocated[i]=power_allocated[i]+margin; } } err_medio=0;
//ricalcolo la metrica continua di bit per tutte le portanti utili e //calcolo errore di quantizzazione medio
for(i=0;i<Ns;i++) if(no_subcarrier[i]==0) { bit_allocation_metric[i]=log(1+(power_allocated[i]*mod_quad_can[i]/ (pow(Dev,2)*SNR_gap)))/log(2.0); err_medio=err_medio+bit_allocation_metric[i]-bit_allocated[i]; } if(useful_subset==0) err_medio=0; else err_medio=err_medio/useful_subset; portanti=useful_subset; free((void*) no_subcarrier); free((void*) bit_allocation_metric); free((void*) distribuisci); free((void*) delta); return total_bit; }