Appendice software
In questa sezione vengono riportati alcuni programmi utilizzati nelle simulazioni al
calcolatore, effettuate presso il Laboratorio di Simulazione dei Sistemi di
Comunicazione del Dipartimento di Ingegneria dell’Informazione di Pisa.
E’ stato utilizzato il linguaggio di programmazione FORTRAN90.
Per l’esecuzione dei programmi vengono richiamate anche alcune routine, che fanno
parte della libreria del pacchetto di SPACE (Software Package for Communication
Enviroment). Nnon vengono riportate in quanto facilmente reperibili.
Il primo programma (µ) calcola la BER su canale lentamente variabile, per un
sistema MC-DS-CDMA, al variare di µ,per un SNR pari a 10dB, utilizzando il
metodo di rivelazione MRC, e stimatore LMS.
Il secondo programma (LMS) calcola la BER, nelle stesse condizioni di cui
sopra, al variare del SNR, con canale stimato tramite algoritmo LMS.
Il terzo programma (RLS) calcola la BER, ma con canale stimato tramite
algoritmo RLS.
I. Calcolo della probabilità di errore con canale lentamente variabile
tramite il rivelatore MRC, stima di canale LMS, al variare di µ, fissato
SNR=10dB
Riportiamo il corpo principale del programma e di seguito le subroutine implementate.
program µ implicit none
character*60 filein,filemonitor,fileout character*5 Gauss
integer*4 Nlev,semerum,semesig,semetaps,Npunti,
& j,mm,Nutenti,Numblock,N,Ntap,ljk,k, nlimit, & i,u1(32),u2(32),m,dimeWH,indl,contadec, & indice1,indice2,contaerr,np,ni,ii, wh,Niter, & mmm,stepBut,contapot,Na,nblocchi, deciso1, & deciso2,Nmedia,index1,index,nant,transit, & contaerr_st,contablocchi,NumTrame,ind Real*4 AREAFAD(513) real*4 ebsun0dBin,ebsun0dBfin,ebsun0dB,ebsun0, & dev,usc(2),devtap,pi,asc(100),mu,Hst(20,32), & rolloff,AreaCh2(10000),BER,BN,Bd,muin,mufin, & essun0,Qfun,potmed,potenza,a(20,32),b, & alfanew(100),alfain(100),ord_id(100), & pip,rum(2),ord(100),matWH(256,256)complex*8 & X(20,20),simb(32),H(20),stat,z_st(20,32), & simb_st(32),alpha(20,32),somma(20,32), & z(20),alpha_st(20,32),stat_st,alpha_v, parameter(pi=3.141592653589793) filein='µ.in' filemonitor='µ.mon' fileout='µ.out' open(10,file=filein) read(10,*) read(10,*) gauss read(10,*) read(10,*) ni read(10,*) read(10,*) Nlev read(10,*)
read(10,*) semesig read(10,*) read(10,*) semerum read(10,*) read(10,*) semetaps read(10,*) read(10,*) muin read(10,*) read(10,*) mufin read(10,*) read(10,*) Npunti read(10,*) read(10,*) NumTrame read(10,*) read(10,*) Numblock read(10,*) read(10,*) Na read(10,*) read(10,*) dimeWH read(10,*) read(10,*) Nutenti read(10,*) read(10,*) nlimit read(10,*) read(10,*) Bd read(10,*) read(10,*) np read(10,*) read(10,*) stepBut close(10) --- PARAMETRI FILTRO PASSA-BASSO PER FADING
--- pip=pi/(2.*np) BN=Bd*pip/sin(pip) devtap=0.5*sqrt(1/BN) transit=5*nint(1/Bd) contapot=0
--- GENERAZIONE SEQUENZE DI SPREADING
--- do k=1,dimeWH do ljk=1,dimeWH call walsh(k-1,ljk-1,wh) matWH(ljk,k)=wh/sqrt(real(dimeWH)) enddo enddo --- INIZIO CICLO SU SNR --- do mm=0,Npunti mu=muin+mm*(mufin-muin)/Npunti ebsun0dB=10. ebsun0=10**(0.1*ebsun0dB) essun0=ebsun0*nint((Log10(real(Nlev)))/Log10(2.)) dev=sqrt(0.5/essun0) --- INIZIALIZZAZIONE COSTANTI --- contadec=0 potenza=0. contaerr=0 contaerr_st=0 contablocchi=-1 contapot=0 do nant=1,Na do k=1,Nutenti a(nant,k)=0 alpha_st(nant,k)=cmplx(0.,0.) enddo enddo --- CICLO SUL NUMERO DI TRAME
--- do mmm=1,NumTrame
--- DEFINIZIONE FILTRO DI BUTTERWORTH PER IL FADING
--- call ButDef(AreaFad,2*Na*Nutenti,Np,0.,Bd,1.)
c? ButDef(AreaFad,100,4,0.,Bd,1.)
--- TRANSITORIO INIZIALE PER IL FILTRO DI BUTTERWORTH
--- do i=1,transit do j=1,Na*Nutenti call Gaussgen(usc,devtap,semetaps) alfain(2*j-1)=usc(1) alfain(2*j)=usc(2) enddo call FilRun(AreaFad,alfain,alfanew) enddo --- CICLO SUL NUMERO DI BLOCCHI DI BLOCCHI
--- nblocchi=-1
do ii=1,Numblock
nblocchi=nblocchi+1
--- GENERAZIONE BIT UTENTI
--- do k=1,Nutenti call symb_gray(simb(k),u1(k),u2(k),semesig) enddo --- INIZIALIZZAZIONE VARIABILI --- do ljk=1,dimeWH do nant=1,Na X(ljk,nant)=cmplx(0.,0.) enddo enddo do nant=1,Na H(nant)=cmplx(0.,0.) enddo --- GENERAZIONE DEL SEGNALE RICEVUTO
--- do ljk=1,dimeWH
contablocchi=contablocchi+1 do k=1,Na*Nutenti
call Gaussgen(usc,devtap,semetaps) alfain(2*k-1)=usc(1) alfain(2*k)=usc(2) enddo if(mod(contablocchi,stepBut).eq.0) then call FilRun(AreaFad,alfain,alfanew) endif --- CANALE DELL'UTENTE UTILE
--- do nant=1,Na index1=1+2*Nutenti*(nant-1) H(nant)=H(nant)+(cmplx(alfanew(index1), & alfanew(index1+1)))/dimeWH do k=1,Nutenti index=2*k-1+2*Nutenti*(nant-1) alpha(nant,k)=cmplx(alfanew(index), & alfanew(index+1)) if(gauss.eq.'SI') & alpha(nant,k)=cmplx(1.,0.) X(ljk,nant)=X(ljk,nant)+alpha(nant,k)* & simb(k)*matWH(ljk,k) enddo call Gaussgen(rum,dev,semerum) X(ljk,nant)=X(ljk,nant)+ & ni*cmplx(rum(1),rum(2)) enddo enddo do nant=1,Na potenza=potenza+(cabs(H(nant))**2-1) contapot=contapot+1 enddo --- TRAINING DELLA STIMA DI CANALE
--- if(nblocchi.eq.0) then do nant=1,Na do k=1,Nutenti Hst(nant,k)=cmplx(0.,0.) enddo enddo
do nant=1,Na do k=1,Nutenti somma(nant,k)=cmplx(0.,0.) potmed=(cabs(simb(k))**2) do ljk=1,dimeWH somma(nant,k)=somma(nant,k)+matWH(ljk,k) & *X(ljk,nant) enddo Hst(nant,k)=(1/potmed)*(conjg(simb(k))) & *somma(nant,k) enddo enddo goto 100 endif --- RIVELAZIONE CON CANALE STIMATO
--- stat_st=cmplx(0.,0.) do nant=1,Na do k=1,Nutenti z_st(nant,k)=cmplx(0.,0.) do ljk=1,dimeWH z_st(nant,k)=z_st(nant,k)+X(ljk,nant) & *matWH(ljk,k) enddo alpha_st(nant,k)=Hst(nant,k) if(gauss.eq.'SI') alpha_st(nant,k)=cmplx(1.,0.) stat_st=stat_st+conjg(alpha_st(nant,k)) & *z_st(nant,k) enddo enddo
call Decisore (stat_st,deciso1,deciso2)
if(deciso1.ne.u1(1)) contaerr_st= contaerr_st+1 if(deciso2.ne.u2(1)) contaerr_st= contaerr_st+1 do k=1,Nutenti call graymap(deciso1,deciso2,simb_st(k)) enddo call LMS(Na,Nutenti,dimeWH,matWH,X, & Hst,mu,nblocchi,simb_st) contadec=contadec+2
if(contaerr_st.ge.nlimit) goto 200 --- FILE MONITOR 1 --- 100 if((mod(mmm,100).eq.0).and.(ii.eq.1)) then open(20,file=filemonitor,err=99) write(20,*) write(20,*) 'FILEMONITOR' write(20,*) write(20,*) 'muiniziale=',muin,' ', & 'mufinale=',mufin write(20,*) write(20,*) 'Eb/No=',ebsun0dB write(20,*) write(20,*) 'mu=',mu write(20,*) write(20,*) 'potenza & canale',potenza/contapot+1 write(20,*) write(20,*) 'Nutenti=',Nutenti write(20,*)
write(20,*) 'N trame:',' ',NumTrame write(20,*)
write(20,*) 'N trame esaminate:',' ',mmm write(20,*) if(contaerr_st.ne.0) then write(20,*) 'P(e):', & Log10(real(contaerr_st)/contadec) else write(20,*) 'P(e):-INF' endif 99 close(20) endif
enddo !FINE BLOCCHI DI BLOCCHI enddo !FINE TRAME
do nant=1,Na do k=1,Nutenti a(nant,k)=a(nant,k)/Numtrame enddo enddo 200 asc(mm+1)=mu
ord(mm+1)=log10(real(contaerr_st)/contadec) open(30,file=fileout,access='append') write(30,*) write(30,*) asc(mm+1) write(30,*) ord(mm+1) close(30) enddo !FINE SNR call grf2update(0) call grf2block(1,asc,ord,Npunti+1,'Pe_can_st',0) end
--- SUBROUTINE WALSH
--- SUBROUTINE walsh(rig, col, w_h)
implicit none
integer*4 rig, col, w_h, x(0:8), y(0:8), espo, & i,j,usc, c,k i = rig j = col c = 0 espo = 0 do c = 0,8 x(c) = mod(i, 2) i = i / 2 y(c) = mod(j, 2) j = j / 2
espo = espo + (x(c) * y(c)) enddo usc = 1 if(espo.ne.0) then do k = 0, (espo-1), 1 usc = -usc enddo endif w_h = usc return end --- SUBROUTINE GRAYMAP --- SUBROUTINE graymap(b1,b2,simbo) implicit none integer*4 b1,b2 complex*8 simbo if((b1.eq.0).and.(b2.eq.0)) simbo=(1.,0.) if((b1.eq.0).and.(b2.eq.1)) simbo=(0.,1.) if((b1.eq.1).and.(b2.eq.1)) simbo=(-1.,0.) if((b1.eq.1).and.(b2.eq.0)) simbo=(0.,-1.) return end
--- SUBROUTINE SYMB_GRAY --- SUBROUTINE symb_gray(simbolo,u1,u2,semesig) implicit none integer*4 u1,u2,semesig complex*8 simbolo call UNI_SymbGen(u1,1,2,semesig) call UNI_SymbGen(u2,1,2,semesig) call graymap(u1,u2,simbolo) return end --- SUBROUTINE DECISORE --- SUBROUTINE decisore(x,dec1,dec2) implicit none integer*4 dec,dec1,dec2 real*4 fi,fi1,pi complex*8 x pi=3.141592653589793 fi1=180*(atan2(aimag(x),real(x)))/pi fi=fi1 dec=2 if(abs(fi).lt.45) dec=0 fi=fi1-90 if(abs(fi).lt.45) dec=1 fi=fi1+90 if(abs(fi).lt.45) dec=3 if(dec.eq.0) then dec1=0 dec2=0 endif if(dec.eq.1) then dec1=0 dec2=1 endif if(dec.eq.2) then dec1=1
dec2=1 endif if(dec.eq.3) then dec1=1 dec2=0 endif return end --- SUBROUTINE STIMA DI CANALE
--- SUBROUTINE LMS(Na,Nutenti,dimeWH,matWH,X,Hst, & mu,nblocchi,simb_st) implicit none integer*4 nant,k,ljk,Na,Nutenti,dimeWH,nblocchi,ind real*4 mu,matWH(256,256) complex*8 X(20,20),Hst(20,32),simb_st(32), & somma(20,32) do nant=1,Na do k=1,Nutenti somma(nant,k)=cmplx(0.,0.) do ljk=1,dimeWH somma(nant,k)=somma(nant,k)+matWH(ljk,k) & *X(ljk,nant) enddo Hst(nant,k)=(1-mu)*Hst(nant,k)+mu* & conjg(simb_st(k))*somma(nant,k) enddo enddo end
II.
Calcolo della probabilità di errore con canale lentamente
variabile tramite il rivelatore MRC, stima di canale LMS, al
variare del SNR
Riportiamo il corpo principale del programma e di seguito le subroutine implementate.
program LMS implicit none
character*60 filein,filemonitor,fileout character*5 Gauss
integer*4 Nlev,semerum,semesig,semetaps,Npunti, & j,mm,Nutenti, Numblock,N,Ntap,ljk, & k,nlimit,i,u1(32),u2(32),m,dimeWH,indl, & contadec,indice1,indice2,contaerr,np,ni, & ii,wh,Niter,mmm,stepBut,deciso2_st(32), & contapot,Na,nblocchi,deciso1_st(32), & Nmedia,index1,index, contaerr_st, & deciso1,deciso2,nant, & contablocchi,NumTrame,ind,transit, Real*4 AREAFAD(513) real*4 ebsun0dBin,ebsun0dBfin,ebsun0dB,ebsun0, & dev,usc(2),devtap,pi,asc(100),mu, & rolloff,AreaCh2(10000),BER,BN,Bd, & essun0,Qfun,potmed,potenza,a(20,32),b, & alfanew(100),alfain(100),ord_id(100), & pip,rum(2),ord(100),matWH(256,256) complex*8 X(20,20),simb(32),H(20),stat,z_st(20,32), & simb_st(32),alpha(20,32), alpha_v
& somma(20,32),Hst(20,32), & z(20),alpha_st(20,32),stat_st(32), parameter(pi=3.141592653589793) filein='LMS.in' filemonitor='LMS.mon' fileout='LMS.out' open(10,file=filein) read(10,*) read(10,*) gauss read(10,*) read(10,*) ni read(10,*)
read(10,*) Nlev read(10,*) read(10,*) semesig read(10,*) read(10,*) semerum read(10,*) read(10,*) semetaps read(10,*) read(10,*) ebsun0dBin read(10,*) read(10,*) ebsun0dBfin read(10,*) read(10,*) Npunti read(10,*) read(10,*) NumTrame read(10,*) read(10,*) Numblock read(10,*) read(10,*) Na read(10,*) read(10,*) dimeWH read(10,*) read(10,*) Nutenti read(10,*) read(10,*) nlimit read(10,*) read(10,*) Bd read(10,*) read(10,*) np read(10,*) read(10,*) stepBut read(10,*) read(10,*) mu close(10) --- PARAMETRI FILTRO PASSA-BASSO PER FADING
--- Bd=Bd*stepBut
pip=pi/(2.*np) BN=Bd*pip/sin(pip) devtap=0.5*sqrt(1/BN)
transit=5*nint(1/Bd) contapot=0
--- GENERAZIONE SEQUENZE DI SPREADING
--- do k=1,dimeWH do ljk=1,dimeWH call walsh(k-1,ljk-1,wh) matWH(ljk,k)=wh/sqrt(real(dimeWH)) enddo enddo --- INIZIO CICLO SU SNR --- do mm=0,Npunti ebsun0dB=ebsun0dBin+mm*(ebsun0dBfin- & ebsun0dBin)/Npunti ebsun0=10**(0.1*ebsun0dB) essun0=ebsun0*nint((Log10(real(Nlev)))/Log10(2.)) dev=sqrt(0.5/essun0) --- INIZIALIZZAZIONE COSTANTI --- contadec=0 potenza=0. contaerr=0 contaerr_st=0 contablocchi=-1 contapot=0 do nant=1,Na do k=1,Nutenti a(nant,k)=0 alpha_st(nant,k)=0. enddo enddo --- CICLO SUL NUMERO DI TRAME
--- do mmm=1,NumTrame
--- DEFINIZIONE FILTRO DI BUTTERWORTH PER IL FADING
--- call ButDef(AreaFad,2*Na*Nutenti,Np,0.,Bd,1.)
c? ButDef(AreaFad,100,4,0.,Bd,1.)
--- TRANSITORIO INIZIALE PER IL FILTRO DI BUTTERWORTH
--- do i=1,transit do j=1,Na*Nutenti call Gaussgen(usc,devtap,semetaps) alfain(2*j-1)=usc(1) alfain(2*j)=usc(2) enddo call FilRun(AreaFad,alfain,alfanew) enddo --- CICLO SUL NUMERO DI BLOCCHI DI BLOCCHI
--- nblocchi=-1
do ii=1,Numblock
nblocchi=nblocchi+1
--- GENERAZIONE BIT UTENTI
--- do k=1,Nutenti call symb_gray(simb(k),u1(k),u2(k),semesig) enddo --- INIZIALIZZAZIONE VARIABILI --- do ljk=1,dimeWH do nant=1,Na X(ljk,nant)=cmplx(0.,0.) enddo enddo do nant=1,Na H(nant)=cmplx(0.,0.) Enddo
--- GENERAZIONE DEL SEGNALE RICEVUTO
--- do ljk=1,dimeWH contablocchi=contablocchi+1 do k=1,Na*Nutenti call Gaussgen(usc,devtap,semetaps) alfain(2*k-1)=usc(1) alfain(2*k)=usc(2) enddo if(mod(contablocchi,stepBut).eq.0) then call FilRun(AreaFad,alfain,alfanew) endif --- CANALE DELL'UTENTE UTILE
--- do nant=1,Na index1=1+2*Nutenti*(nant-1) H(nant)=H(nant)+(cmplx(alfanew(index1), & alfanew(index1+1)))/dimeWH do k=1,Nutenti index=2*k-1+2*Nutenti*(nant-1) alpha(nant,k)=cmplx(alfanew(index), & alfanew(index+1)) if(gauss.eq.'SI') alpha(nant,k)= & cmplx(1.,0.) X(ljk,nant)=X(ljk,nant)+alpha(nant,k)* & simb(k)*matWH(ljk,k) enddo call Gaussgen(rum,dev,semerum) X(ljk,nant)=X(ljk,nant)+ & ni*cmplx(rum(1),rum(2)) enddo enddo do nant=1,Na potenza=potenza+(cabs(H(nant))**2-1) contapot=contapot+1 enddo
--- TRAINING DELLA STIMA DI CANALE
--- if(nblocchi.eq.0) then do nant=1,Na do k=1,Nutenti Hst(nant,k)=cmplx(0.,0.) enddo enddo do nant=1,Na do k=1,Nutenti somma(nant,k)=cmplx(0.,0.) potmed=(cabs(simb(k))**2) do ljk=1,dimeWH somma(nant,k)=somma(nant,k)+matWH(ljk,k) & *X(ljk,nant) enddo Hst(nant,k)=(1/potmed)*(conjg(simb(k))) & *somma(nant,k) enddo enddo --- RIVELAZIONE CON CANALE NOTO
--- stat=cmplx(0.,0.) do nant=1,Na z(nant)=cmplx(0.,0.) do ljk=1,dimeWH z(nant)=z(nant)+X(ljk,nant)*matWH(ljk,1) enddo alpha_v=H(nant) if(gauss.eq.'SI') alpha_v=cmplx(1.,0.) stat=stat+conjg(alpha_v)*z(nant) enddo --- RIVELAZIONE CON CANALE STIMATO
--- do k=1,Nutenti
stat_st(k)=cmplx(0.,0.) enddo
do k=1,Nutenti z_st(nant,k)=cmplx(0.,0.) do ljk=1,dimeWH z_st(nant,k)=z_st(nant,k)+X(ljk,nant) & *matWH(ljk,k) enddo alpha_st(nant,k)=Hst(nant,k) if(gauss.eq.'SI') alpha_st(nant,k)= & cmplx(1.,0.) stat_st(k)=stat_st(k)+conjg & (alpha_st(nant,k))*z_st(nant,k) enddo enddo
call Decisore (stat,deciso1,deciso2) if(deciso1.ne.u1(1)) contaerr= contaerr+1 if(deciso2.ne.u2(1)) contaerr= contaerr+1 do k=1,Nutenti
call Decisore (stat_st,deciso1_st(k), & deciso2_st(k))
if(deciso1_st(k).ne.u1(1))
& contaerr_st= contaerr_st+1 if(deciso2_st(k).ne.u2(1)) & contaerr_st=contaerr_st+1 call graymap(deciso1_st(k), & deciso2_st(k),simb_st(k)) enddo call LMS(Na,Nutenti,dimeWH,matWH,X, & Hst,mu,nblocchi,simb_st) contadec=contadec+2 if(contaerr.ge.nlimit) goto 200 --- FILE MONITOR 1 --- 100 if((mod(mmm,100).eq.0).and.(ii.eq.1)) then open(20,file=filemonitor,err=99) write(20,*) write(20,*) 'FILEMONITOR' write(20,*) write(20,*) 'Eb/Noiniziale=',ebsun0dBin, & ' ', 'Eb/Nofinale=', & ebsun0dBfin
write(20,*)
write(20,*) 'Eb/No=',ebsun0dB write(20,*)
write(20,*) 'potenza canale', & potenza/contapot+1 write(20,*)
write(20,*) 'Nutenti=',Nutenti write(20,*)
write(20,*) 'N trame:',' ',NumTrame write(20,*)
write(20,*) 'N trame esaminate:',' ',mmm write(20,*) if(contaerr.ne.0) then write(20,*) 'P(e):', & Log10(real(contaerr)/contadec) else write(20,*) 'P(e):-INF' endif write(20,*) if(contaerr_st.ne.0) then write(20,*) 'P(e):', & Log10(real(contaerr_st)/contadec) else write(20,*) 'P(e):-INF' endif 99 close(20) endif
enddo !FINE blocchi di blocchi enddo !FINE TRAME
200 asc(mm+1)=ebsun0dB ord_id(mm+1)=log10(real(contaerr)/contadec) ord(mm+1)=log10(real(contaerr_st/k)/contadec) open(30,file=fileout,access='append') write(30,*) write(30,*) asc(mm+1) write(30,*) ord(mm+1) close(30) enddo !FINE SNR call grf2update(0) call grf2block(1,asc,ord_id,Npunti+1,'Pe_can_vero',0) call grf2block(2,asc,ord,Npunti+1,'Pe_LMS',0)
end
--- SUBROUTINE WALSH
--- SUBROUTINE walsh(rig, col, w_h)
implicit none
integer*4 rig, col, w_h, x(0:8), y(0:8), espo, & i, j,usc, c,k i = rig j = col c = 0 espo = 0 do c = 0,8 x(c) = mod(i, 2) i = i / 2 y(c) = mod(j, 2) j = j / 2
espo = espo + (x(c) * y(c)) enddo usc = 1 if(espo.ne.0) then do k = 0, (espo-1), 1 usc = -usc enddo endif w_h = usc return end --- SUBROUTINE GRAYMAP --- SUBROUTINE graymap(b1,b2,simbo) implicit none integer*4 b1,b2 complex*8 simbo if((b1.eq.0).and.(b2.eq.0)) simbo=(1.,0.) if((b1.eq.0).and.(b2.eq.1)) simbo=(0.,1.) if((b1.eq.1).and.(b2.eq.1)) simbo=(-1.,0.)
if((b1.eq.1).and.(b2.eq.0)) simbo=(0.,-1.) return end --- SUBROUTINE SYMB_GRAY --- SUBROUTINE symb_gray(simbolo,u1,u2,semesig) implicit none integer*4 u1,u2,semesig complex*8 simbolo call UNI_SymbGen(u1,1,2,semesig) call UNI_SymbGen(u2,1,2,semesig) call graymap(u1,u2,simbolo) return end --- SUBROUTINE DECISORE --- SUBROUTINE decisore(x,dec1,dec2) implicit none integer*4 dec,dec1,dec2 real*4 fi,fi1,pi complex*8 x pi=3.141592653589793 fi1=180*(atan2(aimag(x),real(x)))/pi fi=fi1 dec=2 if(abs(fi).lt.45) dec=0 fi=fi1-90 if(abs(fi).lt.45) dec=1 fi=fi1+90 if(abs(fi).lt.45) dec=3 if(dec.eq.0) then dec1=0 dec2=0 endif if(dec.eq.1) then dec1=0 dec2=1 endif
if(dec.eq.2) then dec1=1 dec2=1 endif if(dec.eq.3) then dec1=1 dec2=0 endif return end --- SUBROUTINE STIMA DI CANALE
--- SUBROUTINE LMS(Na,Nutenti,dimeWH,matWH,X,Hst, & mu,nblocchi,simb_st) implicit none integer*4 nant,k,ljk,Na,Nutenti,dimeWH,nblocchi,ind real*4 mu,matWH(256,256) complex*8 X(20,20),Hst(20,32),simb_st(32), & somma(20,32) do nant=1,Na do k=1,Nutenti somma(nant,k)=cmplx(0.,0.) do ljk=1,dimeWH somma(nant,k)=somma(nant,k)+matWH(ljk,k) & *X(ljk,nant) enddo Hst(nant,k)=(1-mu)*Hst(nant,k)+mu* & conjg(simb_st(k))*somma(nant,k) enddo enddo end
III.
Calcolo della probabilità di errore con canale lentamente
variabile tramite il rivelatore MRC, stima di canale RLS, al variare
del SNR
Riportiamo il corpo principale del programma e di seguito le subroutine implementate.
program RLS implicit none character*60 filein,filemonitor,fileout character*5 Gauss integer*4 Nlev,semerum,semesig,semetaps,Npunti, & j,mm,Nutenti,Numblock,N,Ntap,ljk,k, & nlimit,i,u1(32),u2(32),m,dimeWH,indl, & contadec,indice1,indice2,contaerr,np, & ni,ii,wh,Niter,mmm,stepBut,deciso1, & deciso2,Nmedia,index1,index,nant,transit, & contapot,Na,nblocchi,contaerr_st, & contablocchi,NumTrame,ind,npassi, & deciso1_st(32),deciso2_st(32) Real*4 AREAFAD(513) real*4 ebsun0dBin,ebsun0dBfin,ebsun0dB,ebsun0, & dev,usc(2),devtap,pi,asc(100),mu,lambda, & rho,rolloff,AreaCh2(10000),BER,BN,Bd, & rho_max,essun0,Qfun,potmed,potenza, & b,a(20,32),,alfanew(100),alfain(100), & ord_id(100),pip,rum(2),ord(100), & matWH(256,256) complex*8 X(20,20),simb(32),H(20),stat,z_st(20,32), & simb_st(32),alpha(20,32),somma(20,32), & Hst(20,32),z(20),alpha_st,stat_st(32), & alpha_v parameter(pi=3.141592653589793) filein='stima_RLS.in' filemonitor='stima_RLS.mon' fileout='stima_RLS.out' open(10,file=filein) read(10,*) read(10,*) gauss read(10,*) read(10,*) ni
read(10,*) read(10,*) Nlev read(10,*) read(10,*) semesig read(10,*) read(10,*) semerum read(10,*) read(10,*) semetaps read(10,*) read(10,*) ebsun0dBin read(10,*) read(10,*) ebsun0dBfin read(10,*) read(10,*) Npunti read(10,*) read(10,*) NumTrame read(10,*) read(10,*) Numblock read(10,*) read(10,*) Na read(10,*) read(10,*) dimeWH read(10,*) read(10,*) Nutenti read(10,*) read(10,*) nlimit read(10,*) read(10,*) Bd read(10,*) read(10,*) np read(10,*) read(10,*) stepBut read(10,*) read(10,*) lambda read(10,*) read(10,*) rho_max npassi=0. npassi=nint((log(rho_max+lambda-1)-log(rho_max)) & /log(lambda)) close(10)
--- PARAMETRI FILTRO PASSA-BASSO PER FADING
--- Bd=Bd*stepBut pip=pi/(2.*np) BN=Bd*pip/sin(pip) devtap=0.5*sqrt(1/BN) transit=5*nint(1/Bd) contapot=0 --- GENERAZIONE SEQUENZE DI SPREADING
--- do k=1,dimeWH do ljk=1,dimeWH call walsh(k-1,ljk-1,wh) matWH(ljk,k)=wh/sqrt(real(dimeWH)) enddo enddo --- INIZIO CICLO SU SNR --- do mm=0,Npunti ebsun0dB=ebsun0dBin+mm*(ebsun0dBfin- & ebsun0dBin)/Npunti ebsun0=10**(0.1*ebsun0dB) essun0=ebsun0*nint((Log10(real(Nlev)))/Log10(2.)) dev=sqrt(0.5/essun0) --- INIZIALIZZAZIONE COSTANTI --- contadec=0 potenza=0. contaerr=0 contaerr_st=0 contablocchi=-1 contapot=0 do nant=1,Na do k=1,Nutenti a(nant,k)=0 enddo enddo
--- CICLO SUL NUMERO DI TRAME
--- do mmm=1,NumTrame
--- DEFINIZIONE FILTRO DI BUTTERWORTH PER IL FADING
--- call ButDef(AreaFad,2*Na*Nutenti,Np,0.,Bd,1.)
c? ButDef(AreaFad,100,4,0.,Bd,1.)
--- TRANSITORIO INIZIALE PER IL FILTRO DI BUTTERWORTH
--- do i=1,transit do j=1,Na*Nutenti call Gaussgen(usc,devtap,semetaps) alfain(2*j-1)=usc(1) alfain(2*j)=usc(2) enddo call FilRun(AreaFad,alfain,alfanew) enddo --- CICLO SUL NUMERO DI BLOCCHI DI BLOCCHI
--- nblocchi=-1
do ii=1,Numblock
nblocchi=nblocchi+1
--- GENERAZIONE BIT UTENTI
--- do k=1,Nutenti call symb_gray(simb(k),u1(k),u2(k),semesig) enddo --- INIZIALIZZAZIONE VARIABILI --- do ljk=1,dimeWH do nant=1,Na X(ljk,nant)=cmplx(0.,0.) enddo enddo do nant=1,Na
H(nant)=cmplx(0.,0.) enddo
--- GENERAZIONE DEL SEGNALE RICEVUTO
--- do ljk=1,dimeWH contablocchi=contablocchi+1 do k=1,Na*Nutenti call Gaussgen(usc,devtap,semetaps) alfain(2*k-1)=usc(1) alfain(2*k)=usc(2) enddo if(mod(contablocchi,stepBut).eq.0) then call FilRun(AreaFad,alfain,alfanew) endif --- CANALE DELL'UTENTE UTILE
--- do nant=1,Na index1=1+2*Nutenti*(nant-1) H(nant)=H(nant)+(cmplx(alfanew(index1), & alfanew(index1+1)))/dimeWH do k=1,Nutenti index=2*k-1+2*Nutenti*(nant-1) alpha(nant,k)=cmplx(alfanew(index), & alfanew(index+1)) if(gauss.eq.'SI')alpha(nant,k)= & cmplx(1.,0.) X(ljk,nant)=X(ljk,nant)+alpha(nant,k)* & simb(k)*matWH(ljk,k) enddo call Gaussgen(rum,dev,semerum) X(ljk,nant)=X(ljk,nant)+ni*cmplx(rum(1), & rum(2)) enddo enddo do nant=1,Na potenza=potenza+(cabs(H(nant))**2-1) contapot=contapot+1 enddo
--- TRAINING DELLA STIMA DI CANALE
--- if(nblocchi.eq.0) then mu=1 do nant=1,Na do k=1,Nutenti Hst(nant,k)=cmplx(0.,0.) enddo enddo do nant=1,Na do k=1,Nutenti somma(nant,k)=cmplx(0.,0.) potmed=(cabs(simb(k))**2) do ljk=1,dimeWH somma(nant,k)=somma(nant,k)+matWH(ljk,k) & *X(ljk,nant) enddo Hst(nant,k)=(1/potmed)*(conjg(simb(k))) & *somma(nant,k) enddo enddo goto 100 endif --- RIVELAZIONE CON CANALE NOTO
--- stat=cmplx(0.,0.) do nant=1,Na z(nant)=cmplx(0.,0.) do ljk=1,dimeWH z(nant)=z(nant)+X(ljk,nant)*matWH(ljk,1) enddo alpha_v=H(nant) if(gauss.eq.'SI') alpha_v=cmplx(1.,0.) stat=stat+conjg(alpha_v)*z(nant) enddo --- RIVELAZIONE CON CANALE STIMATO
--- do k=1,Nutenti
stat_st(k)=cmplx(0.,0.) enddo do nant=1,Na do k=1,Nutenti z_st(nant,k)=cmplx(0.,0.) do ljk=1,dimeWH z_st(nant,k)=z_st(nant,k)+X(ljk,nant) & *matWH(ljk,k) enddo alpha_st=Hst(nant,k) if(gauss.eq.'SI') alpha_st=cmplx(1.,0.) stat_st(k)=stat_st(k)+conjg(alpha_st) & *z_st(nant,k) enddo enddo
call Decisore (stat,deciso1,deciso2) if(deciso1.ne.u1(1)) contaerr= contaerr+1 if(deciso2.ne.u2(1)) contaerr= contaerr+1 do k=1,Nutenti
call Decisore (stat_st,deciso1_st(k), & deciso2_st(k)) if(deciso1_st(k).ne.u1(1)) contaerr_st= & contaerr_st+1 if(deciso2_st(k).ne.u2(1)) contaerr_st= & contaerr_st+1 call graymap(deciso1_st(k),deciso2_st(k), & simb_st(k)) enddo call RLS(Na,Nutenti,DimeWH,matWH,X,Hst, & lambda,npassi,mu,nblocchi,simb_st) contadec=contadec+2 if(contaerr.ge.nlimit) goto 200 --- FILE MONITOR 1 --- 100 if((mod(mmm,100).eq.0).and.(ii.eq.1)) then open(20,file=filemonitor,err=99) write(20,*) write(20,*) 'FILEMONITOR' write(20,*) write(20,*)'Eb/Noiniziale=',ebsun0dBin,
& ' ','Eb/Nofinale=',ebsun0dBfin write(20,*)
write(20,*) 'Eb/No=',ebsun0dB write(20,*)
write(20,*) 'potenza canale', & potenza/contapot+1 write(20,*)
write(20,*) 'Nutenti=',Nutenti write(20,*)
write(20,*) 'N trame:',' ',NumTrame write(20,*)
write(20,*) 'N trame esaminate:',' ',mmm write(20,*) if(contaerr.ne.0) then write(20,*) 'P(e):', & Log10(real(contaerr)/contadec) else write(20,*) 'P(e):-INF' endif write(20,*) if(contaerr_st.ne.0) then write(20,*) 'P(e):', & Log10(real(contaerr_st)/contadec) else write(20,*) 'P(e):-INF' endif 99 close(20) endif
enddo !FINE BLOCCHI DI BLOCCHI enddo !FINE TRAME
do nant=1,Na do k=1,Nutenti a(nant,k)=a(nant,k)/Numtrame enddo enddo 200 asc(mm+1)=ebsun0dB ord_id(mm+1)=log10(real(contaerr)/contadec) ord(mm+1)=log10(real(contaerr_st/k)/contadec) open(30,file=fileout,access='append') write(30,*) write(30,*) asc(mm+1)
write(30,*) ord(mm+1) close(30) enddo !FINE SNR call grf2update(0) call grf2block(1,asc,ord_id,Npunti+1,'Pe_can_vero',0) call grf2block(2,asc,ord,Npunti+1,'Pe_RLS',0) end --- SUBROUTINE WALSH --- SUBROUTINE walsh(rig, col, w_h)
implicit none
integer*4 rig, col, w_h, x(0:8), y(0:8), espo, & i, j,usc, c,k i = rig j = col c = 0 espo = 0 do c = 0,8 x(c) = mod(i, 2) i = i / 2 y(c) = mod(j, 2) j = j / 2
espo = espo + (x(c) * y(c)) enddo usc = 1 if(espo.ne.0) then do k = 0, (espo-1), 1 usc = -usc enddo endif w_h = usc return end
--- SUBROUTINE GRAYMAP --- SUBROUTINE graymap(b1,b2,simbo) implicit none integer*4 b1,b2 complex*8 simbo if((b1.eq.0).and.(b2.eq.0)) simbo=(1.,0.) if((b1.eq.0).and.(b2.eq.1)) simbo=(0.,1.) if((b1.eq.1).and.(b2.eq.1)) simbo=(-1.,0.) if((b1.eq.1).and.(b2.eq.0)) simbo=(0.,-1.) return end --- SUBROUTINE SYMB_GRAY --- SUBROUTINE symb_gray(simbolo,u1,u2,semesig) implicit none integer*4 u1,u2,semesig complex*8 simbolo call UNI_SymbGen(u1,1,2,semesig) call UNI_SymbGen(u2,1,2,semesig) call graymap(u1,u2,simbolo) return end --- SUBROUTINE DECISORE --- SUBROUTINE decisore(x,dec1,dec2) implicit none integer*4 dec,dec1,dec2 real*4 fi,fi1,pi complex*8 x pi=3.141592653589793 fi1=180*(atan2(aimag(x),real(x)))/pi fi=fi1 dec=2 if(abs(fi).lt.45) dec=0 fi=fi1-90
if(abs(fi).lt.45) dec=1 fi=fi1+90 if(abs(fi).lt.45) dec=3 if(dec.eq.0) then dec1=0 dec2=0 endif if(dec.eq.1) then dec1=0 dec2=1 endif if(dec.eq.2) then dec1=1 dec2=1 endif if(dec.eq.3) then dec1=1 dec2=0 endif return end --- SUBROUTINE STIMA DI CANALE
--- SUBROUTINE RLS(Na,Nutenti,DimeWH,matWH,X,Hst, & lambda,npassi,mu,nblocchi,simb_st) implicit none integer*4 nant,k,ljk,Na,Nutenti,DimeWH,nblocchi real*4 rho,matWH(256,256),lambda,npassi,mu complex*8 X(20,20),Hst(20,32),simb(32),somma(20,32), & simb_st(32) rho=0. mu=mu/(lambda+mu) if (nblocchi.le.npassi) then rho=1-lambda else rho=mu endif do nant=1,Na do k=1,Nutenti
somma(nant,k)=cmplx(0.,0.) do ljk=1,dimeWH somma(nant,k)=somma(nant,k)+matWH(ljk,k) & *X(ljk,nant) enddo Hst(nant,k)=(1-rho)*Hst(nant,k)+rho* & conjg(simb_st(k))*somma(nant,k) enddo enddo end