mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-26 14:18:38 -05:00
9ae479e9d9
2. osd codeword selected based on correlation discrepancy instead of Hamming dist (improves sensitivity) 3. trap zero-valued spectrum values caused by large dt. 4. trap all-zero codeword 4. both decoders return number of hard errors 5. osd174 returns correlation discrepancy (rejection threshold still needs to be tuned). 6. both decoders return the codeword with bits in as-transmitted order, for subtraction. git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@7735 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
402 lines
11 KiB
Fortran
402 lines
11 KiB
Fortran
subroutine bpdecode174(llr,apmask,maxiterations,decoded,cw,nharderror)
|
|
!
|
|
! A log-domain belief propagation decoder for the (174,87) code.
|
|
!
|
|
integer, parameter:: N=174, K=87, M=N-K
|
|
integer*1 codeword(N),cw(N),apmask(N)
|
|
integer colorder(N)
|
|
integer*1 decoded(K)
|
|
integer Nm(7,M) ! 5, 6, or 7 bits per check
|
|
integer Mn(3,N) ! 3 checks per bit
|
|
integer synd(M)
|
|
real tov(3,N)
|
|
real toc(7,M)
|
|
real tanhtoc(7,M)
|
|
real zn(N)
|
|
real llr(N)
|
|
real Tmn
|
|
integer nrw(M)
|
|
|
|
data colorder/ &
|
|
0, 1, 2, 3, 30, 4, 5, 6, 7, 8, 9, 10, 11, 32, 12, 40, 13, 14, 15, 16,&
|
|
17, 18, 37, 45, 29, 19, 20, 21, 41, 22, 42, 31, 33, 34, 44, 35, 47, 51, 50, 43,&
|
|
36, 52, 63, 46, 25, 55, 27, 24, 23, 53, 39, 49, 59, 38, 48, 61, 60, 57, 28, 62,&
|
|
56, 58, 65, 66, 26, 70, 64, 69, 68, 67, 74, 71, 54, 76, 72, 75, 78, 77, 80, 79,&
|
|
73, 83, 84, 81, 82, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,&
|
|
100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,&
|
|
120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,&
|
|
140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,&
|
|
160,161,162,163,164,165,166,167,168,169,170,171,172,173/
|
|
|
|
data Mn/ &
|
|
1, 25, 69, &
|
|
2, 5, 73, &
|
|
3, 32, 68, &
|
|
4, 51, 61, &
|
|
6, 63, 70, &
|
|
7, 33, 79, &
|
|
8, 50, 86, &
|
|
9, 37, 43, &
|
|
10, 41, 65, &
|
|
11, 14, 64, &
|
|
12, 75, 77, &
|
|
13, 23, 81, &
|
|
15, 16, 82, &
|
|
17, 56, 66, &
|
|
18, 53, 60, &
|
|
19, 31, 52, &
|
|
20, 67, 84, &
|
|
21, 29, 72, &
|
|
22, 24, 44, &
|
|
26, 35, 76, &
|
|
27, 36, 38, &
|
|
28, 40, 42, &
|
|
30, 54, 55, &
|
|
34, 49, 87, &
|
|
39, 57, 58, &
|
|
45, 74, 83, &
|
|
46, 62, 80, &
|
|
47, 48, 85, &
|
|
59, 71, 78, &
|
|
1, 50, 53, &
|
|
2, 47, 84, &
|
|
3, 25, 79, &
|
|
4, 6, 14, &
|
|
5, 7, 80, &
|
|
8, 34, 55, &
|
|
9, 36, 69, &
|
|
10, 43, 83, &
|
|
11, 23, 74, &
|
|
12, 17, 44, &
|
|
13, 57, 76, &
|
|
15, 27, 56, &
|
|
16, 28, 29, &
|
|
18, 19, 59, &
|
|
20, 40, 63, &
|
|
21, 35, 52, &
|
|
22, 54, 64, &
|
|
24, 62, 78, &
|
|
26, 32, 77, &
|
|
30, 72, 85, &
|
|
31, 65, 87, &
|
|
33, 39, 51, &
|
|
37, 48, 75, &
|
|
38, 70, 71, &
|
|
41, 42, 68, &
|
|
45, 67, 86, &
|
|
46, 81, 82, &
|
|
49, 66, 73, &
|
|
58, 60, 66, &
|
|
61, 65, 85, &
|
|
1, 14, 21, &
|
|
2, 13, 59, &
|
|
3, 67, 82, &
|
|
4, 32, 73, &
|
|
5, 36, 54, &
|
|
6, 43, 46, &
|
|
7, 28, 75, &
|
|
8, 33, 71, &
|
|
9, 49, 76, &
|
|
10, 58, 64, &
|
|
11, 48, 68, &
|
|
12, 19, 45, &
|
|
15, 50, 61, &
|
|
16, 22, 26, &
|
|
17, 72, 80, &
|
|
18, 40, 55, &
|
|
20, 35, 51, &
|
|
23, 25, 34, &
|
|
24, 63, 87, &
|
|
27, 39, 74, &
|
|
29, 78, 83, &
|
|
30, 70, 77, &
|
|
31, 69, 84, &
|
|
22, 37, 86, &
|
|
38, 41, 81, &
|
|
42, 44, 57, &
|
|
47, 53, 62, &
|
|
52, 56, 79, &
|
|
60, 75, 81, &
|
|
1, 39, 77, &
|
|
2, 16, 41, &
|
|
3, 31, 54, &
|
|
4, 36, 78, &
|
|
5, 45, 65, &
|
|
6, 57, 85, &
|
|
7, 14, 49, &
|
|
8, 21, 46, &
|
|
9, 15, 72, &
|
|
10, 20, 62, &
|
|
11, 17, 71, &
|
|
12, 34, 47, &
|
|
13, 68, 86, &
|
|
18, 23, 43, &
|
|
19, 64, 73, &
|
|
24, 48, 79, &
|
|
25, 70, 83, &
|
|
26, 80, 87, &
|
|
27, 32, 40, &
|
|
28, 56, 69, &
|
|
29, 63, 66, &
|
|
30, 42, 50, &
|
|
33, 37, 82, &
|
|
35, 60, 74, &
|
|
38, 55, 84, &
|
|
44, 52, 61, &
|
|
51, 53, 72, &
|
|
58, 59, 67, &
|
|
47, 56, 76, &
|
|
1, 19, 37, &
|
|
2, 61, 75, &
|
|
3, 8, 66, &
|
|
4, 60, 84, &
|
|
5, 34, 39, &
|
|
6, 26, 53, &
|
|
7, 32, 57, &
|
|
9, 52, 67, &
|
|
10, 12, 15, &
|
|
11, 51, 69, &
|
|
13, 14, 65, &
|
|
16, 31, 43, &
|
|
17, 20, 36, &
|
|
18, 80, 86, &
|
|
21, 48, 59, &
|
|
22, 40, 46, &
|
|
23, 33, 62, &
|
|
24, 30, 74, &
|
|
25, 42, 64, &
|
|
27, 49, 85, &
|
|
28, 38, 73, &
|
|
29, 44, 81, &
|
|
35, 68, 70, &
|
|
41, 63, 76, &
|
|
45, 49, 71, &
|
|
50, 58, 87, &
|
|
48, 54, 83, &
|
|
13, 55, 79, &
|
|
77, 78, 82, &
|
|
1, 2, 24, &
|
|
3, 6, 75, &
|
|
4, 56, 87, &
|
|
5, 44, 53, &
|
|
7, 50, 83, &
|
|
8, 10, 28, &
|
|
9, 55, 62, &
|
|
11, 29, 67, &
|
|
12, 33, 40, &
|
|
14, 16, 20, &
|
|
15, 35, 73, &
|
|
17, 31, 39, &
|
|
18, 36, 57, &
|
|
19, 46, 76, &
|
|
21, 42, 84, &
|
|
22, 34, 59, &
|
|
23, 26, 61, &
|
|
25, 60, 65, &
|
|
27, 64, 80, &
|
|
30, 37, 66, &
|
|
32, 45, 72, &
|
|
38, 51, 86, &
|
|
41, 77, 79, &
|
|
43, 56, 68, &
|
|
47, 74, 82, &
|
|
40, 52, 78, &
|
|
54, 61, 71, &
|
|
46, 58, 69/
|
|
|
|
data Nm/ &
|
|
1, 30, 60, 89, 118, 147, 0, &
|
|
2, 31, 61, 90, 119, 147, 0, &
|
|
3, 32, 62, 91, 120, 148, 0, &
|
|
4, 33, 63, 92, 121, 149, 0, &
|
|
2, 34, 64, 93, 122, 150, 0, &
|
|
5, 33, 65, 94, 123, 148, 0, &
|
|
6, 34, 66, 95, 124, 151, 0, &
|
|
7, 35, 67, 96, 120, 152, 0, &
|
|
8, 36, 68, 97, 125, 153, 0, &
|
|
9, 37, 69, 98, 126, 152, 0, &
|
|
10, 38, 70, 99, 127, 154, 0, &
|
|
11, 39, 71, 100, 126, 155, 0, &
|
|
12, 40, 61, 101, 128, 145, 0, &
|
|
10, 33, 60, 95, 128, 156, 0, &
|
|
13, 41, 72, 97, 126, 157, 0, &
|
|
13, 42, 73, 90, 129, 156, 0, &
|
|
14, 39, 74, 99, 130, 158, 0, &
|
|
15, 43, 75, 102, 131, 159, 0, &
|
|
16, 43, 71, 103, 118, 160, 0, &
|
|
17, 44, 76, 98, 130, 156, 0, &
|
|
18, 45, 60, 96, 132, 161, 0, &
|
|
19, 46, 73, 83, 133, 162, 0, &
|
|
12, 38, 77, 102, 134, 163, 0, &
|
|
19, 47, 78, 104, 135, 147, 0, &
|
|
1, 32, 77, 105, 136, 164, 0, &
|
|
20, 48, 73, 106, 123, 163, 0, &
|
|
21, 41, 79, 107, 137, 165, 0, &
|
|
22, 42, 66, 108, 138, 152, 0, &
|
|
18, 42, 80, 109, 139, 154, 0, &
|
|
23, 49, 81, 110, 135, 166, 0, &
|
|
16, 50, 82, 91, 129, 158, 0, &
|
|
3, 48, 63, 107, 124, 167, 0, &
|
|
6, 51, 67, 111, 134, 155, 0, &
|
|
24, 35, 77, 100, 122, 162, 0, &
|
|
20, 45, 76, 112, 140, 157, 0, &
|
|
21, 36, 64, 92, 130, 159, 0, &
|
|
8, 52, 83, 111, 118, 166, 0, &
|
|
21, 53, 84, 113, 138, 168, 0, &
|
|
25, 51, 79, 89, 122, 158, 0, &
|
|
22, 44, 75, 107, 133, 155, 172, &
|
|
9, 54, 84, 90, 141, 169, 0, &
|
|
22, 54, 85, 110, 136, 161, 0, &
|
|
8, 37, 65, 102, 129, 170, 0, &
|
|
19, 39, 85, 114, 139, 150, 0, &
|
|
26, 55, 71, 93, 142, 167, 0, &
|
|
27, 56, 65, 96, 133, 160, 174, &
|
|
28, 31, 86, 100, 117, 171, 0, &
|
|
28, 52, 70, 104, 132, 144, 0, &
|
|
24, 57, 68, 95, 137, 142, 0, &
|
|
7, 30, 72, 110, 143, 151, 0, &
|
|
4, 51, 76, 115, 127, 168, 0, &
|
|
16, 45, 87, 114, 125, 172, 0, &
|
|
15, 30, 86, 115, 123, 150, 0, &
|
|
23, 46, 64, 91, 144, 173, 0, &
|
|
23, 35, 75, 113, 145, 153, 0, &
|
|
14, 41, 87, 108, 117, 149, 170, &
|
|
25, 40, 85, 94, 124, 159, 0, &
|
|
25, 58, 69, 116, 143, 174, 0, &
|
|
29, 43, 61, 116, 132, 162, 0, &
|
|
15, 58, 88, 112, 121, 164, 0, &
|
|
4, 59, 72, 114, 119, 163, 173, &
|
|
27, 47, 86, 98, 134, 153, 0, &
|
|
5, 44, 78, 109, 141, 0, 0, &
|
|
10, 46, 69, 103, 136, 165, 0, &
|
|
9, 50, 59, 93, 128, 164, 0, &
|
|
14, 57, 58, 109, 120, 166, 0, &
|
|
17, 55, 62, 116, 125, 154, 0, &
|
|
3, 54, 70, 101, 140, 170, 0, &
|
|
1, 36, 82, 108, 127, 174, 0, &
|
|
5, 53, 81, 105, 140, 0, 0, &
|
|
29, 53, 67, 99, 142, 173, 0, &
|
|
18, 49, 74, 97, 115, 167, 0, &
|
|
2, 57, 63, 103, 138, 157, 0, &
|
|
26, 38, 79, 112, 135, 171, 0, &
|
|
11, 52, 66, 88, 119, 148, 0, &
|
|
20, 40, 68, 117, 141, 160, 0, &
|
|
11, 48, 81, 89, 146, 169, 0, &
|
|
29, 47, 80, 92, 146, 172, 0, &
|
|
6, 32, 87, 104, 145, 169, 0, &
|
|
27, 34, 74, 106, 131, 165, 0, &
|
|
12, 56, 84, 88, 139, 0, 0, &
|
|
13, 56, 62, 111, 146, 171, 0, &
|
|
26, 37, 80, 105, 144, 151, 0, &
|
|
17, 31, 82, 113, 121, 161, 0, &
|
|
28, 49, 59, 94, 137, 0, 0, &
|
|
7, 55, 83, 101, 131, 168, 0, &
|
|
24, 50, 78, 106, 143, 149, 0/
|
|
|
|
data nrw/ &
|
|
6,6,6,6,6,6,6,6,6,6, &
|
|
6,6,6,6,6,6,6,6,6,6, &
|
|
6,6,6,6,6,6,6,6,6,6, &
|
|
6,6,6,6,6,6,6,6,6,7, &
|
|
6,6,6,6,6,7,6,6,6,6, &
|
|
6,6,6,6,6,7,6,6,6,6, &
|
|
7,6,5,6,6,6,6,6,6,5, &
|
|
6,6,6,6,6,6,6,6,6,6, &
|
|
5,6,6,6,5,6,6/
|
|
|
|
ncw=3
|
|
|
|
decoded=0
|
|
toc=0
|
|
tov=0
|
|
tanhtoc=0
|
|
! initialize messages to checks
|
|
do j=1,M
|
|
do i=1,nrw(j)
|
|
toc(i,j)=llr((Nm(i,j)))
|
|
enddo
|
|
enddo
|
|
|
|
ncnt=0
|
|
|
|
do iter=0,maxiterations
|
|
|
|
! Update bit log likelihood ratios (tov=0 in iteration 0).
|
|
do i=1,N
|
|
if( apmask(i) .ne. 1 ) then
|
|
zn(i)=llr(i)+sum(tov(1:ncw,i))
|
|
else
|
|
zn(i)=llr(i)
|
|
endif
|
|
enddo
|
|
|
|
! Check to see if we have a codeword (check before we do any iteration).
|
|
cw=0
|
|
where( zn .gt. 0. ) cw=1
|
|
ncheck=0
|
|
do i=1,M
|
|
synd(i)=sum(cw(Nm(1:nrw(i),i)))
|
|
if( mod(synd(i),2) .ne. 0 ) ncheck=ncheck+1
|
|
! if( mod(synd(i),2) .ne. 0 ) write(*,*) 'check ',i,' unsatisfied'
|
|
enddo
|
|
! write(*,*) 'number of unsatisfied parity checks ',ncheck
|
|
if( ncheck .eq. 0 ) then ! we have a codeword - reorder the columns and return it
|
|
codeword=cw(colorder+1)
|
|
decoded=codeword(M+1:N)
|
|
nerr=0
|
|
do i=1,N
|
|
if( (2*cw(i)-1)*llr(i) .lt. 0.0 ) nerr=nerr+1
|
|
enddo
|
|
nharderror=nerr
|
|
return
|
|
endif
|
|
|
|
if( iter.gt.0 ) then ! this code block implements an early stopping criterion
|
|
! if( iter.gt.10000 ) then ! this code block implements an early stopping criterion
|
|
nd=ncheck-nclast
|
|
if( nd .lt. 0 ) then ! # of unsatisfied parity checks decreased
|
|
ncnt=0 ! reset counter
|
|
else
|
|
ncnt=ncnt+1
|
|
endif
|
|
! write(*,*) iter,ncheck,nd,ncnt
|
|
if( ncnt .ge. 5 .and. iter .ge. 10 .and. ncheck .gt. 15) then
|
|
nharderror=-1
|
|
return
|
|
endif
|
|
endif
|
|
nclast=ncheck
|
|
|
|
! Send messages from bits to check nodes
|
|
do j=1,M
|
|
do i=1,nrw(j)
|
|
ibj=Nm(i,j)
|
|
toc(i,j)=zn(ibj)
|
|
do kk=1,ncw ! subtract off what the bit had received from the check
|
|
if( Mn(kk,ibj) .eq. j ) then
|
|
toc(i,j)=toc(i,j)-tov(kk,ibj)
|
|
endif
|
|
enddo
|
|
enddo
|
|
enddo
|
|
|
|
! send messages from check nodes to variable nodes
|
|
do i=1,M
|
|
tanhtoc(1:7,i)=tanh(-toc(1:7,i)/2)
|
|
enddo
|
|
|
|
do j=1,N
|
|
do i=1,ncw
|
|
ichk=Mn(i,j) ! Mn(:,j) are the checks that include bit j
|
|
Tmn=product(tanhtoc(1:nrw(ichk),ichk),mask=Nm(1:nrw(ichk),ichk).ne.j)
|
|
call platanh(-Tmn,y)
|
|
! y=atanh(-Tmn)
|
|
tov(i,j)=2*y
|
|
enddo
|
|
enddo
|
|
|
|
enddo
|
|
nharderror=-1
|
|
return
|
|
end subroutine bpdecode174
|