Skip to content

Commit

Permalink
'Refactored by Sourcery'
Browse files Browse the repository at this point in the history
  • Loading branch information
Sourcery AI committed Nov 1, 2022
1 parent 2f5f21a commit 1ccbdf8
Show file tree
Hide file tree
Showing 9 changed files with 188 additions and 205 deletions.
66 changes: 32 additions & 34 deletions jupyter notebooks/CommpyTest_BERvsEbN0_wPulseShaping.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,38 +68,38 @@ def GrayMapping(M, constType):

L = int(np.sqrt(M)-1)
bitsSymb = int(np.log2(M))

code = GrayCode(bitsSymb)
a = list(code.generate_gray())

if constType == 'qam':
PAM = np.arange(-L, L+1, 2)
PAM = np.array([PAM])

# generate complex square M-QAM constellation
const = repmat(PAM, L+1, 1) + 1j*repmat(np.flip(PAM.T,0), 1, L+1)
const = const.T

for ind in np.arange(1,L+1,2):
const[ind] = np.flip(const[ind],0)

elif constType == 'psk':
pskPhases = np.arange(0,2*np.pi,2*np.pi/M)

# generate complex M-PSK constellation
const = np.exp(1j*pskPhases)

const = const.reshape(M,1)
const_ = np.zeros((M,2),dtype=complex)


for ind in range(0,M):

for ind in range(M):
const_[ind,0] = const[ind,0] # complex constellation symbol
const_[ind,1] = int(a[ind],2) # mapped bit sequence (as integer decimal)

# sort complex symbols column according to their mapped bit sequence (as integer decimal)
const = const_[const_[:,1].real.argsort()]

return const


Expand All @@ -121,12 +121,10 @@ def modulateGray(bits, M, constType):
def demodulateGray(symb, M ,constType):

const = GrayMapping(M, constType)

hdDecision_vec = np.vectorize(hdDecision, excluded = [1])
index_list = hdDecision_vec(symb, const[:,0])
demod_bits = dec2bitarray(index_list, int(np.log2(M)))

return demod_bits

hdDecision_vec = np.vectorize(hdDecision, excluded = [1])
index_list = hdDecision_vec(symb, const[:,0])
return dec2bitarray(index_list, int(np.log2(M)))

def pulseShape(pulseType, SpS=2, N=1024, alpha=0.1, Ts=1):

Expand Down Expand Up @@ -158,7 +156,7 @@ def pulseShape(pulseType, SpS=2, N=1024, alpha=0.1, Ts=1):
alpha = 0.05 # Rolloff do filtro RRC
N = 1024 # Número de coeficientes do filtro RRC
EbN0dB = 20

# generate random bits
bitsTx = np.random.randint(2, size=3*2**12)

Expand All @@ -176,7 +174,7 @@ def pulseShape(pulseType, SpS=2, N=1024, alpha=0.1, Ts=1):
# pulse shaping
#pulseFilter = pulseShape('rrc', SpS, N, alpha, Ts)
tindex, rrcFilter = rrcosfilter(N, alpha, Ts, Fa)
sigTx = filterNoDelay(pulseFilter, symbolsUp)
sigTx = filterNoDelay(pulseFilter, symbolsUp)
sigTx = sigTx/np.sqrt(signal_power(sigTx))

# plot eye diagrams
Expand Down Expand Up @@ -211,7 +209,7 @@ def pulseShape(pulseType, SpS=2, N=1024, alpha=0.1, Ts=1):

# +
# matched filter
sigRx = filterNoDelay(rrcFilter, sigRx)
sigRx = filterNoDelay(rrcFilter, sigRx)
sigRx = sigRx/SpS

# plot eye diagrams
Expand Down Expand Up @@ -240,7 +238,7 @@ def pulseShape(pulseType, SpS=2, N=1024, alpha=0.1, Ts=1):
BERtheory = theoryBER(M, EbN0dB,'qam')

# print results
print('EbN0: %3.2f dB, EbN0_est: %3.2f dB,\nBERtheory: %3.1e, BER: %3.1e ' %(EbN0dB, EbN0dB_est, BERtheory, BER))
print('EbN0: %3.2f dB, EbN0_est: %3.2f dB,\nBERtheory: %3.1e, BER: %3.1e ' %(EbN0dB, EbN0dB_est, BERtheory, BER))
print('Total of bits counted: ', ERR.size)

# plot constellations
Expand Down Expand Up @@ -268,29 +266,30 @@ def pulseShape(pulseType, SpS=2, N=1024, alpha=0.1, Ts=1):
BER = np.zeros(EbN0dB_.shape)
EbN0dB_est = np.zeros(EbN0dB_.shape)

discard = 100
for indSNR in range(EbN0dB_.size):

EbN0dB = EbN0dB_[indSNR]

# generate random bits
bitsTx = np.random.randint(2, size=3*2**18)

# map bits to constellation symbols
mod = QAMModem(m=M)
symbTx = mod.modulate(bitsTx)
Es = mod.Es;

# Normalize symbols energy to 1
symbTx = symbTx/np.sqrt(Es)

