• Non ci sono risultati.

Appendice software

N/A
N/A
Protected

Academic year: 2021

Condividi "Appendice software"

Copied!
28
0
0

Testo completo

(1)

A.1 Definizioni

DEFINIZIONI RELATIVE A UTENTI E SOTTOPORTANTI

simulInfo.userNumber =16; simulInfo.subCarNumber = 64;

DEFINIZIONI RELATIVE AL CANALE

simulInfo.simNum = 1;

Tipo di canale utilizzato:

0. Canale incorrelato, utenti tutti alla stessa distanza, spatial non conta; 1. Canale ETSI BRAN (non implementato);

2. Canale con Exponential Power Delay Profile e utenti posizionati a caso nella cella 3. Canale WiLan

(2)

Parametro che imposta lo stato del generatore casuale di segnali (0 deterministico, 1 casuale)

simulInfo.randSeedChannel = 1;

Frequenza della portante e banda complessiva del segnale in Hz

simulInfo.carFreq = 2e9; simulInfo.sigBandWidth = 20e6;

Variabile che determina la funzione di posizione spaziale degli utenti quando sono generati (0: no PL = 1 per tutti; 1: sì)

simulInfo.spatial = 1; simulInfo.radius = 500;

simulInfo.pathLossExponent = 4; simulInfo.rmsDelaySpread = 5e-7;

TIPO DI CALCOLO DI PRESTAZIONI CHE VOGLIO EFFETTUARE 1. Calcolo BER

2. Calcolo potenza in funzione del rate 3. Calcolo pdf

simulInfo.prest=1;

(3)

A.2 Algoritmo di allocazione dinamica delle risorse

PROGRAMMA PRINCIPALE. GENERA IL CANALE ED ALLOCA AD OGNI UTENTE IL NUMERO DI SOTTOPORTANTI RICHESTO. CALCOLA POI LE PRESTAZIONI

clear all load definiz simNumber=100; prest=simulInfo.prest; userNumber=simulInfo.userNumber; subCarNumber=simulInfo.subCarNumber; switch prest

case 1 CALCOLO IL BER DATO UN RATE DI 2 MHz/s rate=2*10^6; for sim=1:simNumber simulInfo = canale(simulInfo); simulInfo = BABS(simulInfo,rate); matrix=simulInfo.subCarMatrix; assegnazione = allocazione(simulInfo,matrix); assegnOttima=linProgImpl(simulInfo,matrix); assegnNoAll=noAll(simulInfo,matrix); vect=sum(assegnazione); vectOtt=sum(assegnOttima); vectNoAll=sum(assegnNoAll); muta = 0; for SNR = 0:2:12 SNRLin = 10^(SNR/10);

(4)

muta = muta+1; BER(sim,muta)=calcoloBER(vect,SNRLin); BEROtt(sim,muta)=calcoloBER(vectOtt,SNRLin); BERNoAll(sim,muta)=calcoloBER(vectNoAll,SNRLin); end sim end mediaBER=sum(BER)/simNumber; mediaBEROtt=sum(BEROtt)/simNumber; mediaBERNoAll=sum(BERNoAll)/simNumber; semilogy(0:2:12,mediaBER,'g') hold on semilogy(0:2:12,mediaBEROtt) hold on semilogy(0:2:12,mediaBERNoAll,'r')

case 2 CALCOLO LA POTENZA IN FUNZIONE DEL RATE for sim=1:simNumber simulInfo = canale(simulInfo); muta=0; sim for rate=(0.5:0.5:4)*10^6 simulInfo = BABS(simulInfo,rate); matrix=simulInfo.costMatrix; assegnazione = allocazione(simulInfo,matrix); assegnOttima=linProgImpl(simulInfo,matrix);

(5)

muta=muta+1; Potenza(sim,muta)=(sum(sum(assegnazione)))*simulInfo.noisePower; PotenzaOtt(sim,muta)=(sum(sum(assegnOttima)))*simulInfo.noisePower; PotenzaNoAll(sim,muta)=(sum(sum(assegnNoAll)))*simulInfo.noisePower; end end mediaPot=sum(Potenza)/simNumber; mediaPotOtt=sum(PotenzaOtt)/simNumber; mediaPotNoAll=sum(PotenzaNoAll)/simNumber; semilogy((0.5:0.5:4),mediaPot) hold on semilogy((0.5:0.5:4),mediaPotOtt,'g') hold on semilogy((0.5:0.5:4),mediaPotNoAll,'r')

case 3 CALCOLO PDF: ISTOGRAMMA CON TUTTI I VALORI DELL'ASSEGNAZIONE PER

TUTTE LE SIMULAZIONI rate=2*10^6; simNumber=3000; for sim=1:simNumber simulInfo = canale(simulInfo); simulInfo = BABS(simulInfo,rate); matrix=simulInfo.subCarMatrix; sim assegnazione = allocazione(simulInfo,matrix); assegnOttima=linProgImpl(simulInfo,matrix);

