diff --git a/lib/fsk4hf/ldpcsim300.f90 b/lib/fsk4hf/ldpcsim300.f90 index 8fc50e564..bf1614319 100644 --- a/lib/fsk4hf/ldpcsim300.f90 +++ b/lib/fsk4hf/ldpcsim300.f90 @@ -115,7 +115,8 @@ write(*,*) i1Msg8BitBytes(1:9) write(*,'(38(8i1,1x))') codeword write(*,*) "Es/N0 SNR2500 ngood nundetected nbadcrc sigma" -do idb = -14, 20 +do idb = 20,-14,-1 +!do idb = -10, -10 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 @@ -168,6 +169,9 @@ do idb = -14, 20 ! max_iterations is max number of belief propagation iterations call bpdecode300(llr, apmask, max_iterations, decoded, niterations, cw) + if( niterations .lt. 0 ) then + call osd300(llr, decoded, niterations, cw) + endif n2err=0 do i=1,N if( cw(i)*(2*codeword(i)-1.0) .lt. 0 ) n2err=n2err+1 @@ -225,7 +229,7 @@ do idb = -14, 20 endif endif enddo - snr2500=db+10*log10(1.03/2500.0) + snr2500=db+10*log10(1.389/2500.0) pberr=real(nberr)/(real(ntrials*N)) write(*,"(f4.1,4x,f5.1,1x,i8,1x,i8,1x,i8,8x,f5.2,8x,e10.3)") db,snr2500,ngood,nue,nbadcrc,ss,pberr diff --git a/lib/fsk4hf/osd300.f90 b/lib/fsk4hf/osd300.f90 new file mode 100644 index 000000000..1825cd372 --- /dev/null +++ b/lib/fsk4hf/osd300.f90 @@ -0,0 +1,409 @@ +subroutine osd300(llr,decoded,niterations,cw) +! +! An ordered-statistics decoder for the (300,60) code. +! Based on the ideas in: +! "Soft-decision decoding of linear block codes based on ordered statistics," +! by Marc P. C. Fossorier and Shu Lin, +! IEEE Trans Inf Theory, Vol 41, No 5, Sep 1995 +! +character*15 g(240) +integer*1 gen(60,300) +integer*1 genmrb(60,300) +integer*1 temp(60),m0(60),me(60) +integer indices(300) +integer, parameter:: N=300, K=60, M=N-K +integer*1 codeword(N),cw(N),apmask(N),hdec(N) +integer colorder(N) +integer*1 decoded(K) +integer indx(N),indxmrb(K) +real llr(N),rx(N),absrx(N),absmrb(K) +logical first +data first/.true./ +data g/ & + "316fd3bb18bcefd", & + "a9c1c984f91244e", & + "9e04bd3d5d78d89", & + "f81617089621bd4", & + "12997ce2f44dbf4", & + "3ebddaf9b0fa1fc", & + "d0c114b0b0ef162", & + "f8c4f115f98bd92", & + "d0a79c0c5b8ca19", & + "477f6712f357b3b", & + "fa28b2444a7e66b", & + "bedcd4df8d95c64", & + "da30de73e57022c", & + "bc099bbb90fe09e", & + "cffc1e47e5708e8", & + "713d808563ca9a3", & + "70fcf1741d5d5d7", & + "32e80bc15112008", & + "804cef4df9b18ec", & + "3736881819d1033", & + "f4e37db7f9c5efe", & + "9e84b93d4d78d09", & + "2250c3518ec830a", & + "55a529a92e18021", & + "1cb80b14c9f6eae", & + "80c504b031ef926", & + "ece6636d0ac9c6d", & + "5d50a1690782cd0", & + "3d54a1fb30937a2", & + "ba8fe8006318041", & + "02917ce2fc45bf4", & + "abc1d984f95a44e", & + "fc05b4c4ab2d850", & + "467f7718f357b3b", & + "472cc094546c6b2", & + "fcdd94cf8c9cc64", & + "4dbc1647e970cc8", & + "6caa465c442aed1", & + "aead5af8b0da1be", & + "d8e1fa45a2e8431", & + "9d4dc4cc63abb7f", & + "9b2df6b48264637", & + "7335808563ca3a3", & + "36bf8d5cd93e6cc", & + "004ccf4db9b08ec", & + "90a71c8c598ca19", & + "f8c5d115f90bc92", & + "b95546c4e3f7934", & + "7d50a1690786cd0", & + "c90939921a0d7c6", & + "d0c504b030ef126", & + "ce3e6f9396fc542", & + "a0072a59f3707f5", & + "532d0a8fe3da1ea", & + "68b9e5cd7d142db", & + "fedc94df8c9dc64", & + "6da2465c448aed0", & + "3574aa19cb273c0", & + "1e54768c6bc6843", & + "691f65654498186", & + "fe2c92444a6ef6b", & + "9caad933e038cc4", & + "ad4e6f4defb28ec", & + "4f3d80947c6d2b2", & + "1caad933e0b8cc4", & + "b14fd3bf18bcafd", & + "ad091bbbb0f809e", & + "90b71c8c598da19", & + "f8c4d115f90bd92", & + "9d4dcccc63afb7f", & + "fa2c92444a6e76b", & + "1e14768c6bc6c43", & + "d1baf5aacb86087", & + "bdf762b92ee51c7", & + "caacec06ad8a90c", & + "804ccf4df9b08ec", & + "69e969f9da5cbd8", & + "814ccf4df9b086c", & + "cebe4f9796f4542", & + "491f65654499186", & + "8fbf5b9796f6d2a", & + "ce3e4f9396f4542", & + "47558560e7debc3", & + "94aadd33e038cc4", & + "a94eef4debb286e", & + "d8e5d115f91bcd2", & + "532d488fe3da0ab", & + "664e7bc4e23a80c", & + "94a2dd33a038cd4", & + "d8c5d115f91bc92", & + "0fef071eee60bd5", & + "9a89a09163c2b97", & + "0eaf071e6c60bd5", & + "bc0d1bbbb0fe0be", & + "f9babd3d12d0f31", & + "69a969f9da5c9d8", & + "6e4e7bc4e23a82c", & + "b0042659f3227f5", & + "2d51418f0f28347", & + "be0d5bbbb0da0be", & + "225003508ec8302", & + "8fbf4b9796f4d2a", & + "bead5af9b0da1be", & + "6ca2465c440aed1", & + "4fbc1e47ed708c8", & + "bd091bbbb0fc09e", & + "b0062259f3307f5", & + "a8072a59f3727f5", & + "a0062259f3707f5", & + "3c380b14c974eae", & + "30042659f3226f5", & + "48b9e4cd7d142db", & + "728bcd4b38308fb", & + "c0c504b031ef126", & + "314fd3bb18bcafd", & + "1c29148305faec1", & + "44c92a9c28ada63", & + "88e99b370aae32b", & + "695081690386ad8", & + "572d0a8de3da1ea", & + "467f6610f357b2b", & + "733d008563da1a3", & + "d1baf4aacb84087", & + "4315551d71c8ff0", & + "48bde4cd7d140db", & + "3ebd58f9b0da9fc", & + "51baf4aacb84083", & + "814e4f4de9b082c", & + "814ecf4de9b086c", & + "be0d1bbbb0fa0be", & + "4f7580947c792b3", & + "cdf2dce48c39c3b", & + "d8c5c115f91bc12", & + "a94e6f4debb28ee", & + "be2d5afbb0da1be", & + "cdd6dce48439c2b", & + "bebd5af9b0da1fe", & + "fa2892444a6e66b", & + "51bbf4aacb8c083", & + "baa73d81eebcd83", & + "79a2ce47f138cc9", & + "cc28cf198e6dbd4", & + "fcde94dfcc9cc64", & + "1016fcf59286717", & + "12917ce2fc4dbf4", & + "4fbc1647e9708c8", & + "3e382b1cc974fae", & + "d5bafdaad386087", & + "0fef473eee60bd5", & + "c0e504b031ee126", & + "8bbf5b9797f6d2a", & + "0eef071e6e60bd5", & + "1806fcf59386517", & + "fcdc94df8c9cc64", & + "141eca2bfa25656", & + "5fbc1767e9708e8", & + "5aa4c7803a6bdf1", & + "b14bd3b718bcafd", & + "3ebd5af9b0da1fc", & + "d0a7148c5b8ca09", & + "a94ecf4debb086e", & + "733d808563ca1a3", & + "fd9abd1d92d0f31", & + "bc091bbbb0fe09e", & + "d0c514b0b0ef122", & + "4f7d80947c7d2b3", & + "8b3f5b97b7f6d2a", & + "4fbc1767e9708c8", & + "cebf4f9796f4502", & + "9c76c880a864e67", & + "abc1c984f95244e", & + "795081690786ad8", & + "467f6710f357b3b", & + "1c380b14c9f4eae", & + "d5baf5aac386087", & + "bedc94df8c95c64", & + "553d0a8de2da1fa", & + "0315551d71d8ff0", & + "1c1eca2ffa25656", & + "d4bafdaad3c6087", & + "be2d5bfbb0da0be", & + "b0062659f3207f5", & + "5ffc1765e9708e8", & + "8d62e8bcd303e33", & + "cc08cf198e69bd4", & + "573d0a8de3da1fa", & + "cd56dce48639c2b", & + "472dc094546c2b2", & + "7950a16907868d8", & + "7283cf4b38308fb", & + "894ecf4de9b086e", & + "0f7580b47c792b3", & + "cfbf4b9796f4d0a", & + "3e380b14c974fae", & + "732d0085e3da1a3", & + "1816fcf59386717", & + "532d088fe3da1ab", & + "1c300b94c9fcaae", & + "d0a71c8c5b8ca19", & + "9e84bd3d5d78d09", & + "225083508ec830a", & + "f99abd1d12d0f31", & + "35f4aa19cb673c0", & + "cdd2dce48c39c2b", & + "0f7780b47c792bf", & + "0e33a5f114f5730", & + "bc05b4c4ab0d850", & + "1c300b14c9f4aae", & + "cfbc1e47ed708e8", & + "0f7180b47c392b3", & + "d8c7c115f91be12", & + "c09148adfa94e97", & + "9c66c880a844e67", & + "2226c13b73519f8", & + "cebf4b9796f4d02", & + "c0e706b031ee126", & + "6a6629715e53ce3", & + "73f9aa824e7d0b8", & + "473d80947c6c2b2", & + "1df140e0ddb5632", & + "473dc0945c6c2b2", & + "81b4d95f671971d", & + "663945ca758e2b6", & + "02ec3d98a2306fd", & + "5dadb0fa1275690", & + "4bb8aaa854948d0", & + "8359ba40886971c", & + "49cc3d2a2be2ee0", & + "bfdf13af137f318", & + "a1de773a2b1ff04", & + "8ff3945a2f465c7", & + "532d0087e3da1a3", & + "f3eaf7fa454d385", & + "a606aa5aeba07d9", & + "67f0627b0af8a53", & + "56698bed69d1c2c", & + "d5f420011fbf924", & + "2a8f86c810e2c62", & + "43cc1cf1208c206", & + "ee784c4900258de"/ + +data colorder/ & +0,1,2,3,4,5,6,7,8,9,10,11,123,12,13,14,15,16,17,18, & +19,20,21,22,23,24,25,138,26,145,27,28,29,30,31,32,33,34,35,36, & +37,154,38,39,40,41,42,43,44,144,46,47,48,49,50,51,52,53,143,54, & +125,56,57,58,124,59,120,140,157,160,55,60,61,62,156,162,141,64,65,153, & +181,183,66,170,67,68,69,130,70,164,71,72,73,74,75,63,76,77,135,78, & +79,80,176,169,82,83,84,167,180,85,136,158,129,166,175,142,134,146,121,165, & +88,89,192,90,45,91,92,93,182,189,94,95,96,173,81,97,98,178,122,126, & +132,99,100,152,186,193,101,102,151,103,104,172,159,168,150,190,147,148,201,107, & +205,177,108,198,197,174,127,109,185,110,202,87,199,171,179,187,139,137,106,131, & +206,194,112,149,155,113,128,184,196,86,114,203,212,195,208,105,188,161,163,191, & +200,209,214,204,115,218,133,111,207,117,213,216,211,217,116,215,219,220,210,221, & +118,222,223,225,224,228,226,229,231,227,233,119,234,235,232,230,237,239,236,238, & +240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259, & +260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279, & +280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299/ + +save first,gen + +if( first ) then ! fill the generator matrix + gen=0 + do i=1,240 + do j=1,15 + read(g(i)(j:j),"(Z1)") istr + do jj=1, 4 + irow=(j-1)*4+jj + if( btest(istr,4-jj) ) gen(irow,i)=1 + enddo + enddo + enddo + do irow=1,60 + gen(irow,240+irow)=1 + enddo +first=.false. +endif + +! re-order received vector to place systematic msg bits at the end +rx=llr(colorder+1) + +! hard decode the received word +hdec=0 +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. +do i=1,N + genmrb(1:K,N+1-i)=gen(1:K,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 +do id=1,K ! diagonal element indices + do ic=id,K+20 ! + icol=N-K+ic + if( icol .gt. N ) icol=241-(icol-300) + iflag=0 + if( genmrb(id,icol) .eq. 1 ) then + iflag=1 + if( icol-240 .ne. id ) then ! reorder column + temp(1:60)=genmrb(1:60,240+id) + genmrb(1:60,240+id)=genmrb(1:60,icol) + genmrb(1:60,icol)=temp(1:60) + itmp=indices(240+id) + indices(240+id)=indices(icol) + indices(icol)=itmp + endif + do ii=1,K + if( ii .ne. id .and. genmrb(ii,N-K+id) .eq. 1 ) then + genmrb(ii,1:N)=mod(genmrb(ii,1:N)+genmrb(id,1:N),2) + endif + enddo + exit + endif + 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(241:300)).ge.0.0) m0=1 +absmrb=abs(rx(indices(241:300))) +!do i=1,60 +!write(*,*) i,absmrb(i) +!enddo +call indexx(absmrb,K,indxmrb) +!do i=1,60 +!write(*,*) i,absmrb(i),indxmrb(i),absmrb(indxmrb(i)) +!enddo +xmed=absmrb(45) + +! 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=300 +corrmax=-1.0e32 +do i1=0,60 + do i2=i1,60 + do i3=i2,60 + do i4=i3,60 + 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 is the "errored" message = MRB's + error pattern + do i=1, 300 + nsum=sum(iand(me,genmrb(1:60,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 ! early stopping criterion + endif + enddo + enddo + enddo +enddo + +200 decoded=cw(241:300) +!write(*,*) absmrb(i1min),absmrb(i2min),absmrb(i3min),absmrb(i4min),xmed,nhardmin +niterations=-1 +if( nhardmin .le. 90 ) niterations=1 +return +end subroutine osd300