Skip to content

Commit 9cc623b

Browse files
authored
Update README.md
1 parent 5446b07 commit 9cc623b

File tree

1 file changed

+71
-2
lines changed

1 file changed

+71
-2
lines changed

commpy/channelcoding/README.md

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ The main idea of the channel codes can be formulated as following thesises:
77
- **redundant bits** are added for *error detection* and *error correction*;
88
- some special algorithms (<u>coding schemes</u>) are used for this.
99

10-
![](https://raw.githubusercontent.com/kirlf/CSP/master/FEC/assets/FECmainidea1.png)
10+
<img src="https://raw.githubusercontent.com/kirlf/CSP/master/FEC/assets/FECmainidea1.png" width="800" />
1111

1212
The fact how "further" a certain algorithm divides the code words among themselves, and determines how strongly it protects the signal from noise [1, p.23].
1313

14-
![](https://habrastorage.org/webt/n7/o4/bs/n7o4bsf7_htlv10gsatc-yojbrq.png)
14+
<img src="https://habrastorage.org/webt/n7/o4/bs/n7o4bsf7_htlv10gsatc-yojbrq.png" width="800" />
1515

1616
In the case of binary codes, the minimum distance between all existing code words is called **Hamming distance** and is usually denoted **dmin**:
1717

@@ -56,11 +56,18 @@ Main modeling routines:
5656
- decode
5757
- check the error correction
5858

59+
<img src="https://habrastorage.org/webt/v3/v5/w2/v3v5w2gbwk34nzk_2qt25baoebq.png" width="500"/>
60+
5961
```python
6062
import numpy as np
6163
import commpy.channelcoding.convcode as cc
6264
import commpy.modulation as modulation
6365

66+
def BER_calc(a, b):
67+
num_ber = np.sum(np.abs(a - b))
68+
ber = np.mean(np.abs(a - b))
69+
return int(num_ber), ber
70+
6471
N = 100000 #number of symbols per the frame
6572
message_bits = np.random.randint(0, 2, N) # message
6673

@@ -91,14 +98,76 @@ Viterbi decoder parameters:
9198
tb_depth = 5*(m.sum() + 1) # traceback depth
9299
```
93100

101+
Two oppitions of the Viterbi decoder will be tested:
102+
- *hard* (hard decision)
103+
- *unquatized* (soft decision)
104+
105+
Additionally, uncoded case will be considered.
106+
94107
Simulation loop:
95108

96109
```python
97110
EbNo = 5 # energy per bit to noise power spectral density ratio (in dB)
98111
snrdB = EbNo + 10*np.log10(k*rate) # Signal-to-Noise ratio (in dB)
99112
noiseVar = 10**(-snrdB/10) # noise variance (power)
100113

114+
N_c = 10 # number of trials
115+
116+
BER_soft = np.empty((N_c,))
117+
BER_hard = np.empty((N_c,))
118+
BER_uncoded = np.empty((N_c,))
119+
120+
for cntr in range(N_c):
121+
122+
message_bits = np.random.randint(0, 2, N) # message
123+
coded_bits = cc.conv_encode(message_bits, trellis) # encoding
124+
125+
modulated = modem.modulate(coded_bits) # modulation
126+
modulated_uncoded = modem.modulate(message_bits) # modulation (uncoded case)
127+
128+
Es = np.mean(np.abs(modulated)**2) # symbol energy
129+
No = Es/((10**(EbNo/10))*np.log2(M)) # noise spectrum density
130+
131+
noisy = modulated + np.sqrt(No/2)*\
132+
(np.random.randn(modulated.shape[0])+\
133+
1j*np.random.randn(modulated.shape[0])) # AWGN
134+
135+
noisy_uncoded = modulated_uncoded + np.sqrt(No/2)*\
136+
(np.random.randn(modulated_uncoded.shape[0])+\
137+
1j*np.random.randn(modulated_uncoded.shape[0])) # AWGN (uncoded case)
138+
139+
demodulated_soft = modem.demodulate(noisy, demod_type='soft', noise_var=noiseVar) # demodulation (soft output)
140+
demodulated_hard = modem.demodulate(noisy, demod_type='hard') # demodulation (hard output)
141+
demodulated_uncoded = modem.demodulate(noisy_uncoded, demod_type='hard') # demodulation (uncoded case)
101142

143+
decoded_soft = cc.viterbi_decode(demodulated_soft, trellis, tb_depth, decoding_type='unquantized') # decoding (soft decision)
144+
decoded_hard = cc.viterbi_decode(demodulated_hard, trellis, tb_depth, decoding_type='hard') # decoding (hard decision)
145+
146+
147+
NumErr, BER_soft[cntr] = BER_calc(message_bits, decoded_soft[:-(L-1)]) # bit-error ratio (soft decision)
148+
NumErr, BER_hard[cntr] = BER_calc(message_bits, decoded_hard[:-(L-1)]) # bit-error ratio (hard decision)
149+
NumErr, BER_uncoded[cntr] = BER_calc(message_bits, demodulated_uncoded) # bit-error ratio (uncoded case)
150+
151+
mean_BER_soft = np.mean(BER_soft) # averaged bit-error ratio (soft decision)
152+
mean_BER_hard = np.mean(BER_hard) # averaged bit-error ratio (hard decision)
153+
mean_BER_uncoded = np.mean(BER_uncoded) # averaged bit-error ratio (uncoded case)
154+
155+
print("Soft decision:\n"+str(mean_BER_soft)+"\n")
156+
print("Hard decision:\n"+str(mean_BER_hard)+"\n")
157+
print("Uncoded message:\n"+str(mean_BER_uncoded)+"\n")
158+
```
159+
160+
Outputs:
161+
162+
```python
163+
>>> Soft decision:
164+
>>> 0.0
165+
>>>
166+
>>> Hard decision:
167+
>>> 3.0000000000000004e-05
168+
>>>
169+
>>> Uncoded message:
170+
>>> 0.008782
102171
```
103172

104173
### Reference

0 commit comments

Comments
 (0)