(6)

assegnNoAll=noAll(simulInfo,matrix); vect=sum(assegnazione); vectOtt=sum(assegnOttima); vectNoAll=sum(assegnNoAll); x((1:userNumber)+userNumber*(sim-1))=vect; xOtt((1:userNumber)+userNumber*(sim-1))=vectOtt; xNoAll((1:userNumber)+userNumber*(sim-1))=vectNoAll; end y = pdf1(x); hold on yOtt = pdf2(xOtt); hold on yNoAll = pdf3(xNoAll); end

(7)

A.3 Funzione per generare il canale

function simulInfo = canale(simulInfo) corrChannel = simulInfo.corrChannel; userNumber = simulInfo.userNumber; subCarNumber = simulInfo.subCarNumber; sim = simulInfo.simNum; randSeedChannel=simulInfo.randSeedChannel; if prest==2 simulInfo = calcoloperditacanale(simulInfo); else simulInfo.pathLoss=ones(1,userNumber); end

MATRICE DI GUADAGNI DI CANALE INCORRELATA

if corrChannel == 0

Inizializzazione del generatore di variabili aleatorie uniformi e Gaussiane.

if simulInfo.randSeedChannel==1

randn('state',sum(100000*clock)) Setto un nuovo valore del seme del generatore di numeri casuali else

randn('state',sim) Setto il generatore di variabili aleatorie al valore iniziale end

powerScale = 0.5.^0.5; Generazione del canale X = powerScale*randn(subCarNumber,userNumber); Y = powerScale*randn(subCarNumber,userNumber);

(8)

CANALE CON EXPONENTIAL POWER DELAY PROFILE

elseif corrChannel == 2

simulInfo = canaleprofiloesponenziale(simulInfo); Funzione per il calcolo del guadagno di canale end

MATRICE DEI GUADAGNI DI CANALE TIPO WiLAN

elseif corrChannel ==3

simulInfo=canaleWLAN(simulInfo); end

k = 1.38e-23; Costante di Bolzmann T = 293; Temperatura ambiente

sigBandWidth = simulInfo.sigBandWidth;

subCarBandWidth = sigBandWidth/subCarNumber; simulInfo.noisePower = k*T*subCarBandWidth; simulInfo.simNum = sim+1;

(9)

A.3.1 Calcolo perdita di canale

function simulInfo = calcoloperditacanale(simulInfo)

Funzione che calcola la posizione all'interno della cella per ciascun utente e la Pathloss associata.

userNumber = simulInfo.userNumber; subCarNumber = simulInfo.subCarNumber; carFreq = simulInfo.carFreq; nFFT = subCarNumber; sigBandWidth = simulInfo.sigBandWidth; lightSpeed = 3e8;

lambda = lightSpeed/carFreq; Lunghezza d'onda del segnale trasmesso spatial = simulInfo.spatial;

if spatial==0

simulInfo.pathLoss = ones(1,userNumber); elseif spatial == 1

Genero le posizioni e le attenuazioni di pathloss per ciascun utente nella cella (large scale fading) if simulInfo.randSeedChannel==1 Inizializzazione del generatore di variabili aleatorie uniformi e

Gaussiane

rand('state',sum(100*clock)) Setto un nuovo valore del seme del generatore di numeri casuali else

rand('state',1) Setto il generatore di variabili aleatorie al valore iniziale end

R = simulInfo.radius;

pLExp = simulInfo.pathLossExponent;

unifVar = rand(1,userNumber); Genero una variabile uniformemente distribuita tra 0 e 1 per ciascun

utente

Calcolo la distanza di ciascun utente dalla BS in metri: è formulata in maniera tale che non sia possibile che un utente sia più vicino di 10 m

(10)

simulInfo.userPos = userPos;

Fattore di normalizzazione della Pathloss: attenuazione di spazio libero ad un metro dalla sorgente.

pathLossNorm = (lambda/(4*pi))^2;

pathLoss = (userPos.^-pLExp)*pathLossNorm; Attenuazione dovuta alla Pathloss k = 1.38e-23; Costante di Boltzmann in J/K

T = 293; Temperature del ricevitore in K

subCarBanWidth = sigBandWidth/nFFT; Banda di una sottoportante noisePower = subCarBanWidth*k*T; Potenza del rumore

pathLossNoise = pathLoss/noisePower; Termine che riassume effetto di Pathloss e rumore simulInfo.pathLoss = pathLoss;

end

A.3.2 Canale con exponential power delay profile

function simulInfo = chanExpPowDelPro(simulInfo)

Modello di canale correlato con exponential power delay profile

