mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-31 04:50:34 -04:00 
			
		
		
		
	Add support for a rate 1/3 (204,68) code.
git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@8585 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
		
							parent
							
								
									8b164ba17f
								
							
						
					
					
						commit
						2786c20ba2
					
				
							
								
								
									
										482
									
								
								lib/fsk4hf/bpdecode204.f90
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										482
									
								
								lib/fsk4hf/bpdecode204.f90
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,482 @@ | ||||
| subroutine bpdecode204(llr,apmask,maxiterations,decoded,cw,nharderror,iter) | ||||
| ! | ||||
| ! A log-domain belief propagation decoder for the (204,68) code. | ||||
| ! | ||||
| integer, parameter:: N=204, K=68, M=N-K | ||||
| integer*1 codeword(N),cw(N),apmask(N) | ||||
| integer  colorder(N) | ||||
| integer*1 decoded(K) | ||||
| integer Nm(6,M)  ! 4, 5, or 6 bits per check  | ||||
| integer Mn(3,N)  ! 3 checks per bit | ||||
| integer synd(M) | ||||
| real tov(3,N) | ||||
| real toc(6,M) | ||||
| real tanhtoc(6,M) | ||||
| real zn(N) | ||||
| real llr(N) | ||||
| real Tmn | ||||
| integer nrw(M) | ||||
| 
 | ||||
| data colorder/                                                              & | ||||
|          0,  1,  2,  3,  4,  5, 47,  6,  7,  8,  9, 10, 11, 12, 58, 55, 13, & | ||||
|         14, 15, 46, 17, 18, 60, 19, 20, 21, 22, 23, 24, 25, 57, 26, 27, 49, & | ||||
|         28, 52, 65, 16, 50, 73, 59, 68, 63, 29, 30, 31, 32, 51, 62, 56, 66, & | ||||
|         45, 33, 34, 53, 67, 35, 36, 37, 61, 69, 54, 38, 71, 82, 39, 77, 80, & | ||||
|         83, 78, 84, 48, 41, 85, 40, 64, 75, 96, 74, 72, 76, 86, 87, 89, 90, & | ||||
|         79, 70, 92, 99, 93,101, 95,100, 97, 94, 42, 98,103,105,102, 43,104, & | ||||
|         88, 44,106, 81,107,110,108,111,112,109,113,114,117,118,116,121,115, & | ||||
|        119,122,120,125,129,124,127,126,128, 91,123,133,131,130,134,135,137, & | ||||
|        136,132,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,174,175,176,177,178,179,180,181,182,183,184,185,186, & | ||||
|        187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203/ | ||||
| 
 | ||||
| data Mn/       & | ||||
|    1,  38, 107, & | ||||
|    2,   7, 114, & | ||||
|    3,  48, 106, & | ||||
|    4,  79,  94, & | ||||
|    5,  97, 108, & | ||||
|    6,  50, 122, & | ||||
|    8,  78, 134, & | ||||
|    9,  55,  65, & | ||||
|   10,  62, 100, & | ||||
|   11,  16,  99, & | ||||
|   12, 113, 119, & | ||||
|   13,  31, 125, & | ||||
|   14,  15, 127, & | ||||
|   17,  87, 103, & | ||||
|   18,  81,  98, & | ||||
|   19,  43,  77, & | ||||
|   20, 102, 130, & | ||||
|   21,  36, 111, & | ||||
|   22,  23,  60, & | ||||
|   24,  39, 112, & | ||||
|   25,  37,  42, & | ||||
|   26,  41,  51, & | ||||
|   27,  67,  70, & | ||||
|   28,  64, 136, & | ||||
|   29,  61,  68, & | ||||
|   30,  91, 124, & | ||||
|   32,  80, 121, & | ||||
|   33,  40, 117, & | ||||
|   34,  35,  90, & | ||||
|   44,  88,  93, & | ||||
|   45, 128, 133, & | ||||
|   46,  56,  69, & | ||||
|   47,  49,  52, & | ||||
|   53,  76, 131, & | ||||
|   54, 104, 116, & | ||||
|   57,  84,  86, & | ||||
|   58, 120, 135, & | ||||
|   59,  75,  92, & | ||||
|   63,  71, 109, & | ||||
|   66,  74, 126, & | ||||
|   72,  85, 105, & | ||||
|   73,  82,  95, & | ||||
|   83,  89, 123, & | ||||
|   96, 115, 118, & | ||||
|  101, 110, 129, & | ||||
|   52,  99, 132, & | ||||
|    1,   3,  20, & | ||||
|    2,  77,  89, & | ||||
|    4,  72,  75, & | ||||
|    5,  34,  79, & | ||||
|    6,  24, 130, & | ||||
|    7,  48,  88, & | ||||
|    8,  36, 116, & | ||||
|    9,  71, 114, & | ||||
|   10,  87, 101, & | ||||
|   11,  22, 121, & | ||||
|   12,  50,  64, & | ||||
|   13,  39,  53, & | ||||
|   14,  41,  78, & | ||||
|   15,  68,  96, & | ||||
|   16,  83,  90, & | ||||
|   17,  23,  45, & | ||||
|   18,  47, 126, & | ||||
|   19,  70,  91, & | ||||
|   21,  57,  76, & | ||||
|   25, 110, 117, & | ||||
|   26,  82, 135, & | ||||
|   27,  46,  58, & | ||||
|   28,  37,  56, & | ||||
|   29,  66, 102, & | ||||
|   30,  62, 125, & | ||||
|   31,  85,  93, & | ||||
|   32, 104, 113, & | ||||
|   33,  81,  92, & | ||||
|   35, 100, 118, & | ||||
|   38,  95, 133, & | ||||
|   40,  86, 109, & | ||||
|   42,  61, 124, & | ||||
|   43,  59, 119, & | ||||
|   44,  49, 134, & | ||||
|   51,  97, 122, & | ||||
|   54, 105, 107, & | ||||
|   55, 128, 136, & | ||||
|   60,  67,  84, & | ||||
|   63, 112, 115, & | ||||
|   65,  74, 131, & | ||||
|   69,  80,  94, & | ||||
|   73,  98, 123, & | ||||
|  103, 130, 134, & | ||||
|   46, 106, 111, & | ||||
|    1,  84, 108, & | ||||
|  120, 129, 132, & | ||||
|   65,  75, 127, & | ||||
|    2,  80, 101, & | ||||
|    3, 118, 119, & | ||||
|    4,  52, 124, & | ||||
|    5,  13,  68, & | ||||
|    6,  27,  81, & | ||||
|    7,  51,  76, & | ||||
|    8,  77, 108, & | ||||
|    9,  31,  58, & | ||||
|   10,  18,  57, & | ||||
|   11,  63, 105, & | ||||
|   12,  14, 132, & | ||||
|   15,  56, 123, & | ||||
|   16,  21, 128, & | ||||
|   17,  37,  59, & | ||||
|   19,  85, 126, & | ||||
|   20,  71,  91, & | ||||
|   22,  26, 117, & | ||||
|   23,  79,  98, & | ||||
|   24,  32,  95, & | ||||
|   25,  90,  93, & | ||||
|   28,  49, 109, & | ||||
|   29, 116, 120, & | ||||
|   30,  54, 136, & | ||||
|   33,  53, 107, & | ||||
|   34,  64, 103, & | ||||
|   35,  39,  67, & | ||||
|   36,  71,  73, & | ||||
|   38,  47, 125, & | ||||
|   40,  66,  94, & | ||||
|   41,  70, 104, & | ||||
|   42,  55, 112, & | ||||
|   43,  44,  82, & | ||||
|   29,  45,  88, & | ||||
|   48,  86, 127, & | ||||
|   50,  72, 135, & | ||||
|   60,  74,  96, & | ||||
|   61, 121, 131, & | ||||
|   62,  78,  92, & | ||||
|   69, 100, 133, & | ||||
|   83, 122, 129, & | ||||
|   87,  97, 106, & | ||||
|   89, 102, 113, & | ||||
|   24,  99, 108, & | ||||
|   20,  72, 110, & | ||||
|  111, 115, 117, & | ||||
|   35,  52, 114, & | ||||
|    1,  44,  94, & | ||||
|    2,  23, 107, & | ||||
|    3,  81, 136, & | ||||
|    4,   8,  96, & | ||||
|    5,  37,  70, & | ||||
|    6,  43, 131, & | ||||
|    7, 103, 115, & | ||||
|    9,  94, 122, & | ||||
|   10,  68,  82, & | ||||
|   11,  56,  88, & | ||||
|   12,  46, 126, & | ||||
|   13,  16,  75, & | ||||
|   14,  79, 112, & | ||||
|   15,  47, 110, & | ||||
|   17,  36,  39, & | ||||
|   18,  63, 120, & | ||||
|   19,  22,  55, & | ||||
|   21,  49, 113, & | ||||
|   25,  54,  57, & | ||||
|   26,  89, 125, & | ||||
|   27, 101, 109, & | ||||
|   28,  31,  60, & | ||||
|   30,  74,  97, & | ||||
|   32,  92,  93, & | ||||
|   33,  83,  91, & | ||||
|   34,  58, 121, & | ||||
|   38,  65, 111, & | ||||
|   40,  99, 118, & | ||||
|    3,  41,  61, & | ||||
|   42,  50, 100, & | ||||
|   45,  78, 106, & | ||||
|   48,  95, 129, & | ||||
|   51,  85, 133, & | ||||
|   53,  59,  69, & | ||||
|   11,  62,  66, & | ||||
|   64,  73, 124, & | ||||
|   67, 123, 134, & | ||||
|   76, 104, 132, & | ||||
|   77, 100, 127, & | ||||
|   36,  80, 119, & | ||||
|   84, 102, 135, & | ||||
|   86, 105, 124, & | ||||
|    4,  87, 128, & | ||||
|   90, 106, 116, & | ||||
|   65,  98, 130, & | ||||
|   92, 108, 114, & | ||||
|    1,  52, 121, & | ||||
|    2,  84, 117, & | ||||
|    5,  83, 105, & | ||||
|    6,  15,  63, & | ||||
|    7,  28,  82, & | ||||
|    8,  32, 135, & | ||||
|    9, 104, 134, & | ||||
|    9,  10,  89, & | ||||
|   12,  62, 107, & | ||||
|   13,  40, 103, & | ||||
|   14,  31,  95, & | ||||
|   16,  27,  74, & | ||||
|   17,  90, 132, & | ||||
|   18,  34,  69, & | ||||
|   19, 103, 129, & | ||||
|   20,  76,  87, & | ||||
|   21,  22, 130, & | ||||
|   23,  25,  99, & | ||||
|   24, 101, 126/ | ||||
| 
 | ||||
