diff --git a/lib/fsk4hf/ldpcsim168.f90 b/lib/fsk4hf/ldpcsim168.f90 index f134a8fbb..29e766172 100644 --- a/lib/fsk4hf/ldpcsim168.f90 +++ b/lib/fsk4hf/ldpcsim168.f90 @@ -10,7 +10,7 @@ character*8 arg integer*1, allocatable :: codeword(:), decoded(:), message(:) integer*1, target:: i1Msg8BitBytes(11) integer*1 msgbits(84) -integer*1 apmask(168) +integer*1 apmask(168), cw(168) integer*2 checksum integer*4 i4Msg6BitWords(13) integer colorder(168) @@ -124,9 +124,8 @@ allocate ( rxdata(N), llr(N) ) write(*,'(21(8i1,1x))') codeword write(*,*) "Es/N0 SNR2500 ngood nundetected nbadcrc sigma" -do idb = -10, 24 +do idb = 6,-6,-1 db=idb/2.0-1.0 -! sigma=1/sqrt( 2*rate*(10**(db/10.0)) ) sigma=1/sqrt( 2*(10**(db/10.0)) ) ngood=0 nue=0 @@ -180,14 +179,18 @@ do idb = -10, 24 ! max_iterations is max number of belief propagation iterations call bpdecode168(llr, apmask, max_iterations, decoded, niterations) + if( niterations .eq. -1 ) then + norder=3 + call osd168(llr, norder, decoded, niterations, cw) + endif ! If the decoder finds a valid codeword, niterations will be .ge. 0. if( niterations .ge. 0 ) then call extractmessage168(decoded,msgreceived,ncrcflag,recent_calls,nrecent) if( ncrcflag .ne. 1 ) then nbadcrc=nbadcrc+1 endif - nueflag=0 + nueflag=0 nerrmpc=0 do i=1,K ! find number of errors in message+crc part of codeword if( msgbits(i) .ne. decoded(i) ) then @@ -195,12 +198,16 @@ do idb = -10, 24 nerrmpc=nerrmpc+1 endif enddo + +write(37,*) niterations, ncrcflag, nueflag nmpcbad(nerrmpc)=nmpcbad(nerrmpc)+1 - if( ncrcflag .eq. 1 .and. nueflag .eq. 0 ) then - ngood=ngood+1 - nerrdec(nerr)=nerrdec(nerr)+1 - else if( ncrcflag .eq. 1 .and. nueflag .eq. 1 ) then - nue=nue+1; + if( ncrcflag .eq. 1 ) then + if( nueflag .eq. 0 ) then + ngood=ngood+1 + nerrdec(nerr)=nerrdec(nerr)+1 + else if( nueflag .eq. 1 ) then + nue=nue+1; + endif endif endif enddo diff --git a/lib/fsk4hf/ldpcsim300.f90 b/lib/fsk4hf/ldpcsim300.f90 index 098839a06..a4b5beaa4 100644 --- a/lib/fsk4hf/ldpcsim300.f90 +++ b/lib/fsk4hf/ldpcsim300.f90 @@ -117,7 +117,7 @@ write(*,*) i1Msg8BitBytes(1:9) write(*,*) "Es/N0 SNR2500 ngood nundetected nbadcrc sigma" do idb = 20,-16,-1 -!do idb = -14, -16, -1 +!do idb = -16, -16, -1 db=idb/2.0-1.0 ! sigma=1/sqrt( 2*rate*(10**(db/10.0)) ) ! to make db represent Eb/No sigma=1/sqrt( 2*(10**(db/10.0)) ) ! db represents Es/No diff --git a/lib/fsk4hf/osd300.f90 b/lib/fsk4hf/osd300.f90 index 81ab2e3c6..2feebab16 100644 --- a/lib/fsk4hf/osd300.f90 +++ b/lib/fsk4hf/osd300.f90 @@ -10,7 +10,7 @@ include "ldpc_300_60_params.f90" integer*1 gen(K,N) integer*1 genmrb(K,N) -integer*1 temp(K),m0(K),me(K) +integer*1 temp(K),m0(K),me(0:K) integer indices(N) integer*1 codeword(N),cw(N),hdec(N) integer*1 decoded(K) @@ -48,37 +48,33 @@ where(rx .ge. 0) hdec=1 ! use magnitude of received symbols as a measure of reliability. absrx=abs(rx) call indexx(absrx,N,indx) -! re-order the columns of the generator matrix in order of increasing reliability. + +! re-order the columns of the generator matrix in order of decreasing reliability. do i=1,N - genmrb(1:K,N+1-i)=gen(1:K,indx(N+1-i)) + genmrb(1:K,i)=gen(1:K,indx(N+1-i)) + indices(i)=indx(N+1-i) enddo ! do gaussian elimination to create a generator matrix with the most reliable -! received bits as the systematic bits. if it happens that the K most reliable -! bits are not independent, then we will encounter a zero pivot, in that case -! we dip into the less reliable bits to find K independent MRBs. -! the "indices" array will track any column reordering that is done as part -! of the gaussian elimination. -do i=1,N - indices(i)=indx(i) -enddo +! received bits in positions 1:K in order of decreasing reliability (more or less). +! reliability will not be strictly decreasing because column re-ordering is needed +! to put the generator matrix in systematic form. the "indices" array tracks +! column permutations caused by reliability sorting and gaussian elimination. do id=1,K ! diagonal element indices - do ic=id,K+20 ! The 20 is ad hoc - beware - icol=N-K+ic - if( icol .gt. N ) icol=M+1-(icol-N) + do icol=id,K+20 ! The 20 is ad hoc - beware iflag=0 if( genmrb(id,icol) .eq. 1 ) then iflag=1 - if( icol-M .ne. id ) then ! reorder column - temp(1:K)=genmrb(1:K,M+id) - genmrb(1:K,M+id)=genmrb(1:K,icol) + if( icol .ne. id ) then ! reorder column + temp(1:K)=genmrb(1:K,id) + genmrb(1:K,id)=genmrb(1:K,icol) genmrb(1:K,icol)=temp(1:K) - itmp=indices(M+id) - indices(M+id)=indices(icol) + itmp=indices(id) + indices(id)=indices(icol) indices(icol)=itmp endif do ii=1,K - if( ii .ne. id .and. genmrb(ii,N-K+id) .eq. 1 ) then + if( ii .ne. id .and. genmrb(ii,id) .eq. 1 ) then genmrb(ii,1:N)=mod(genmrb(ii,1:N)+genmrb(id,1:N),2) endif enddo @@ -87,17 +83,15 @@ do id=1,K ! diagonal element indices enddo enddo -! now, use the indices of the K MRB bits to find the hard-decisions -! for those bits. the resulting message is encoded to find the -! zero'th order codeword estimate (assuming no errors in the MRB). -m0=0 -where (rx(indices(M+1:N)).ge.0.0) m0=1 +! The hard decisions for the K MRB bits define the order 0 message, m0. +! Encode m0 using the modified generator matrix to find the "order 0" codeword. +! Flip various combinations of bits in m0 and re-encode to generate a list of +! codewords. Test all such codewords against the received word to decide which +! codeword is most likely to be correct. +hdec=hdec(indices) +m0=hdec(1:K) -! the MRB should have only a few errors. Try various error patterns, -! re-encode each errored version of the MRBs, re-order the resulting codeword -! and compare with the original received vector. Keep the best codeword. nhardmin=N -corrmax=-1.0e32 j0=0 j1=0 j2=0 @@ -106,45 +100,41 @@ if( norder.ge.4 ) j0=K if( norder.ge.3 ) j1=K if( norder.ge.2 ) j2=K if( norder.ge.1 ) j3=K +! me(0) is a dummy position --- only me(1:K) are actually used. This is done +! to avoid "if" statements within the inner loop. do i1=0,j0 do i2=i1,j1 do i3=i2,j2 do i4=i3,j3 - me=m0 - if( i1 .ne. 0 ) me(i1)=1-me(i1) - if( i2 .ne. 0 ) me(i2)=1-me(i2) - if( i3 .ne. 0 ) me(i3)=1-me(i3) - if( i4 .ne. 0 ) me(i4)=1-me(i4) + me(1:K)=m0 + me(i1)=1-me(i1) + me(i2)=1-me(i2) + me(i3)=1-me(i3) + me(i4)=1-me(i4) -! me is the MRB message + error pattern -! use the modified generator matrix to encode this message, -! producing a codeword that will be tested against the received vector +! me is the m0 + error pattern. encode this message using genmrb to +! produce a codeword. test the codeword against the received vector +! and save it if it's the best that we've seen so far. do i=1,N - nsum=sum(iand(me,genmrb(1:K,i))) + nsum=sum(iand(me(1:K),genmrb(1:K,i))) codeword(i)=mod(nsum,2) enddo -! undo the index permutations to put the "real" message bits at the end - codeword(indices)=codeword nhard=count(codeword .ne. hdec) -! corr=sum(codeword*rx) ! to save time use nhard to pick best codeword if( nhard .lt. nhardmin ) then -! if( corr .gt. corrmax ) then cw=codeword nhardmin=nhard -! corrmax=corr i1min=i1 i2min=i2 i3min=i3 i4min=i4 - if( nhardmin .le. 85 ) goto 200 ! tune for each code endif enddo enddo enddo enddo - -200 decoded=cw(M+1:N) -niterations=-1 -if( nhardmin .le. 90 ) niterations=1 ! tune for each code +! re-order the codeword to place message bits at the end +cw(indices)=cw +decoded=cw(M+1:N) +niterations=1 return end subroutine osd300