userNumber = simulInfo.userNumber; subCarNumber = simulInfo.subCarNumber; nFFT = subCarNumber; carFreq = simulInfo.carFreq; sigBandWidth = simulInfo.sigBandWidth; lightSpeed = 3e8;

lambda = lightSpeed/carFreq; Lunghezza d'onda del segnale trasmesso pathLoss = simulInfo.pathLoss;

(11)

Inizializzazione del generatore di variabili aleatorie uniformi e Gaussiane

if simulInfo.randSeedChannel==1

rand('state',sum(100*clock)) Setto un nuovo valore del seme del generatore di numeri casuali randn('state',sum(100*clock))

else

rand('state',sim) Setto il generatore di variabili aleatorie al valore iniziale randn('state',sim)

end

Genero il canale frequency selective secondo un modello di propagazione exponential power delay profile

sampTime = 1/sigBandWidth; Tempo di campionamento segnale OFDM delSpread = simulInfo.rmsDelaySpread;

normDelSpread = delSpread/sampTime; Delay spread normalizzato al tempo di campionamento

Si generano un numero di repliche pari a tre volte il reciproco del delay spread normalizzato.

pathNumber = ceil(3*normDelSpread);

Fattore di normalizzazione che fa sì che il guadagno medio sia pari alla pathloss

normFactor = (1-exp(-(pathNumber)/normDelSpread))... /(1-exp(-1/normDelSpread));

for path = 1:pathNumber

pathPow(path) = (1/normFactor)*exp(-(path-1)/normDelSpread); Potenza media di ciascuna path end

pathStDv = (0.5*pathPow).^.5; Deviazione standard della potenza di ciascuna replica for user = 1:userNumber

chanGain(user,:) = pathStDv.*(randn(1,pathNumber)+i*randn(1,pathNumber)); Genero la risposta di

canale nel dominio del tempo

end

(12)

radioChanFreq(user,:) = fft(chanGain(user,:),nFFT).'; Calcolo la TdF del canale di ciascun utente end

pathLossMatrix = diag(pathLoss); Organizzo il vettore delle pathloss in una matrice

simulInfo.subCarMatrix = ... Matrice che ha gli utenti in ascissa e le sottoportanti in ordinata (pathLossMatrix*(abs(radioChanFreq).^2)).';

A.3.3 Canale WiLan

function simulInfo = canaleWLAN(simulInfo)

simulInfo.subCarNumber = 64; Aggiorno il numero di sottoportanti subCarNumber = simulInfo.subCarNumber;

userNumber=simulInfo.userNumber;

subCarMatrix = zeros(subCarNumber,userNumber); for user=1:userNumber

Inizializzazione del generatore di variabili aleatorie uniformi e Gaussiane.

rand('state',sum(100*clock)) Setto un nuovo valore del seme del generatore di numeri casuali randn('state',sum(100*clock))

subCarVector = canaleWLANsingoloUtente(simulInfo); subCarMatrix(:,user)=subCarVector*simulInfo.pathLoss(user); end

(13)

A.3.4 Canale WiLan per un singolo utente

function subCarVector = canaleWLANsingoloUtente(simulInfo) nFFT = 64;

nSubCar = simulInfo.subCarNumber;

cpLength = 16; Lunghezza del prefisso ciclico

PDP_delays = [0 1 2 3 4 5 6 7 8 9 11 14 17 20 24 29 34 39]*10e-9; Ritardi di propagazione

power_per_PDP_delays_dB = [0 -0.9 -1.7 -2.6 -3.5 -4.3 -5.2 -6.1 -6.9 -7.8 -4.7 -7.3 -9.9 -12.5 -13.7 -18 -22.4 -26.7]; Potenza in dB di ciascun percorso

power_per_PDP_delays_linear = 10.^(.1.*power_per_PDP_delays_dB); Da dB a lineare path_number = size(power_per_PDP_delays_linear,2);

Considero un canale con multipath con un filtro tx/rx

filtCoeff = filtro; coefficients = filtCoeff.coeff; offSet = filtCoeff.offSet; overSampleFactor = filtCoeff.filtOverSamp; tSamp = filtCoeff.Ts/(overSampleFactor); tempRatio = 10e-9/tSamp;

Wishart matrix of dimensions path number

X = sqrt(0.5)*randn(path_number,1); Y = sqrt(0.5)*randn(path_number,1); H = reshape(power_per_PDP_delays_linear,[],1).*(X + i*Y); Channel coefficients sampledDelays = PDP_delays/tSamp; maxDelay = max(sampledDelays); chan.cir = zeros(ceil((maxDelay+length(coefficients))/overSampleFactor),1); Channel Generator subChan = reshape(H,1,[]);

(14)

oSVector(round(sampledDelays)+1) = subChan; subChanConv = conv(oSVector,coefficients);

Channel Impulse Response (CIR)