| data Nm/               & | ||||
|    1,  47,  91, 140, 186,   0, & | ||||
|    2,  48,  94, 141, 187,   0, & | ||||
|    3,  47,  95, 142, 168,   0, & | ||||
|    4,  49,  96, 143, 182,   0, & | ||||
|    5,  50,  97, 144, 188,   0, & | ||||
|    6,  51,  98, 145, 189,   0, & | ||||
|    2,  52,  99, 146, 190,   0, & | ||||
|    7,  53, 100, 143, 191,   0, & | ||||
|    8,  54, 101, 147, 192, 193, & | ||||
|    9,  55, 102, 148, 193,   0, & | ||||
|   10,  56, 103, 149, 174,   0, & | ||||
|   11,  57, 104, 150, 194,   0, & | ||||
|   12,  58,  97, 151, 195,   0, & | ||||
|   13,  59, 104, 152, 196,   0, & | ||||
|   13,  60, 105, 153, 189,   0, & | ||||
|   10,  61, 106, 151, 197,   0, & | ||||
|   14,  62, 107, 154, 198,   0, & | ||||
|   15,  63, 102, 155, 199,   0, & | ||||
|   16,  64, 108, 156, 200,   0, & | ||||
|   17,  47, 109, 137, 201,   0, & | ||||
|   18,  65, 106, 157, 202,   0, & | ||||
|   19,  56, 110, 156, 202,   0, & | ||||
|   19,  62, 111, 141, 203,   0, & | ||||
|   20,  51, 112, 136, 204,   0, & | ||||
|   21,  66, 113, 158, 203,   0, & | ||||
|   22,  67, 110, 159,   0,   0, & | ||||
|   23,  68,  98, 160, 197,   0, & | ||||
|   24,  69, 114, 161, 190,   0, & | ||||
|   25,  70, 115, 126,   0,   0, & | ||||
|   26,  71, 116, 162,   0,   0, & | ||||
|   12,  72, 101, 161, 196,   0, & | ||||
|   27,  73, 112, 163, 191,   0, & | ||||
|   28,  74, 117, 164,   0,   0, & | ||||
|   29,  50, 118, 165, 199,   0, & | ||||
|   29,  75, 119, 139,   0,   0, & | ||||
|   18,  53, 120, 154, 179,   0, & | ||||
|   21,  69, 107, 144,   0,   0, & | ||||
|    1,  76, 121, 166,   0,   0, & | ||||
|   20,  58, 119, 154,   0,   0, & | ||||
|   28,  77, 122, 167, 195,   0, & | ||||
|   22,  59, 123, 168,   0,   0, & | ||||
|   21,  78, 124, 169,   0,   0, & | ||||
|   16,  79, 125, 145,   0,   0, & | ||||
|   30,  80, 125, 140,   0,   0, & | ||||
|   31,  62, 126, 170,   0,   0, & | ||||
|   32,  68,  90, 150,   0,   0, & | ||||
|   33,  63, 121, 153,   0,   0, & | ||||
|    3,  52, 127, 171,   0,   0, & | ||||
|   33,  80, 114, 157,   0,   0, & | ||||
|    6,  57, 128, 169,   0,   0, & | ||||
|   22,  81,  99, 172,   0,   0, & | ||||
|   33,  46,  96, 139, 186,   0, & | ||||
|   34,  58, 117, 173,   0,   0, & | ||||
|   35,  82, 116, 158,   0,   0, & | ||||
|    8,  83, 124, 156,   0,   0, & | ||||
|   32,  69, 105, 149,   0,   0, & | ||||
|   36,  65, 102, 158,   0,   0, & | ||||
|   37,  68, 101, 165,   0,   0, & | ||||
|   38,  79, 107, 173,   0,   0, & | ||||
|   19,  84, 129, 161,   0,   0, & | ||||
|   25,  78, 130, 168,   0,   0, & | ||||
|    9,  71, 131, 174, 194,   0, & | ||||
|   39,  85, 103, 155, 189,   0, & | ||||
|   24,  57, 118, 175,   0,   0, & | ||||
|    8,  86,  93, 166, 184,   0, & | ||||
|   40,  70, 122, 174,   0,   0, & | ||||
|   23,  84, 119, 176,   0,   0, & | ||||
|   25,  60,  97, 148,   0,   0, & | ||||
|   32,  87, 132, 173, 199,   0, & | ||||
|   23,  64, 123, 144,   0,   0, & | ||||
|   39,  54, 109, 120,   0,   0, & | ||||
|   41,  49, 128, 137,   0,   0, & | ||||
|   42,  88, 120, 175,   0,   0, & | ||||
|   40,  86, 129, 162, 197,   0, & | ||||
|   38,  49,  93, 151,   0,   0, & | ||||
|   34,  65,  99, 177, 201,   0, & | ||||
|   16,  48, 100, 178,   0,   0, & | ||||
|    7,  59, 131, 170,   0,   0, & | ||||
|    4,  50, 111, 152,   0,   0, & | ||||
|   27,  87,  94, 179,   0,   0, & | ||||
|   15,  74,  98, 142,   0,   0, & | ||||
|   42,  67, 125, 148, 190,   0, & | ||||
|   43,  61, 133, 164, 188,   0, & | ||||
|   36,  84,  91, 180, 187,   0, & | ||||
|   41,  72, 108, 172,   0,   0, & | ||||
|   36,  77, 127, 181,   0,   0, & | ||||
|   14,  55, 134, 182, 201,   0, & | ||||
|   30,  52, 126, 149,   0,   0, & | ||||
|   43,  48, 135, 159, 193,   0, & | ||||
|   29,  61, 113, 183, 198,   0, & | ||||
|   26,  64, 109, 164,   0,   0, & | ||||
|   38,  74, 131, 163, 185,   0, & | ||||
|   30,  72, 113, 163,   0,   0, & | ||||
|    4,  87, 122, 140, 147,   0, & | ||||
|   42,  76, 112, 171, 196,   0, & | ||||
|   44,  60, 129, 143,   0,   0, & | ||||
|    5,  81, 134, 162,   0,   0, & | ||||
|   15,  88, 111, 184,   0,   0, & | ||||
|   10,  46, 136, 167, 203,   0, & | ||||
|    9,  75, 132, 169, 178,   0, & | ||||
|   45,  55,  94, 160, 204,   0, & | ||||
|   17,  70, 135, 180,   0,   0, & | ||||
|   14,  89, 118, 146, 195, 200, & | ||||
|   35,  73, 123, 177, 192,   0, & | ||||
|   41,  82, 103, 181, 188,   0, & | ||||
|    3,  90, 134, 170, 183,   0, & | ||||
|    1,  82, 117, 141, 194,   0, & | ||||
|    5,  91, 100, 136, 185,   0, & | ||||
|   39,  77, 114, 160,   0,   0, & | ||||
|   45,  66, 137, 153,   0,   0, & | ||||
|   18,  90, 138, 166,   0,   0, & | ||||
|   20,  85, 124, 152,   0,   0, & | ||||
|   11,  73, 135, 157,   0,   0, & | ||||
|    2,  54, 139, 185,   0,   0, & | ||||
|   44,  85, 138, 146,   0,   0, & | ||||
|   35,  53, 115, 183,   0,   0, & | ||||
|   28,  66, 110, 138, 187,   0, & | ||||
|   44,  75,  95, 167,   0,   0, & | ||||
|   11,  79,  95, 179,   0,   0, & | ||||
|   37,  92, 115, 155,   0,   0, & | ||||
|   27,  56, 130, 165, 186,   0, & | ||||
|    6,  81, 133, 147,   0,   0, & | ||||
|   43,  88, 105, 176,   0,   0, & | ||||
|   26,  78,  96, 175, 181,   0, & | ||||
|   12,  71, 121, 159,   0,   0, & | ||||
|   40,  63, 108, 150, 204,   0, & | ||||
|   13,  93, 127, 178,   0,   0, & | ||||
|   31,  83, 106, 182,   0,   0, & | ||||
|   45,  92, 133, 171, 200,   0, & | ||||
|   17,  51,  89, 184, 202,   0, & | ||||
|   34,  86, 130, 145,   0,   0, & | ||||
|   46,  92, 104, 177, 198,   0, & | ||||
|   31,  76, 132, 172,   0,   0, & | ||||
|    7,  80,  89, 176, 192,   0, & | ||||
|   37,  67, 128, 180, 191,   0, & | ||||
|   24,  83, 116, 142,   0,   0/ | ||||
| 
 | ||||