# Aumenta a taxa de amostragem do sinal para SpS amostras/símbolo
symbolsUp = upsample(symbTx, SpS)

# filtro formatador de pulso
tindex, rrcFilter = rrcosfilter(N, alpha, Ts, Fa)
symbolsUp = filterNoDelay(rrcFilter, symbolsUp)
symbolsUp = filterNoDelay(rrcFilter, symbolsUp)
symbolsUp = symbolsUp/np.sqrt(signal_power(symbolsUp))

# AWGN channel
snrdB = EbN0dB + 10*np.log10(np.log2(M))
noiseVar = 1/(10**(snrdB/10))
Expand All @@ -300,24 +299,23 @@ def pulseShape(pulseType, SpS=2, N=1024, alpha=0.1, Ts=1):
noise = 1/np.sqrt(2)*noise

symbRx = symbolsUp + noise

# filtro casado
symbRx = filterNoDelay(rrcFilter, symbRx)
symbRx = filterNoDelay(rrcFilter, symbRx)
symbRx = symbRx/SpS

# Decimação para uma amostra por símbolo
symbRx = symbRx[0::SpS]

# Demodulate received symbols
bitsRx = mod.demodulate(np.sqrt(Es)*symbRx, demod_type = 'hard')
discard = 100
bitsRx = mod.demodulate(np.sqrt(Es)*symbRx, demod_type = 'hard')
numBits = bitsTx.size;

# BER calculation, EbN0 estimation
ERR = np.logical_xor(bitsRx[discard:numBits-discard], bitsTx[discard:numBits-discard])
BER[indSNR] = ERR.sum()/ERR.size
EbN0dB_est[indSNR] = 10*np.log10(1/(signal_power(symbRx-symbTx)*np.log2(M)))

print('EbN0: %3.2f dB, EbN0_est: %3.2f dB, BER: %3.1e ' %(EbN0dB, EbN0dB_est[indSNR], BER[indSNR]))


Expand Down
4 changes: 2 additions & 2 deletions jupyter notebooks/Detecção de sinais ópticos e ruído.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,11 @@
σ2_s = 2*q*(Ip + Id)*B # variância
μ = 0 # média

σ = np.sqrt(σ2_s)
σ = np.sqrt(σ2_s)
Is = normal(μ, σ, Namostras)

# plotas as primeiras 1000 amostras
plt.plot(Is[0:1000],linewidth = 0.8);
plt.plot(Is[:1000], linewidth = 0.8);
plt.xlim(0,1000)
plt.ylabel('Is')
plt.xlabel('amostra')
Expand Down
4 changes: 1 addition & 3 deletions jupyter notebooks/Geração de sinais ópticos.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,9 +301,7 @@ def mzm(Ai, Vπ, u, Vb):
:return Ao: amplitude da portadora modulada
"""
π = np.pi
Ao = Ai*np.cos(0.5/*(u+Vb)*π)

return Ao
return Ai*np.cos(0.5/*(u+Vb)*π)


# ### Transmitindo informação na intensidade (potência) da portadora óptica
Expand Down
28 changes: 12 additions & 16 deletions jupyter notebooks/Sistemas coerentes.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,17 +298,15 @@ def hybrid_2x4_90(E1, E2):

M = Matrix([[C_3dB, zeros(2)],
[zeros(2), C_3dB]])

U = Matrix([[1, 0, 0, 0],
[0, 0, 1, 0],
[0, 1, 0, 0],
[0, 0, 0, j]])

Ei = Matrix([[E1],[0],[0],[E2]]) # vetor 4x1

Eo = M*U*M*Ei

return Eo

return M*U*M*Ei

# fotodetector balanceado
def bpd(E1, E2, R=1):
Expand Down Expand Up @@ -406,19 +404,17 @@ def hybrid_2x4_90deg(E1, E2):
:return: hybrid outputs
'''
assert E1.size == E2.size, 'E1 and E2 need to have the same size'

# optical hybrid transfer matrix
T = np.array([[ 1/2, 1j/2, 1j/2, -1/2],
[ 1j/2, -1/2, 1/2, 1j/2],
[ 1j/2, 1/2, -1j/2, -1/2],
[-1/2, 1j/2, -1/2, 1j/2]])

Ei = np.array([E1, np.zeros((E1.size,)),
np.zeros((E1.size,)), E2])

Eo = T@Ei

return Eo

return T@Ei

def coherentReceiver(Es, Elo, Rd=1):
'''
Expand Down Expand Up @@ -447,12 +443,12 @@ def coherentReceiver(Es, Elo, Rd=1):

def phaseNoise(lw, Nsamples, Ts):

σ2 = 2*np.pi*lw*Ts
σ2 = 2*np.pi*lw*Ts
phi = np.zeros(Nsamples)
for ind in range(0, Nsamples-1):

for ind in range(Nsamples-1):
phi[ind+1] = phi[ind] + normal(0, np.sqrt(σ2))

return phi


Expand Down
Loading

0 comments on commit 1ccbdf8

Please sign in to comment.