cir = subChanConv(offSet+(1:overSampleFactor:end));

Normalizing to one the CIR power

normCoeff = sum(abs(cir).^2); cir = (cir)./sqrt(normCoeff); freq = fft(cir,nFFT);

subCarVector=(abs(freq).^2).';

A.4 Algoritmo BABS

function simulInfo = BABS(simulInfo,rate)

CALCOLO DEL NUMERO DELLE SOTTOPORTANTI PER OGNI UTENTE

subCarNumber = simulInfo.subCarNumber; userNumber = simulInfo.userNumber; matrix=simulInfo.subCarMatrix;

mediaCanale=mean(matrix); Valor medio del canale di ogni utente (media sulle sottoportanti) subCarPerUser=ones(1,userNumber); Vettore che indica quante sottoportanti vengono assegnate ad

ogni utente (inizialmente una sottoportante per ogni utente)

subCarUsed=sum(subCarPerUser); Calcolo il numero delle sottoportanti assegnate B=simulInfo.sigBandWidth; Banda complessiva a disposizione

BSubCar=B/subCarNumber; Banda di ogni sottoportante effic=rate/BSubCar;

if simulInfo.prest == 1 effic = 1;

(15)

Il vettore powerUserSubCar è formato dalla potenza necessaria all'utente (user) per trasmettere il suo flusso dati su un numero di sottoportanti pari a quelle ad esso assegnate (subCarPerUser(user)). Il vettore powerUserSubCarUno è formato dalla potenza che sarebbe necessaria ad ogni utente se potesse trasmettere su un numero di sottoportanti pari a quello ad esso assegnate + 1. Il vettore Delta Power è formato dalla differenza di potenza che ogni utente ha trasmettendo su una sottoportante in più.

for user=1:userNumber powerUserSubCar(user)=subCarPerUser(user)*(exp(effic/subCarPerUser(user))-1)/mediaCanale(user); powerUserSubCarUno(user)=(subCarPerUser(user)+1)*(exp(effic/(subCarPerUser(user)+1))-1)/mediaCanale(user); DeltaPower(user)=powerUserSubCar(user)-powerUserSubCarUno(user); end

while subCarUsed ~= subCarNumber; Ciclo fino all'assegnazione di tutte le sottoportanti [maxDeltaPower,userind]=max(DeltaPower); Userind è l'utente che ha il DeltaPower massimo

subCarPerUser(userind)=subCarPerUser(userind)+1; E a tale utente viene effettivamente assegnata una

sottoportante in più

Aggiorno il numero delle sottoportanti assegnate e aggiorno i valori delle potenze e del DeltaPower solo per l'utente che ho considerato.

subCarUsed=sum(subCarPerUser); powerUserSubCar(userind)=subCarPerUser(userind)*(exp(effic/subCarPerUser(userind))-1)/mediaCanale(userind); powerUserSubCarUno(userind)=(subCarPerUser(userind)+1)*(exp(effic/(subCarPerUser(userind)+1))-1)/mediaCanale(userind); DeltaPower(userind)=powerUserSubCar(userind)-powerUserSubCarUno(userind); end simulInfo.subCarPerUser=subCarPerUser;

Dopo aver calcolato quante sottoportanti allocare ad ogni utente, devo creare una nuova matrice dei costi; infatti, se un utente usa una sola sottoportante, essa avrà costo maggiore perchè su di essa si trasmetteranno tutti i bit e sarà necessaria molta potenza; se invece un utente trasmette su 10 sottoportanti, ciascuna sottoportante supporta solo 1/10 del flusso di bit e la potenza per trasmettere su di essa è inferiore. Nel primo caso descritto il costo sarà superiore al secondo. La matrice dei costi si ottiene considerando un termine che tiene conto del numero di sottoportanti allocate ad ogni utente e dividendo tale termine per il guadagno di canale di ogni utente su ogni sottoportante.

(16)

subCarMatrix=simulInfo.subCarMatrix; for user=1:userNumber ni(user)=effic/subCarPerUser(user); pesi(user)=2^(ni(user))-1; costMatrix(:,user)=pesi(user)./subCarMatrix(:,user); end simulInfo.costMatrix=costMatrix;

A.5 Algoritmo di allocazione dinamica delle sottoportanti

function assegnazione = allocazione(simulInfo, matrix)

ALLOCA AD OGNI UTENTE UNA O PIU' SOTTOPORTANTI

Alloca ad ogni utente il numero di sottoportanti inserito nel vettore subCarPerUser. Funziona solo se il numero di sottoportanti è maggiore o uguale al numero degli utenti

subCarNumber = simulInfo.subCarNumber; Numero di sottoportanti subCarNumberNew=subCarNumber;

userNumber = simulInfo.userNumber; Numero di utenti