| data nrw/    & | ||||
|   5,5,5,5,5,5,5,5,6,5,5,5,5,5,5,5,5, & | ||||
|   5,5,5,5,5,5,5,5,4,5,5,4,4,5,5,4,5, & | ||||
|   4,5,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4, & | ||||
|   5,4,4,4,4,4,4,4,4,4,5,5,4,5,4,4,4, & | ||||
|   5,4,4,4,4,5,4,5,4,4,4,4,4,5,5,5,4, & | ||||
|   4,5,4,5,5,4,5,4,5,5,4,4,4,5,5,5,4, & | ||||
|   6,5,5,5,5,5,4,4,4,4,4,4,4,4,5,4,4, & | ||||
|   4,5,4,4,5,4,5,4,4,5,5,4,5,4,5,5,4/ | ||||
| 
 | ||||
| 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:6,i)=tanh(-toc(1:6,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 bpdecode204 | ||||
							
								
								
									
										48
									
								
								lib/fsk4hf/encode204.f90
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								lib/fsk4hf/encode204.f90
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | ||||
| subroutine encode204(message,codeword) | ||||
| ! Encode an 68-bit message and return a 204-bit codeword.  | ||||
| ! The generator matrix has dimensions (136,68).  | ||||
| ! The code is a (204,68) regular ldpc code with column weight 3. | ||||
| ! The code was generated using the PEG algorithm. | ||||
| ! After creating the codeword, the columns are re-ordered according to  | ||||
| ! "colorder" to make the codeword compatible with the parity-check matrix  | ||||
| ! | ||||
| 
 | ||||
| include "ldpc_204_68_params.f90" | ||||
| 
 | ||||
| integer*1 codeword(N) | ||||
| integer*1 gen(M,K) | ||||
| integer*1 itmp(N) | ||||
| integer*1 message(K) | ||||
| integer*1 pchecks(M) | ||||
| logical first | ||||
| data first/.true./ | ||||
| 
 | ||||
| save first,gen | ||||
| 
 | ||||
| if( first ) then ! fill the generator matrix | ||||
|   gen=0 | ||||
|   do i=1,M | ||||
|     do j=1,17 | ||||
|       read(g(i)(j:j),"(Z1)") istr | ||||
|         do jj=1, 4 | ||||
|           icol=(j-1)*4+jj | ||||
|           if( btest(istr,4-jj) ) gen(i,icol)=1 | ||||
|         enddo | ||||
|     enddo | ||||
|   enddo | ||||
| first=.false. | ||||
| endif | ||||
| 
 | ||||
| do i=1,M | ||||
|   nsum=0 | ||||
|   do j=1,K  | ||||
|     nsum=nsum+message(j)*gen(i,j) | ||||
|   enddo | ||||
|   pchecks(i)=mod(nsum,2) | ||||
| enddo | ||||
| itmp(1:M)=pchecks | ||||
| itmp(M+1:N)=message(1:K) | ||||
| codeword(colorder+1)=itmp(1:N) | ||||
| 
 | ||||
| return | ||||
| end subroutine encode204 | ||||
							
								
								
									
										154
									
								
								lib/fsk4hf/ldpc_204_68_params.f90
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								lib/fsk4hf/ldpc_204_68_params.f90
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,154 @@ | ||||
| integer, parameter:: N=204, K=68, M=N-K | ||||
| character*17 g(136) | ||||
| integer colorder(N) | ||||
| data g/                   &  !parity generator matrix for (204,68) code | ||||
|        "2de7435fd27c0031d", & | ||||
|        "f331b40671e20ea80", & | ||||
|        "48bd3f8cb9a24392f", & | ||||
|        "d4ed71c935162aa2a", & | ||||
|        "c437a3284ec58bce7", & | ||||
|        "35a806dd5be35627c", & | ||||
|        "396e797c33a4739a6", & | ||||
|        "768f331a59c15487b", & | ||||
|        "c214eac24ae5e1732", & | ||||
|        "0b5c53ff3a6da1192", & | ||||
|        "99624981d2703fb97", & | ||||
|        "e9f5447ef7f1ff6af", & | ||||
|        "bd8c730f0cfdf0727", & | ||||
|        "26f61e63e1e098f7f", & | ||||
|        "ef826566137b6526f", & | ||||
|        "af0e4fa251e9b4926", & | ||||
|        "75974a8b2a24292c5", & | ||||
|        "71caf0f2cd10f6d4f", & | ||||
|        "b1103f1f26e6898b7", & | ||||
|        "67ceb7d6f490da64f", & | ||||
|        "ee0e8fbefec23008a", & | ||||
|        "11cc2227e8bd676ca", & | ||||
|        "6e71626ba1e278046", & | ||||
|        "005d28da267e50e13", & | ||||
|        "a9ae4a130aaba8219", & | ||||
|        "d8ab72e0158d0da70", & | ||||
|        "56009d42b37bd66ff", & | ||||
|        "c39a75eca99b0e996", & | ||||
|        "6886de0bf7c0bf4bb", & | ||||
|        "1046cd8f64162f7b5", & | ||||
|        "da0f15843ac21e3a5", & | ||||
|        "e9bf9cd19f3db3913", & | ||||
|        "2fb9cb42d650f47a7", & | ||||
|        "a2b6c5a378fa75a65", & | ||||
|        "41a88f3cd60b79d6c", & | ||||
|        "fcf175794cc3ac96a", & | ||||
|        "8677a3447d40a9f71", & | ||||
|        "97a1f08c250b4bf12", & | ||||
|        "0168f090a1df6e8ea", & | ||||
|        "418a06bf372cc67d9", & | ||||
|        "0f17b880c1ff51239", & | ||||
|        "b2afd6d585deb961b", & | ||||
|        "60298ac5b58dbeee0", & | ||||
|        "8350c03c40119feff", & | ||||
|        "b29c964a8accf6af4", & | ||||
|        "9b46f036a5c178b5d", & | ||||
|        "917398bff051c300a", & | ||||
|        "5e52c03b2f8c5128c", & | ||||
|        "beae6c33c87ba38ab", & | ||||
|        "20843f7b056a02ebf", & | ||||
|        "66690d65acd9de598", & | ||||
|        "8f025841af5b54331", & | ||||
|        "b43cd869d3be2c3db", & | ||||
|        "c9c342fe63c18df50", & | ||||
|        "d331b40671e28ea80", & | ||||
|        "62406a0f4947e6ce9", & | ||||
|        "d67b1495883b22e1b", & | ||||
|        "734534c372408895b", & | ||||
|        "d88750e33d9677dcd", & | ||||
|        "6f96964da55138687", & | ||||
|        "80bee98bb75d50ef2", & | ||||
|        "c428ef3e3f06f4c56", & | ||||
|        "b1a1499b125883a35", & | ||||
|        "ac892d4b37fa9e395", & | ||||
|        "458dbda0f95ab11a5", & | ||||
|        "6f93c9e95b1094eed", & | ||||
|        "2e370d713914f848e", & | ||||
|        "758806dd5be35627c", & | ||||
|        "8c52e01caec798b49", & | ||||
|        "c286cc25bae3669cf", & | ||||
|        "87c56fb895c100884", & | ||||
|        "e89cb1376a18fd911", & | ||||
|        "156ffe5f30dc354e0", & | ||||
|        "f20d0b121d6a6b3ee", & | ||||
|        "7db08891b491a95d2", & | ||||
|        "191fac548d5077bdf", & | ||||
|        "023a37d7ea5660bbc", & | ||||
|        "6781668b363fee682", & | ||||
|        "bbfaf262cab7370da", & | ||||
|        "feea557965b7e474f", & | ||||
|        "c094eb223e1d305b8", & | ||||
|        "2be051abdd5beea35", & | ||||
|        "0790449880fda9d00", & | ||||
|        "f9029a39ec869e7b4", & | ||||
|        "5a29f48926ec9a552", & | ||||
|        "e0463306dc1470f87", & | ||||
|        "9251058334d790f86", & | ||||
|        "3019e1d4578e8a4dc", & | ||||
|        "887e46631502fa111", & | ||||
|        "c25fcd7a42465d326", & | ||||
|        "cf64bcc1056b555c4", & | ||||
|        "3e71c0fe5f0ad733b", & | ||||
|        "11055ec43b076e5b2", & | ||||
|        "3440f64dfa3c30a96", & | ||||
|        "2b73885b4d3299f60", & | ||||
|        "2e71627ba1e268046", & | ||||
|        "ad23743d5e6e5b80c", & | ||||
|        "c9757b05f29bfdc10", & | ||||
|        "f7112bea739247b51", & | ||||
|        "3664062387998b2b1", & | ||||
|        "90897a3b8785aefba", & | ||||
|        "29e126e3201fc1d46", & | ||||
|        "96c9001c84d5257fc", & | ||||
|        "067723447d40a9f71", & | ||||
|        "1a019cc68f7511402", & | ||||
|        "4bd48eb2330032763", & | ||||
|        "d139a5da936b37647", & | ||||
|        "765ab46a4dec5f04f", & | ||||
|        "706f475ad19b91955", & | ||||
|        "1755c988fa8a55e5c", & | ||||
|        "2fd9ed5777eb01d6a", & | ||||
|        "bec27d85b954d3fe8", & | ||||
|        "7135a3b92c45b3f8d", & | ||||
|        "353237872f002163a", & | ||||
|        "e31e4a97aef10c729", & | ||||
|        "da527d5e1cbc4edb6", & | ||||
|        "6e33cdede17c3207e", & | ||||
|        "ef2d2062e84dc401f", & | ||||
|        "8217c84c50c1bf833", & | ||||
|        "12ffbac7b2219c9e0", & | ||||
|        "3729178706f66881f", & | ||||
|        "2fdd748c382a608a1", & | ||||
|        "dd0a00076f9dcec73", & | ||||
|        "46b1d37bced447035", & | ||||
|        "7316f33a9c05ef178", & | ||||
|        "152c39a6de8954cc3", & | ||||
|        "16efffb7b62e12ba3", & | ||||
|        "9d9ec2bb467affd83", & | ||||
|        "467723445d40a9f61", & | ||||
|        "87994762b3bf50697", & | ||||
|        "b1bfa5b51526dde9b", & | ||||
|        "b0a6a19d709a96148", & | ||||
|        "990d567c0aba31a14", & | ||||
|        "171f190792461b1e0", & | ||||
|        "166011c27d2b6b8a4", & | ||||
|        "170c15831244ae73e"/ | ||||
| 
 | ||||
| data colorder/                                                              & | ||||
|          0,  1,  2,  3,  4,  5, 47,  6,  7,  8,  9, 10, 11, 12, 58, 55, 13, & | ||||
|         14, 15, 46, 17, 18, 60, 19, 20, 21, 22, 23, 24, 25, 57, 26, 27, 49, & | ||||
|         28, 52, 65, 16, 50, 73, 59, 68, 63, 29, 30, 31, 32, 51, 62, 56, 66, & | ||||
|         45, 33, 34, 53, 67, 35, 36, 37, 61, 69, 54, 38, 71, 82, 39, 77, 80, & | ||||
|         83, 78, 84, 48, 41, 85, 40, 64, 75, 96, 74, 72, 76, 86, 87, 89, 90, & | ||||
|         79, 70, 92, 99, 93,101, 95,100, 97, 94, 42, 98,103,105,102, 43,104, & | ||||
|         88, 44,106, 81,107,110,108,111,112,109,113,114,117,118,116,121,115, & | ||||
|        119,122,120,125,129,124,127,126,128, 91,123,133,131,130,134,135,137, & | ||||
|        136,132,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,174,175,176,177,178,179,180,181,182,183,184,185,186, & | ||||
|        187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203/ | ||||
							
								
								
									
										249
									
								
								lib/fsk4hf/ldpcsim204.f90
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										249
									
								
								lib/fsk4hf/ldpcsim204.f90
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,249 @@ | ||||
| program ldpcsim204 | ||||
| 
 | ||||
| ! End-to-end test of the (300,60)/crc10 encoder and decoders. | ||||
| 
 | ||||
| use crc | ||||
| use packjt | ||||
| 
 | ||||
| parameter(NRECENT=10) | ||||
| character*12 recent_calls(NRECENT) | ||||
| character*8 arg | ||||
| integer*1, allocatable ::  codeword(:), decoded(:), message(:) | ||||
| integer*1, target:: i1Msg8BitBytes(9) | ||||
| integer*1, target:: i1Dec8BitBytes(9) | ||||
| integer*1 msgbits(68) | ||||
| integer*1 apmask(204) | ||||
| integer*1 cw(204) | ||||
| integer*2 checksum | ||||
| integer colorder(204) | ||||
| integer nerrtot(204),nerrdec(204),nmpcbad(68) | ||||
| logical checksumok,fsk,bpsk | ||||
| real*8, allocatable ::  rxdata(:) | ||||
| real, allocatable :: llr(:) | ||||
| real dllr(204),llrd(204) | ||||
| 
 | ||||
| data colorder/                                                              & | ||||
|          0,  1,  2,  3,  4,  5, 47,  6,  7,  8,  9, 10, 11, 12, 58, 55, 13, & | ||||
|         14, 15, 46, 17, 18, 60, 19, 20, 21, 22, 23, 24, 25, 57, 26, 27, 49, & | ||||
|         28, 52, 65, 16, 50, 73, 59, 68, 63, 29, 30, 31, 32, 51, 62, 56, 66, & | ||||
|         45, 33, 34, 53, 67, 35, 36, 37, 61, 69, 54, 38, 71, 82, 39, 77, 80, & | ||||
|         83, 78, 84, 48, 41, 85, 40, 64, 75, 96, 74, 72, 76, 86, 87, 89, 90, & | ||||
|         79, 70, 92, 99, 93,101, 95,100, 97, 94, 42, 98,103,105,102, 43,104, & | ||||
|         88, 44,106, 81,107,110,108,111,112,109,113,114,117,118,116,121,115, & | ||||
|        119,122,120,125,129,124,127,126,128, 91,123,133,131,130,134,135,137, & | ||||
|        136,132,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,174,175,176,177,178,179,180,181,182,183,184,185,186, & | ||||
|        187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203/ | ||||
| 
 | ||||
| do i=1,NRECENT | ||||
|   recent_calls(i)='            ' | ||||
| enddo | ||||
| nerrtot=0 | ||||
| nerrdec=0 | ||||
| nmpcbad=0  ! Used to collect the number of errors in the message+crc part of the codeword | ||||
| 
 | ||||
| nargs=iargc() | ||||
| if(nargs.ne.4) then | ||||
|    print*,'Usage: ldpcsim  niter ndeep  #trials  s ' | ||||
|    print*,'eg:    ldpcsim   100    4     1000    0.84' | ||||
|    print*,'If s is negative, then value is ignored and sigma is calculated from SNR.' | ||||
|    return | ||||
| endif | ||||
| call getarg(1,arg) | ||||
| read(arg,*) max_iterations  | ||||
| call getarg(2,arg) | ||||
| read(arg,*) ndeep | ||||
| call getarg(3,arg) | ||||
| read(arg,*) ntrials  | ||||
| call getarg(4,arg) | ||||
| read(arg,*) s | ||||
| 
 | ||||
| fsk=.false. | ||||
| bpsk=.true. | ||||
| 
 | ||||
| N=204 | ||||
| K=68 | ||||
| rate=real(K)/real(N) | ||||
| 
 | ||||
| write(*,*) "rate: ",rate | ||||
| write(*,*) "niter= ",max_iterations," s= ",s | ||||
| 
 | ||||
| allocate ( codeword(N), decoded(K), message(K) ) | ||||
| allocate ( rxdata(N), llr(N) ) | ||||
| 
 | ||||
| ! The message should be packed into the first 7 bytes | ||||
|   i1Msg8BitBytes(1:6)=85 | ||||
|   i1Msg8BitBytes(7)=64 | ||||
| ! The CRC will be put into the last 2 bytes | ||||
|   i1Msg8BitBytes(8:9)=0 | ||||
|   checksum = crc10 (c_loc (i1Msg8BitBytes), 9) | ||||
| ! For reference, the next 3 lines show how to check the CRC | ||||
|   i1Msg8BitBytes(8)=checksum/256 | ||||
|   i1Msg8BitBytes(9)=iand (checksum,255) | ||||
|   checksumok = crc10_check(c_loc (i1Msg8BitBytes), 9) | ||||
|   if( checksumok ) write(*,*) 'Good checksum' | ||||
| write(*,*) i1Msg8BitBytes(1:9) | ||||
| 
 | ||||
|   mbit=0 | ||||
|   do i=1, 7  | ||||
|     i1=i1Msg8BitBytes(i) | ||||
|     do ibit=1,8 | ||||
|       mbit=mbit+1 | ||||
|       msgbits(mbit)=iand(1,ishft(i1,ibit-8)) | ||||
|     enddo | ||||
|   enddo | ||||
|   i1=i1Msg8BitBytes(8) ! First 2 bits of crc10 are LSB of this byte | ||||
|   do ibit=1,2 | ||||
|     msgbits(50+ibit)=iand(1,ishft(i1,ibit-2)) | ||||
|   enddo | ||||
|   i1=i1Msg8BitBytes(9) ! Now shift in last 8 bits of the CRC | ||||
|   do ibit=1,8 | ||||
|     msgbits(52+ibit)=iand(1,ishft(i1,ibit-8)) | ||||
|   enddo | ||||
| 
 | ||||
|   write(*,*) 'message' | ||||
|   write(*,'(9(8i1,1x))') msgbits | ||||
| 
 | ||||
|   call encode204(msgbits,codeword) | ||||
|   call init_random_seed() | ||||
|   call sgran() | ||||
| 
 | ||||
|   write(*,*) 'codeword'  | ||||
|   write(*,'(204i1)') codeword | ||||
| 
 | ||||
| write(*,*) "Es/N0  SNR2500   ngood  nundetected nbadcrc   sigma" | ||||
| do idb = 20,-18,-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 | ||||
|   ngood=0 | ||||
|   nue=0 | ||||
|   nbadcrc=0 | ||||
|   nberr=0 | ||||
|   do itrial=1, ntrials | ||||
| ! Create a realization of a noisy received word | ||||
|     do i=1,N | ||||
|       if( bpsk ) then | ||||
|         rxdata(i) = 2.0*codeword(i)-1.0 + sigma*gran() | ||||
|       elseif( fsk ) then | ||||
|         if( codeword(i) .eq. 1 ) then | ||||
|           r1=(1.0 + sigma*gran())**2 + (sigma*gran())**2 | ||||
|           r2=(sigma*gran())**2 + (sigma*gran())**2 | ||||
|         elseif( codeword(i) .eq. 0 ) then | ||||
|           r2=(1.0 + sigma*gran())**2 + (sigma*gran())**2 | ||||
|           r1=(sigma*gran())**2 + (sigma*gran())**2 | ||||
|         endif  | ||||
|         rxdata(i)=0.35*(sqrt(r1)-sqrt(r2)) | ||||
| !        rxdata(i)=0.35*(exp(r1)-exp(r2)) | ||||
| !        rxdata(i)=0.12*(log(r1)-log(r2)) | ||||
|       endif | ||||
|     enddo | ||||
|     nerr=0 | ||||
|     do i=1,N | ||||
|       if( rxdata(i)*(2*codeword(i)-1.0) .lt. 0 ) nerr=nerr+1 | ||||
|     enddo | ||||
|     if(nerr.ge.1) nerrtot(nerr)=nerrtot(nerr)+1 | ||||
|     nberr=nberr+nerr | ||||
| 
 | ||||
| ! Correct signal normalization is important for this decoder. | ||||
|     rxav=sum(rxdata)/N | ||||
|     rx2av=sum(rxdata*rxdata)/N | ||||
|     rxsig=sqrt(rx2av-rxav*rxav) | ||||
|     rxdata=rxdata/rxsig | ||||
| ! To match the metric to the channel, s should be set to the noise standard deviation.  | ||||
| ! For now, set s to the value that optimizes decode probability near threshold.  | ||||
| ! The s parameter can be tuned to trade a few tenth's dB of threshold for an order of | ||||
| ! magnitude in UER  | ||||
|     if( s .lt. 0 ) then | ||||
|       ss=sigma | ||||
|     else  | ||||
|       ss=s | ||||
|     endif | ||||
| 
 | ||||
|     llr=2.0*rxdata/(ss*ss) | ||||
|     apmask=0 | ||||
| ! max_iterations is max number of belief propagation iterations | ||||
|     call bpdecode204(llr,apmask,max_iterations,decoded,cw,nharderror,niterations) | ||||
|     if( (nharderror .lt. 0) .and. (ndeep .ge. 0) ) then | ||||
|        call osd204(llr, apmask, ndeep, decoded, cw, nhardmin, dmin) | ||||
|        niterations=nhardmin | ||||
|     endif | ||||
|     n2err=0 | ||||
|     do i=1,N | ||||
|       if( cw(i)*(2*codeword(i)-1.0) .lt. 0 ) n2err=n2err+1 | ||||
|     enddo | ||||
| !write(*,*) nerr,niterations,n2err | ||||
|     damp=0.75 | ||||
|     ndither=0 | ||||
|     if( niterations .lt. 0 ) then | ||||
|       do i=1, ndither | ||||
|         do in=1,N | ||||
|           dllr(in)=damp*gran()   | ||||
|         enddo | ||||
|         llrd=llr+dllr       | ||||
|         call bpdecode300(llrd, apmask, max_iterations, decoded, cw, nharderror, niterations) | ||||
|         if( niterations .ge. 0 ) exit  | ||||
|       enddo | ||||
|     endif   | ||||
| 
 | ||||
| ! If the decoder finds a valid codeword, niterations will be .ge. 0. | ||||
|     if( niterations .ge. 0 ) then | ||||
| ! Check the CRC | ||||
|       do ibyte=1,6 | ||||
|         itmp=0 | ||||
|         do ibit=1,8 | ||||
|           itmp=ishft(itmp,1)+iand(1,decoded((ibyte-1)*8+ibit)) | ||||
|         enddo | ||||
|         i1Dec8BitBytes(ibyte)=itmp | ||||
|       enddo | ||||
|       i1Dec8BitBytes(7)=decoded(49)*128+decoded(50)*64 | ||||
| ! Need to pack the received crc into bytes 8 and 9 for crc10_check | ||||
|       i1Dec8BitBytes(8)=decoded(51)*2+decoded(52) | ||||
|       i1Dec8BitBytes(9)=decoded(53)*128+decoded(54)*64+decoded(55)*32+decoded(56)*16 | ||||
|       i1Dec8BitBytes(9)=i1Dec8BitBytes(9)+decoded(57)*8+decoded(58)*4+decoded(59)*2+decoded(60)*1 | ||||
|       ncrcflag=0 | ||||
|       if( crc10_check( c_loc( i1Dec8BitBytes ), 9 ) ) ncrcflag=1 | ||||
| 
 | ||||
|       if( ncrcflag .ne. 1 ) then | ||||
|         nbadcrc=nbadcrc+1 | ||||
|       endif | ||||
|       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 | ||||
|           nueflag=1 | ||||
|           nerrmpc=nerrmpc+1  | ||||
|         endif | ||||
|       enddo | ||||
|       if(nerrmpc.ge.1) nmpcbad(nerrmpc)=nmpcbad(nerrmpc)+1  ! This histogram should inform our selection of CRC poly | ||||
|       if( ncrcflag .eq. 1 .and. nueflag .eq. 0 ) then | ||||
|         ngood=ngood+1 | ||||
|         if(nerr.ge.1) nerrdec(nerr)=nerrdec(nerr)+1 | ||||
|       else if( ncrcflag .eq. 1 .and. nueflag .eq. 1 ) then | ||||
|         nue=nue+1; | ||||
|       endif | ||||
|     endif | ||||
|   enddo | ||||
|   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 | ||||
| 
 | ||||
| enddo | ||||
| 
 | ||||
| open(unit=23,file='nerrhisto.dat',status='unknown') | ||||
| do i=1,120 | ||||
|   write(23,'(i4,2x,i10,i10,f10.2)') i,nerrdec(i),nerrtot(i),real(nerrdec(i))/real(nerrtot(i)+1e-10) | ||||
| enddo | ||||
| close(23) | ||||
| open(unit=25,file='nmpcbad.dat',status='unknown') | ||||
| do i=1,68 | ||||
|   write(25,'(i4,2x,i10)') i,nmpcbad(i) | ||||
| enddo | ||||
| close(25) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| end program ldpcsim204 | ||||
							
								
								
									
										365
									
								
								lib/fsk4hf/osd204.f90
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										365
									
								
								lib/fsk4hf/osd204.f90
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,365 @@ | ||||
| subroutine osd204(llr,apmask,ndeep,decoded,cw,nhardmin,dmin) | ||||
| ! | ||||
| ! An ordered-statistics decoder for the (204,68) code. | ||||
| !  | ||||
| include "ldpc_204_68_params.f90" | ||||
| 
 | ||||
| integer*1 apmask(N),apmaskr(N) | ||||
| integer*1 gen(K,N) | ||||
| integer*1 genmrb(K,N),g2(N,K) | ||||
| integer*1 temp(K),m0(K),me(K),mi(K),misub(K),e2sub(N-K),e2(N-K),ui(N-K) | ||||
| integer*1 r2pat(N-K) | ||||
| integer indices(N),nxor(N) | ||||
| integer*1 cw(N),ce(N),c0(N),hdec(N) | ||||
| integer*1 decoded(K) | ||||
| integer indx(N) | ||||
| real llr(N),rx(N),absrx(N) | ||||
| logical first,reset | ||||
| data first/.true./ | ||||
| save first,gen | ||||
| 
 | ||||
| if( first ) then ! fill the generator matrix | ||||
|   gen=0 | ||||
|   do i=1,M | ||||
|     do j=1,17 | ||||
|       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,K | ||||
|     gen(irow,M+irow)=1 | ||||
|   enddo | ||||
| first=.false. | ||||
| endif | ||||
| 
 | ||||
| ! Re-order received vector to place systematic msg bits at the end. | ||||
| rx=llr(colorder+1)  | ||||
| apmaskr=apmask(colorder+1) | ||||
| 
 | ||||
| ! Hard decisions on 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 decreasing reliability. | ||||
| do i=1,N | ||||
|   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 in positions 1:K in order of decreasing reliability (more or less).  | ||||
| do id=1,K ! diagonal element indices  | ||||
|   do icol=id,K+20  ! The 20 is ad hoc - beware | ||||
|     iflag=0 | ||||
|     if( genmrb(id,icol) .eq. 1 ) then | ||||
|       iflag=1 | ||||
|       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(id) | ||||
|         indices(id)=indices(icol) | ||||
|         indices(icol)=itmp | ||||
|       endif | ||||
|       do ii=1,K | ||||
|         if( ii .ne. id .and. genmrb(ii,id) .eq. 1 ) then | ||||
|           genmrb(ii,1:N)=ieor(genmrb(ii,1:N),genmrb(id,1:N)) | ||||
|         endif | ||||
|       enddo | ||||
|       exit | ||||
|     endif | ||||
|   enddo | ||||
| enddo | ||||
| 
 | ||||
| g2=transpose(genmrb) | ||||
| 
 | ||||
| ! 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. Return the member of the list that has the smallest Euclidean | ||||
| ! distance to the received word.  | ||||
| 
 | ||||
| hdec=hdec(indices)   ! hard decisions from received symbols | ||||
| m0=hdec(1:K)         ! zero'th order message | ||||
| absrx=absrx(indices)  | ||||
| rx=rx(indices)        | ||||
| apmaskr=apmaskr(indices) | ||||
| 
 | ||||
| call mrbencode(m0,c0,g2,N,K) | ||||
| nxor=ieor(c0,hdec) | ||||
| nhardmin=sum(nxor) | ||||
| dmin=sum(nxor*absrx) | ||||
| 
 | ||||
| cw=c0 | ||||
| ntotal=0 | ||||
| nrejected=0 | ||||
| 
 | ||||
| if(ndeep.eq.0) goto 998  ! norder=0 | ||||
| if(ndeep.gt.5) ndeep=5 | ||||
| if( ndeep.eq. 1) then | ||||
|    nord=1 | ||||
|    npre1=0 | ||||
|    npre2=0 | ||||
|    nt=40 | ||||
|    ntheta=12 | ||||
| elseif(ndeep.eq.2) then | ||||
|    nord=1 | ||||
|    npre1=1 | ||||
|    npre2=0 | ||||
|    nt=40 | ||||
|    ntheta=12 | ||||
| elseif(ndeep.eq.3) then | ||||
|    nord=1 | ||||
|    npre1=1 | ||||
|    npre2=1 | ||||
|    nt=40 | ||||
|    ntheta=12 | ||||
|    ntau=14 | ||||
| elseif(ndeep.eq.4) then | ||||
|    nord=2 | ||||
|    npre1=1 | ||||
|    npre2=0 | ||||
|    nt=40 | ||||
|    ntheta=12 | ||||
|    ntau=19 | ||||
| elseif(ndeep.eq.5) then | ||||
|    nord=2 | ||||
|    npre1=1 | ||||
|    npre2=1 | ||||
|    nt=40 | ||||
|    ntheta=12 | ||||
|    ntau=19 | ||||
| endif | ||||
| 
 | ||||
| do iorder=1,nord | ||||
|    misub(1:K-iorder)=0 | ||||
|    misub(K-iorder+1:K)=1 | ||||
|    iflag=K-iorder+1 | ||||
|    do while(iflag .ge.0) | ||||
|       if(iorder.eq.nord .and. npre1.eq.0) then | ||||
|          iend=iflag | ||||
|       else | ||||
|          iend=1 | ||||
|       endif | ||||
|       do n1=iflag,iend,-1 | ||||
|          mi=misub | ||||
|          mi(n1)=1 | ||||
|          if(any(iand(apmaskr(1:K),mi).eq.1)) cycle | ||||
|          ntotal=ntotal+1 | ||||
|          me=ieor(m0,mi) | ||||
|          if(n1.eq.iflag) then | ||||
|             call mrbencode(me,ce,g2,N,K) | ||||
|             e2sub=ieor(ce(K+1:N),hdec(K+1:N)) | ||||
|             e2=e2sub | ||||
|             nd1Kpt=sum(e2sub(1:nt))+1 | ||||
|             d1=sum(ieor(me(1:K),hdec(1:K))*absrx(1:K)) | ||||
|          else | ||||
|             e2=ieor(e2sub,g2(K+1:N,n1)) | ||||
|             nd1Kpt=sum(e2(1:nt))+2 | ||||
|          endif | ||||
|          if(nd1Kpt .le. ntheta) then | ||||
|             call mrbencode(me,ce,g2,N,K) | ||||
|             nxor=ieor(ce,hdec) | ||||
|             if(n1.eq.iflag) then | ||||
|                dd=d1+sum(e2sub*absrx(K+1:N)) | ||||
|             else | ||||
|                dd=d1+ieor(ce(n1),hdec(n1))*absrx(n1)+sum(e2*absrx(K+1:N)) | ||||
|             endif | ||||
|             if( dd .lt. dmin ) then | ||||
|                dmin=dd | ||||
|                cw=ce | ||||
|                nhardmin=sum(nxor) | ||||
|                nd1Kptbest=nd1Kpt | ||||
|             endif | ||||
|          else  | ||||
|             nrejected=nrejected+1 | ||||
|          endif | ||||
|       enddo | ||||
| ! Get the next test error pattern, iflag will go negative | ||||
| ! when the last pattern with weight iorder has been generated. | ||||
|       call nextpat(misub,k,iorder,iflag) | ||||
|    enddo | ||||
| enddo | ||||
| 
 | ||||
| if(npre2.eq.1) then | ||||
|    reset=.true. | ||||
|    ntotal=0 | ||||
|    do i1=K,1,-1 | ||||
|       do i2=i1-1,1,-1 | ||||
|          ntotal=ntotal+1 | ||||
|          mi(1:ntau)=ieor(g2(K+1:K+ntau,i1),g2(K+1:K+ntau,i2)) | ||||
|          call boxit(reset,mi(1:ntau),ntau,ntotal,i1,i2) | ||||
|       enddo | ||||
|    enddo | ||||
| 
 | ||||
|    ncount2=0 | ||||
|    ntotal2=0 | ||||
|    reset=.true. | ||||
| ! Now run through again and do the second pre-processing rule | ||||
|    misub(1:K-nord)=0 | ||||
|    misub(K-nord+1:K)=1 | ||||
|    iflag=K-nord+1 | ||||
|    do while(iflag .ge.0) | ||||
|       me=ieor(m0,misub) | ||||
|       call mrbencode(me,ce,g2,N,K) | ||||
|       e2sub=ieor(ce(K+1:N),hdec(K+1:N)) | ||||
|       do i2=0,ntau | ||||
|          ntotal2=ntotal2+1 | ||||
|          ui=0  | ||||
|          if(i2.gt.0) ui(i2)=1  | ||||
|          r2pat=ieor(e2sub,ui) | ||||
| 778      continue  | ||||
|             call fetchit(reset,r2pat(1:ntau),ntau,in1,in2) | ||||
|             if(in1.gt.0.and.in2.gt.0) then | ||||
|                ncount2=ncount2+1 | ||||
|                mi=misub                | ||||
|                mi(in1)=1 | ||||
|                mi(in2)=1 | ||||
|                if(sum(mi).lt.nord+npre1+npre2.or.any(iand(apmaskr(1:K),mi).eq.1)) cycle | ||||
|                me=ieor(m0,mi) | ||||
|                call mrbencode(me,ce,g2,N,K) | ||||
|                nxor=ieor(ce,hdec) | ||||
|                dd=sum(nxor*absrx) | ||||
|                if( dd .lt. dmin ) then | ||||
|                   dmin=dd | ||||
|                   cw=ce | ||||
|                   nhardmin=sum(nxor) | ||||
|                endif | ||||
|                goto 778 | ||||
|              endif | ||||
|       enddo | ||||
|       call nextpat(misub,K,nord,iflag) | ||||
|    enddo | ||||
| endif | ||||
| 
 | ||||
| 998 continue | ||||
| ! Re-order the codeword to place message bits at the end. | ||||
| cw(indices)=cw | ||||
| hdec(indices)=hdec | ||||
| decoded=cw(M+1:N)  | ||||
| cw(colorder+1)=cw ! put the codeword back into received-word order | ||||
| return | ||||
| end subroutine osd204 | ||||
| 
 | ||||
| subroutine mrbencode(me,codeword,g2,N,K) | ||||
| integer*1 me(K),codeword(N),g2(N,K) | ||||
| ! fast encoding for low-weight test patterns | ||||
|   codeword=0 | ||||
|   do i=1,K | ||||
|     if( me(i) .eq. 1 ) then | ||||
|       codeword=ieor(codeword,g2(1:N,i)) | ||||
|     endif | ||||
|   enddo | ||||
| return | ||||
| end subroutine mrbencode | ||||
| 
 | ||||
| subroutine nextpat(mi,k,iorder,iflag) | ||||
|   integer*1 mi(k),ms(k) | ||||
| ! generate the next test error pattern | ||||
|   ind=-1 | ||||
|   do i=1,k-1 | ||||
|      if( mi(i).eq.0 .and. mi(i+1).eq.1) ind=i  | ||||
|   enddo | ||||
|   if( ind .lt. 0 ) then ! no more patterns of this order | ||||
|     iflag=ind | ||||
|     return | ||||
|   endif | ||||
|   ms=0 | ||||
|   ms(1:ind-1)=mi(1:ind-1) | ||||
|   ms(ind)=1 | ||||
|   ms(ind+1)=0 | ||||
|   if( ind+1 .lt. k ) then | ||||
|      nz=iorder-sum(ms) | ||||
|      ms(k-nz+1:k)=1 | ||||
|   endif | ||||
|   mi=ms | ||||
|   do i=1,k  ! iflag will point to the lowest-index 1 in mi | ||||
|     if(mi(i).eq.1) then | ||||
|       iflag=i  | ||||
|       exit | ||||
|     endif | ||||
|   enddo | ||||
|   return | ||||
| end subroutine nextpat | ||||
| 
 | ||||
| subroutine boxit(reset,e2,ntau,npindex,i1,i2) | ||||
|   integer*1 e2(1:ntau) | ||||
|   integer   indexes(4000,2),fp(0:525000),np(4000) | ||||
|   logical reset | ||||
|   common/boxes/indexes,fp,np | ||||
| 
 | ||||
|   if(reset) then | ||||
|     patterns=-1 | ||||
|     fp=-1 | ||||
|     np=-1 | ||||
|     sc=-1 | ||||
|     indexes=-1 | ||||
|     reset=.false. | ||||
|   endif | ||||
|   | ||||
|   indexes(npindex,1)=i1 | ||||
|   indexes(npindex,2)=i2 | ||||
|   ipat=0 | ||||
|   do i=1,ntau | ||||
|     if(e2(i).eq.1) then | ||||
|       ipat=ipat+ishft(1,ntau-i) | ||||
|     endif | ||||
|   enddo | ||||
| 
 | ||||
|   ip=fp(ipat)   ! see what's currently stored in fp(ipat) | ||||
|   if(ip.eq.-1) then | ||||
|     fp(ipat)=npindex | ||||
|   else | ||||
|      do while (np(ip).ne.-1) | ||||
|       ip=np(ip)  | ||||
|      enddo   | ||||
|      np(ip)=npindex | ||||
|   endif | ||||
|   return | ||||
| end subroutine boxit | ||||
| 
 | ||||
| subroutine fetchit(reset,e2,ntau,i1,i2) | ||||
|   integer   indexes(4000,2),fp(0:525000),np(4000) | ||||
|   integer   lastpat | ||||
|   integer*1 e2(ntau) | ||||
|   logical reset | ||||
|   common/boxes/indexes,fp,np | ||||
|   save lastpat,inext | ||||
| 
 | ||||
|   if(reset) then | ||||
|     lastpat=-1 | ||||
|     reset=.false. | ||||
|   endif | ||||
| 
 | ||||
|   ipat=0 | ||||
|   do i=1,ntau | ||||
|     if(e2(i).eq.1) then | ||||
|       ipat=ipat+ishft(1,ntau-i) | ||||
|     endif | ||||
|   enddo | ||||
|   index=fp(ipat) | ||||
| 
 | ||||
|   if(lastpat.ne.ipat .and. index.gt.0) then ! return first set of indices | ||||
|      i1=indexes(index,1) | ||||
|      i2=indexes(index,2) | ||||
|      inext=np(index) | ||||
|   elseif(lastpat.eq.ipat .and. inext.gt.0) then | ||||
|      i1=indexes(inext,1) | ||||
|      i2=indexes(inext,2) | ||||
|      inext=np(inext) | ||||
|   else | ||||
|      i1=-1 | ||||
|      i2=-1 | ||||
|      inext=-1 | ||||
|   endif | ||||
|   lastpat=ipat | ||||
|   return | ||||
| end subroutine fetchit | ||||
|   | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user