prest=simulInfo.prest; Tipo di prestazioni che voglio calcolare if prest==2

matrix=-matrix; Poiché voglio minimizzare la matrice dei costi e il programma massimizza la

matrice che ha in ingresso, devo considerare i valori negativi

end

subCarPerUser=simulInfo.subCarPerUser; Vettore che indica quante sottoportanti devono essere

assegnate a ciascun utente

userRid=4; Vettore che indica quanti utenti vengono considerati nella matrice ridotta probl=0; Variabile che viene successivamente settata a 1 se si verificano problemi

(17)

Ordino le colonne in modo che la prima sia quella a valor medio minore; media è il vettore dei valor medi di ogni colonna; mediaOrd è il vettore dei valori medi ordinati; ord è il vettore che tiene conto di come sono state spostate le colonne; matrixOrd è la matrice così ordinata

media=mean(matrix); [mediaOrd,ord]=sort(media); matrixOrd=matrix(:,ord);

matrixOrdConMinimi=matrixOrd; matrixOrdOld=matrixOrd;

Si lavora su una matrice ridotta composta da tutte le righe della matrice di canale (cioè tutte le sottoportanti) ma solo 4 colonne (cioè solo 4 utenti); man mano che si assegna una colonna (cioè ad un utente vengono assegnate le sottoportanti richieste), non si considera più quella colonna e si aggiunge la successiva.

matrixRid=matrixOrd(:,(1:userRid)); subCarPerUserOrd=subCarPerUser(ord);

subCarPerUserRid=subCarPerUserOrd(1:userRid);

userPos=1:userNumber; Vettore da 1 a userNumber che mi serve per tener conto degli utenti a cui ho

già assegnato le sottoportanti richieste

subCarPos=1:subCarNumber; Vettore da 1 a subCarNumber che mi serve per tener conto delle

sottoportanti già assegnate

subCarFinitePos=subCarPos(isfinite(subCarPos)); Vettore che indica quali sono le posizioni finite di userFinitePos=userPos(isfinite(userPos)); userPos e subCarPos

userLeftNum=userNumber-userRid; E’ il numero di utenti che non considero, cioè che rimangono

assegnazione=zeros(subCarNumber,userNumber);

Matrice di assegnazione utente-sottoportante (è una matrice di 0 che vengono messi a 1 per indicare l'assegnazione)

(18)

ass=ones(subCarNumber,userNumber);

Matrice di appoggio (è una matrice di 1 che vengono messi a 0 per indicare che quell'assegnazione non viene fatta) assConMinimi=ass; assOld=ass; assRid=ones(subCarNumber,userRid); SrigheassRid=sum(assRid,2); ScolonneassRid=sum(assRid);

while subCarPerUserRid ~= 0 Cioè finché non vengono assegnate tutte le sottoportanti necessarie ad

ogni utente

1. Caso in cui il numero di utenti a cui devono ancora essere assegnate delle sottoportanti sia maggiore di 4

if numel(userFinitePos) > userRid

Cancello i valori più piccoli di canale solo nel caso in cui non vi siano delle assegnazioni obbligate;

tali assegnazioni obbligate sono dovute al fatto che in una colonna (utente) sono rimaste un numero di assegnazioni possibili pari a quelle richieste da quell'utente. E' importante prestare attenzione agli indici delle assegnazioni; per questo uso subCarFinitePos e userFinitePos

if (ScolonneassRid~=subCarPerUserRid) [minC,ind]= min(matrixRid);

[minmatrix,user] = min(minC); Trovo l'indice utente del valore minimo nella matrice di canale subCar = ind(user); Trovo l'indice sottoportante del valore minimo nella matrice di canale subCarFinitePos=subCarPos(isfinite(subCarPos)); Passo dagli indici di matrix ridotta a quelli di

matrix

userFinitePos=userPos(isfinite(userPos)); subCarReal=subCarFinitePos(subCar); userReal=userFinitePos(user);

matrixOrdConMinimi (subCarReal , userReal)=inf; matrixRid (subCar , user)=inf;

(19)

assConMinimi (subCarReal , userReal)=0; ScolonneassRid=sum(assRid);

SrigheassRid=sum(assRid,2); else

Considero il caso di una colonna (utente) in cui è necessario fare una o più assegnazioni perché è

rimasto un numero di accoppiamenti utente-sottoportante pari a quello indicato in subCarPerUser

userInd=find(ScolonneassRid==subCarPerUserRid); Trovo l'indice di colonna della matrice

ridotta

for ind=1:numel(userInd)

subCarInd=find(matrixRid(:,userInd(ind))~=inf); Trovo l'indice di riga della matrice ridotta for index=1:numel(subCarInd)

subCarReal=subCarFinitePos(subCarInd(index)); userReal=userFinitePos(userInd(ind));

assegnazione(subCarReal,userReal)=1; Assegno matrixRid(subCarInd(index),:)=inf;

subCarPos(subCarReal)=inf; Cancello la sottoportante appena assegnata

subCarPerUserOrd(userReal)=subCarPerUserOrd(userReal)-1; Decremento subCarPerUser

per indicare l'avvenuta assegnazione

end

userPos(userReal)=inf; Cancello l'utente che ho considerato end

Aggiorno matrixRid e assRid tenendo conto delle colonne cancellate (cioè messe a inf). RigheNulle=find(SrigheassRid==0);

numRigheNulle=numel(RigheNulle);

subCarFinitePos=subCarPos(isfinite(subCarPos)); userFinitePos=userPos(isfinite(userPos));

(20)

userLeftNum=numel(userFinitePos)-userRid; numUserFinitePos=numel(userFinitePos);

userLeft=userFinitePos((userRid+1):numUserFinitePos); subCarLeft=sum(subCarPerUserOrd(userLeft));

minMatrixRid=min(min(matrixRid)); Il valore più piccolo rimasto in matrixRid

Dopo aver effettuato le cancellazioni della o delle colonne assegnate, posso avere un numero di

utenti ancora da assegnare maggiore, uguale o minore a userRid=4; devo allora cambiare opportunamente la dimensione della matrice ridotta

numUserFinitePos=numel(userFinitePos); if numUserFinitePos>userRid userDim=userRid; else userDim=numUserFinitePos; end

Considero due diversi casi:

A. Nella matrice ridotta ci sono un numero di righe completamente cancellate (perchè con valori piccoli) superiore al numero di utenti rimasti (che devo ancora considerare); in questo caso non riuscirò con gli utenti restanti ad assegnare tutte le sottoportanti. Devo quindi resettare tutto e ricominciare da capo il calcolo dei minimi

if numRigheNulle>subCarLeft matrixRid=matrixOrd (subCarFinitePos,userFinitePos(1:userDim)); [subCarNumberNew,userNumberNew]=size(matrixRid); assRid=ass(subCarFinitePos,userFinitePos(1:userDim)); SrigheassRid=sum(assRid,2); ScolonneassRid=sum(assRid); subCarPerUserRid=subCarPerUserOrd(userFinitePos(1:userDim)); matrixOrdConMinimi=matrixOrd;

(21)

assConMinimi=ass;

B. La condizione sopra non è verificata quindi posso tenere la matrice ridotta con i minimi già

calcolati e scartati. Prima di aggiungere un'altra colonna, ne cancello tutti i valori più piccoli del minimo della matrice ridotta.

else

if userLeftNum>0 Se quello considerato non è l'ultimo utente da aggiungere nuovoUtente=userFinitePos(userDim);

nuovaColonna=matrixOrdConMinimi(:,nuovoUtente); maxNuovaColonna=max(nuovaColonna);

Se il massimo valore della nuova colonna è minore del minimo della vecchia matrice ridotta,

allora devo mettere a inf tutti i valori della nuova colonna minori di tale massimo, che al ciclo successivo verrà assegnato (il massimo della nuova colonna diventa il valore di confronto). Altrimenti metto a inf solo i valori della nuova colonna che sono più piccoli del minimo della vecchia matrice (che è il valore di confronto).

if maxNuovaColonna<minMatrixRid valoreDiConfronto=maxNuovaColonna; else valoreDiConfronto=minMatrixRid; end riga=find(nuovaColonna<valoreDiConfronto); for ind=1:numel(riga) matrixOrdConMinimi(riga(ind),nuovoUtente)=inf; assConMinimi(riga(ind),nuovoUtente)=0; end end matrixRid=matrixOrdConMinimi(subCarFinitePos,userFinitePos(1:userDim)); [subCarNumberNew,userNumberNew]=size(matrixRid); assRid=assConMinimi(subCarFinitePos,userFinitePos(1:userDim));

(22)

SrigheassRid=sum(assRid,2); ScolonneassRid=sum(assRid);

subCarPerUserRid=subCarPerUserOrd(userFinitePos(1:userDim)); end

end

2. Caso in cui il numero di utenti a cui devono ancora essere assegnate delle sottoportanti si è ridotto

a 4

else

Cancello i valori più piccoli di canale solo nel caso in cui non vi siano delle assegnazioni obbligate;

tali assegnazioni obbligate sono dovute al fatto che in una colonna (utente) sono rimaste un numero di assegnazioni possibili pari a quelle richiesta da quell'utente oppure al fatto che in una riga (sottoportante) è rimasta una sola possibile assegnazione utente-sottoportante. E' importante fare attenzione agli indici delle assegnazioni; per questo uso subCarFinitePos e userFinitePos

if (ScolonneassRid~=subCarPerUserRid) if (SrigheassRid~=1)

[minC,ind]= min(matrixRid);

[minmatrix,user] = min(minC); Trovo l'indice utente del valore minimo nella matrice di canale subCar = ind(user); Trovo l'indice sottoportante del valore minimo nella matrice di canale subCarFinitePos=subCarPos(isfinite(subCarPos)); Passo dagli indici di matrix ridotta a quelli

di matrix

userFinitePos=userPos(isfinite(userPos)); subCarReal=subCarFinitePos(subCar); userReal=userFinitePos(user);

matrixOrd (subCarReal , userReal)=inf; matrixRid (subCar , user)=inf;

assRid (subCar , user)=0; ass (subCarReal , userReal)=0; SrigheassRid=sum(assRid,2);

(23)

else

Considero il caso di una riga (sottoportante) in cui è necessario fare un’assegnazione perchè è rimasto solo quel possibile accoppiamento utente-sottoportante.

subCarInd=find(SrigheassRid==1); Trovo l'indice di riga della matrice ridotta for ind=1:numel(subCarInd)

ciclo fittizio nel caso vi siano più sottoportanti rimaste a 1

userInd=find(assRid(subCarInd(ind),:)==1); Trovo l'indice di colonna della matrice ridotta subCarReal=subCarFinitePos(subCarInd(ind));

userReal=userFinitePos(userInd);

assegnazione(subCarReal,userReal)= 1; Assegno

subCarPos(subCarReal)=inf; Cancello la sottoportante appena assegnata subCarPerUserOrd(userReal)=subCarPerUserOrd(userReal)-1; Decremento subCarPerUser

per indicare l'avvenuta assegnazione

Considero il caso in cui nella colonna (utente) considerata sono già assegnati tutti gli accoppiamenti utente-sottoportante richiesti.

if subCarPerUserOrd(userReal)==0

userPos(userReal)=inf; Cancello l'utente in questione end

Nel caso in cui si crei un conflitto tra le righe cancellate, rimetto i valori originari e metto

probl a 1 così tengo nota che è avvenuto qualcosa e in seguito carico la matrice senza i minimi cancellati. if subCarPerUserOrd(userReal)<0 subCarPos(subCarReal)=subCarReal; subCarPerUserOrd(userReal)=subCarPerUserOrd(userReal)+1; probl=1; end end

(24)

Aggiorno matrixRid e assRid tenendo conto delle colonne cancellate (cioè messe a inf). Non si

tiene conto dei minimi prima cancellati ma si resetta tutto, cercando nuovamente i minimi di questa nuova matrice ridotta

subCarFinitePos=subCarPos(isfinite(subCarPos)); userFinitePos=userPos(isfinite(userPos)); if probl==1 matrixRid=matrixOrdOld(subCarFinitePos,userFinitePos); assRid=assOld(subCarFinitePos,userFinitePos); else matrixRid=matrixOrd(subCarFinitePos,userFinitePos); assRid=ass(subCarFinitePos,userFinitePos); end [subCarNumberNew,userNumberNew]=size(matrixRid); SrigheassRid=sum(assRid,2); ScolonneassRid=sum(assRid); subCarPerUserRid=subCarPerUserOrd(userFinitePos); end else

Considero il caso di una colonna (utente) in cui è necessario fare una o più assegnazioni perché è rimasto un numero di accoppiamenti utente-sottoportante pari a quello indicato in subCarPerUser

userInd=find(ScolonneassRid==subCarPerUserRid); Trovo l'indice di colonna della matrice

ridotta

for ind=1:numel(userInd)

subCarInd=find(matrixRid(:,userInd(ind))~=inf); Trovo l'indice di riga della matrice ridotta for index=1:numel(subCarInd)

subCarReal=subCarFinitePos(subCarInd(index)); userReal=userFinitePos(userInd(ind));

(25)

subCarPos(subCarReal)=inf; cancello la sottoportante appena assegnata

subCarPerUserOrd(userReal)=subCarPerUserOrd(userReal)-1; Decremento subCarPerUser

per indicare l'avvenuta assegnazione

end

userPos(userReal)=inf; Cancello l'utente che ho considerato end

Aggiorno matrixRid e assRid tenendo conto delle colonne cancellate (cioè messe a inf). Se però

mi trovo con una nuova matrixRid in cui una colonna è tutta di valori inf, allora resetto tutto e ricomincio il calcolo dei minimi.

subCarFinitePos=subCarPos(isfinite(subCarPos)); userFinitePos=userPos(isfinite(userPos)); matrixRid=matrixOrd(subCarFinitePos,userFinitePos); [subCarNumberNew,userNumberNew]=size(matrixRid); assRid=ass(subCarFinitePos,userFinitePos); SrigheassRid=sum(assRid,2); ScolonneassRid=sum(assRid); subCarPerUserRid=subCarPerUserOrd(userFinitePos); if sum(ScolonneassRid==0)>0 matrixRid=matrixOrdOld(subCarFinitePos,userFinitePos); assRid=ones(subCarNumberNew,userNumberNew); SrigheassRid=sum(assRid,2); ScolonneassRid=sum(assRid); end end end end

(26)

[ordord,ordInv]=sort(ord); assegnazione=assegnazione(:,ordInv); assegnazione=assegnazione.*(matrix); if prest==2 assegnazione=-assegnazione; end

A.6 Algoritmo di Linprog

function assegnOttima=linProgImpl(simulInfo,matrix)

Implemento il linear programming per trovare la soluzione ottima da confrontare con l'algoritmo di allocazione studiato

userNumber = simulInfo.userNumber; subCarNumber = simulInfo.subCarNumber; subCarPerUser = simulInfo.subCarPerUser;

prest=simulInfo.prest; Tipo di prestazioni che voglio calcolare costVector=reshape(matrix',[],1); Vettore di costi

if prest~=2

costVector=-costVector; end

Devo poi imporre dei vincoli:

VINCOLO SULLE SOTTOPORTANTI:ogni sottoportante può essere assegnata al massimo ad un utente. Creo la matrice dei vincoli sulle sottoportanti: matrice di zeri con alcuni blocchi formati da tutti 1

matSubCar=zeros(subCarNumber,subCarNumber*userNumber); block=ones(1,userNumber);

for subCar=1:subCarNumber indPos=subCar-1;

(27)

Creo un vettore che esprime il vincolo per ciascuna sottoportante: che venga assegnata al massimo 1 volta

bConstr = ones(subCarNumber,1);

VINCOLO SUGLI UTENTI: ad ogni utente deve essere assegnato un numero di sottoportanti pari a quello indicato in subCarPerUser (calcolato col BABS).

matUser=zeros(userNumber,subCarNumber*userNumber); ident=eye(userNumber); for subCar=1:subCarNumber indPos=subCar-1; matUser(1:userNumber,indPos*userNumber+(1:userNumber))=ident; end bConstrEq=reshape(subCarPerUser,[],1); lb = zeros(subCarNumber*userNumber,1); ub = ones(subCarNumber*userNumber,1); LINPROG options = optimset('LargeScale','off','Simplex','on','Display','off'); assVector=linprog(costVector,matSubCar,bConstr,matUser,bConstrEq,lb,ub,[],options)

Ricostruisco la matrice di assegnazione

ass=reshape(assVector,userNumber,subCarNumber); assegnOttima=ass'.*matrix;

(28)

A.7 Calcolo prestazioni: probabilità d’errore

function BER = calcoloBER(vect,SNR)

Funzione che calcola il BER a partire dai guadagni di canale di tutti gli utenti e dal SNR medio. L'energia viene distribuita tra i vari utenti in modo che il BER sia uguale per tutti. Ciascun utente n viene scalato per alfa*(1/H(n)^2). Imponendo che la potenza massima da distribuire sia N (numero di utenti) => alfa = 1/(media(1/canale))

inverse = 1./vect; Reciproco dei guadagni di canale

Fattore che va a scalare Eb/N0. Se in teoria tutti i canali fossero maggiori di uno => alfa sarebbe maggiore di uno! Prestazioni migliori anche di AWGN

alfa = 1/mean(inverse);

BER = 2*Qfunc((SNR*alfa).^.5);

A.8 Calcolo prestazioni: funzione densità di probabilità

function y = pdf(x)

Funzione che calcola la pdf di una variabile aleatoria partendo dal vettore che x che raccoglie un certo numero di realizzazioni.

nBins = 100; Numero di bins della funzione hist

[freq,bins] = hist(x,nBins); Si calcola con che frequenza la v.a. assume un certo range di valori xMax = max(x);

xMin = min(x);

xDelta = (xMax-xMin)/nBins; xDim = length(x);

y = freq/(xDelta*xDim); Scalo la frequenza relativa per farla diventare una pdf plot(bins,y)

Riferimenti

Documenti correlati

Informalmente, il primo passo dell’algoritmo fa in modo che il pivot della prima riga com- paia prima dei pivot delle righe dalla seconda in poi, il secondo passo dell’algoritmo fa

[r]

[r]

• Ciascuna delle righe di B, essendo stata ottenuta dalle righe di A mediante le operazioni fondamentali sui vettori, appartiene allo spazio generato dalle righe di A..

Infatti, se e vero che ogni vettore di V si puo’ scrivere in almeno un modo come combinazione lineare dei vettori a, b, c, non e’ pero’ vero che tale scrittura e’

[r]

[r]

In seguito useremo la seguente convenzione: quando un vettore v viene consid- erato come vettore colonna, verra’ indicato con lo stesso simbolo v, quando un vettore v viene