CSS product code  0.1
C++ library to estimate distance of CSS codes. Some particular construction of CSS codes are implemented.
bp_decoder.h
Go to the documentation of this file.
1 //Weilei Zeng, April 8 , 2020
2 //copied from bp.c
3 
4 //#include "weilei_lib/my_lib.h"
5 #include "dist.h"
6 #include <itpp/itbase.h>
7 //#include <itpp/itcomm.h>
8 //#include <stdio.h>
9 //#include "weilei_lib.h"
10 //#include <cmath>
11 #include <stdexcept> //for invalid argument
12 
13 
14 int summation(itpp::bvec u){
15  int result = 0;
16  for ( int i=0; i<u.size(); i++){
17  if (u(i)) result ++;
18  }
19  return result;
20 }
21 
22 
23 class BP_Decoder{
24  public:
25  bool silent_mode = false;//not is use
26  bool debug = false;
27  const double INF_BP=10000;
28  itpp::GF2mat H;//parity check matrix
30  double alpha=1.0; // used for normalized decoder, alpha=1.25
31  int decode_mode = 2;
32  std::string decode_mode_str="min sum";
33  int nvar, ncheck, nedge;
34 
35  bool is_initialized=false;
36  bool is_H_valid(itpp::GF2mat H_temp);
37  void init(itpp::GF2mat H_temp);
38 
39  void set_exit_iteration(int exit_iteration_temp);
40  void set_decode_mode(int decode_mode_temp);
41  void set_decode_mode_str(std::string decode_mode_str_temp);
42  void set_silent_mode(bool silent_mode_temp);
43  void set_debug_mode(bool debug_mode_temp);
44  void print_info();
45 
46 
47  int decode(itpp::bvec syndrome, const itpp::vec & LLRin, itpp::vec &LLRout);
48  int bp_syndrome_llr(itpp::bvec syndrome, const itpp::vec & LLRin, itpp::vec & LLRout);
49  int bp_schedule(itpp::bvec syndrome, const itpp::vec & LLRin, itpp::vec & LLRout);
50  bool match_syndrome(itpp::vec LLR, itpp::bvec syndrome);
51  int bp_flexible( itpp::bvec syndrome, const itpp::vec & LLRin, itpp::vec & LLRout);
52 
54  std::string schedule_mode_str="no schedule, parallel";
55  itpp::mat schedule;
56  void set_schedule_mode(int schedule_mode_temp);
57  // void set_schedule(int schedule_mode_temp);
58 };
59 
60 void BP_Decoder::set_silent_mode(bool silent_mode_temp){
61  silent_mode = silent_mode_temp;
62  return;
63 }
64 void BP_Decoder::set_debug_mode(bool debug_mode_temp){
65  debug = debug_mode_temp;
66  return;
67 }
68 
69 
70 bool BP_Decoder::is_H_valid(itpp::GF2mat H_temp){
71  //check degree >=2
72  for ( int i =0; i<H_temp.rows();i++){
73  if ( summation(H_temp.get_row(i)) < 2 ) return false;
74  }
75  //variable degree >=1
76  for ( int j = 0; j< H_temp.cols(); j++){
77  if ( summation(H_temp.get_col(j)) < 1 ) return false;
78  }
79  return true;
80 }
81 
82 void BP_Decoder::init(itpp::GF2mat H_temp){
83  //set up parity check matrix
84  H = H_temp;
85  nvar = H.cols();
86  ncheck = H.rows();
87  if ( ! is_H_valid(H) ) throw std::invalid_argument( "BP_Decoder: invalid parity check matrix H" );
88  is_initialized = true;
89  nedge=0;
90  for ( int i =0; i<ncheck; i++){
91  for ( int j = 0; j<nvar;j++){
92  if (H(i,j)) nedge++;
93  }
94  }
95  return;
96 }
97 
99  if (is_initialized){
100  std::cout<<"--- BP_Decoder --- nvar = "<<nvar
101  <<", ncheck ="<<ncheck
102  <<", schedule_mode ("<<schedule_mode<<") "<<schedule_mode_str.c_str()
103  <<", decode mode ("<<decode_mode<<") "<<decode_mode_str.c_str()
104  <<", exit_iteration = "<<exit_iteration
105  <<std::endl;
106 
107  }else{
108  std::cout<<"decoder is not initialized"<<std::endl;
109  }
110  return;
111 
112 }
113 
114 void BP_Decoder::set_exit_iteration(int exit_iteration_temp){
115  exit_iteration = exit_iteration_temp;
116  return;
117 }
118 
119 
120 
121 
122 void BP_Decoder::set_decode_mode(int decode_mode_temp){
123  decode_mode = decode_mode_temp;
124  alpha=1.0;//reset first
125  switch (decode_mode_temp){
126  case 1:
127  decode_mode_str = "standard";
128  break;
129  case 2:
130  decode_mode_str = "min sum";
131  break;
132  case 3:// part of min sum, just change alpha
133  decode_mode_str = "normalization";
134  alpha = 1.25;
135  break;
136  default:
137  throw std::invalid_argument( "BP_Decoder: illegal decode mode" );
138  }
139  std::cout<<"BP_Dcoder: set decode mode "<<decode_mode<<" - "<<decode_mode_str.c_str()<<std::endl;
140  return;
141 }
142 
143 
144 void BP_Decoder::set_decode_mode_str(std::string decode_mode_str_temp){
145  decode_mode_str = decode_mode_str_temp;
146  if (decode_mode_str_temp =="standard") decode_mode = 1;
147  else if (decode_mode_str_temp == "min sum") decode_mode = 2;
148  else if (decode_mode_str_temp == "normalization") decode_mode = 3;
149  else throw std::invalid_argument( "BP_Decoder: illegal decode mode string" );
150 
151  if (debug) std::cout<<"BP_Dcoder: set decode mode "<<decode_mode<<" - "<<decode_mode_str.c_str()<<std::endl;
152  return;
153 }
154 
155 void BP_Decoder::set_schedule_mode(int schedule_mode_temp){
156  schedule_mode = schedule_mode_temp;
157  int s;
158  //schedule mode is used in decode();
159  switch ( schedule_mode ){
160  case 0:
161  //no schedule, parrallel schedule
162  // set_decode_mode_str("standard");
163  schedule_mode_str = "no schedule, parallel; using bp_syndrome_llr()";
164  break;
165  case 1: // default schedule mode 1, edge by edge
166  //set_decode_mode_str("standard");
167  schedule_mode_str = "edge by edge, using bp_schedule()";
168  break;
169  case 2: //flexible
170  {// edge by edge
171  schedule_mode_str ="edge by edge, using bp_flexible()";
172  schedule.set_size(2*nedge,3);
173  schedule.zeros();
174  s=0;
175  for ( int i =0; i<ncheck; i++ ){
176  for ( int j = 0; j<nvar; j ++){
177  if (H(i,j)){
178  // 0 for c->v, 1 for v->c
179  schedule.set(s,0,0);
180  schedule.set(s,1,i);
181  schedule.set(s,2,j);
182  schedule.set(s+1,0,1);
183  schedule.set(s+1,1,i);
184  schedule.set(s+1,2,j);
185  s +=2;
186  }
187  }
188  }
189  break;
190  }
191  case 3: //flexible
192  { // edge by edge, switch var and check
193  schedule_mode_str ="edge by edge, switch var and check order. using bp_flexible()";
194  schedule.set_size(2*nedge,3);
195  schedule.zeros();
196  s=0;
197  for ( int j = 0; j<nvar; j ++){
198  for ( int i =0; i<ncheck; i++ ){
199  if (H(i,j)){
200  schedule.set(s,0,0);
201  schedule.set(s,1,i);
202  schedule.set(s,2,j);
203  schedule.set(s+1,0,1);
204  schedule.set(s+1,1,i);
205  schedule.set(s+1,2,j);
206  s +=2;
207  }
208  }
209  }
210  break;
211  }
212  case 4: //flexible
213  { // random
215  schedule_mode = 4;
216  schedule_mode_str ="random purterbation of of mode 2, using bp_flexible()";
217  //random permutate
218  int permutation=2*nedge;//number of swaps
219  itpp::RNG_randomize();//get randome seed
220  itpp::ivec source=itpp::randi(permutation,0,nedge*2-1);
221  itpp::ivec target=itpp::randi(permutation,0,nedge*2-1);
222  for ( int i =0; i< permutation; i++){
223  schedule.swap_rows(source(i),target(i));
224  }
225  break;
226  }
227  case 5: //flexible
228  { // edge by edge,
229  schedule_mode_str ="edge by edge, follow the paper. using bp_flexible()";
230  schedule.set_size(2*nedge,3);
231  schedule.zeros();
232  s=0;
233  std::cout<<"start updating schedule"<<std::endl;
234  for ( int j = 0; j<nvar; j ++){
235  for ( int i =0; i<ncheck; i++ ){
236  if (H(i,j)){
237  schedule.set(s,0,0);
238  schedule.set(s,1,i);
239  schedule.set(s,2,j);
240  s ++;
241  }
242  }
243  for ( int i =0; i<ncheck; i++ ){
244  if (H(i,j)){
245  schedule.set(s,0,1);
246  schedule.set(s,1,i);
247  schedule.set(s,2,j);
248  s ++;
249  }
250  }
251  }
252  std::cout<<"finish updating schedule"<<std::endl;
253  break;
254  }
255 
256  default:
257  throw std::invalid_argument( "BP_Decoder: illegal schedule" );
258  }
259  return;
260 }
261 
262 
263 int BP_Decoder::decode( itpp::bvec syndrome, const itpp::vec & LLRin, itpp::vec & LLRout){
264  // a wrapper to determine using which decoding function
265  switch ( schedule_mode){
266  case 0: // no schedule
267  return bp_syndrome_llr(syndrome, LLRin, LLRout);
268  case 1://same position for u and v, one by one
269  return bp_schedule( syndrome, LLRin, LLRout);
270  case 2://same position for u and v, one by one
271  case 3://same position for v and u, one by one,
272  case 4: //random permutation of case 2
273  case 5: //follow the paper
274  return bp_flexible( syndrome, LLRin, LLRout);
275  default:
276  throw std::invalid_argument( "BP_Decoder: illegal schedule" );
277  //return bp_syndrome_llr(syndrome, LLRin, LLRout);
278  }
279 }
280 
281 bool BP_Decoder::match_syndrome(itpp::vec LLR, itpp::bvec syndrome){
282  itpp::bvec error = LLR < 0;
283  return itpp::GF2mat(H*error - syndrome).is_zero();
284 }
285 
286 //int BP_Decoder::bp_syndrome_llr(const GF2mat H, itpp::bvec syndrome, itpp::vec & LLRin, itpp::vec & LLRout, int exit_iteration, int decode_mode){
287 int BP_Decoder::bp_syndrome_llr( itpp::bvec syndrome, const itpp::vec & LLRin, itpp::vec & LLRout){
288  // input: syndrome vector s, loglikelihood ratio LLRin and LLRout
289  // exit_iteration: max number of iteration
290  // decode_mode 1: standard, 2: min sum
291  //LLR(x) = log( p(x)/ (1-p(x)) )
292  // initially we assume zero error, so LLR = LLR(0)=log ( (1-p)/p )>0
293  // bits_out = LLRout < 0;
294  //output: number of iteration, negative if not converge.
295 
296  if ( itpp::GF2mat(syndrome).is_zero() ){
297  //return zero error vector, which is the default input for LLRout
298  return 1;
299  }
300 
301  // bool debug = false;// enable/disable printing
302  //initialize
303  //int nvar = H.cols(), ncheck = H.rows();
304  if (debug) std::cout<<"nvar = "<<nvar <<", ncheck = "<<ncheck<<std::endl;
305  itpp::mat llrs = itpp::zeros(ncheck, nvar), LLRs = itpp::zeros(ncheck, nvar);
306  //LLRout.set_size(nvar);should be the same size
307  // bool match_syndrome = false;// a flag to indicate whether the syndrome has been satisfied
308 
309  for ( int i = 0; i< ncheck ; i++){
310  for ( int j=0; j<nvar; j++){
311  if (H(i,j)) {
312  llrs.set(i,j,LLRin(j));
313  //llrs.set(i,j,log( (1-p)/p ));
314  }
315  }
316  }
317  // if (debug) std::cout<<"finish initialize"<<std::endl;
318 
319  int update_count=0;
320  double sum=0;
321  double llr,LLR;
322  std::string str="";
323  int sign = 1;
324  double prod=1.0;
325  // bool degree_one=true;
326  while ( update_count < exit_iteration ){
327  //check to variable update, LLR
328  switch (decode_mode){
329  case 1://standard
330  for ( int i = 0; i< ncheck ; i++){
331  for ( int j=0; j<nvar; j++){
332  if (H(i,j)) {
333  prod=1.0;
334  str = "prod list: i,j,k,prod,llr:";
335  for ( int k=0; k<nvar; k++){
336  if ( H(i,k) ){
337  if ( k != j ) {
338  prod = prod * tanh( llrs(i,k)/2 );
339  str += std::to_string(i)+",";
340  str += std::to_string(j)+",";
341  str += std::to_string(k)+",";
342  str += std::to_string(prod)+",";
343  str += std::to_string(llrs(i,k))+",";
344  //if (debug) std::cout<<",prod = "<<prod<<" i="<<i <<std::endl;
345  }
346  }
347  }
348 
349  LLR = atanh(prod)*2;
350  if ( syndrome(i) ){
351  LLR = -LLR;
352  }
353  LLRs.set(i,j,LLR);
354 
355  if (debug) if ( std::abs(LLR) > 1000000.0) std::cout<<"LLRs: LLR = "<<LLR<<", prod = "<<prod<<"\n"<<str<<std::endl<<"H.get_row(i)="<<H.get_row(i)<<std::endl <<"llrs.get_row(i)="<<llrs.get_row(i)<<std::endl;
356  }
357  }
358  }
359  case 2://min sum
360  for ( int i = 0; i< ncheck ; i++){
361  for ( int j=0; j<nvar; j++){
362  if (H(i,j)) {
363  prod=INF_BP;
364  sign = 1;
365  // str = "prod list: i,j,k,prod,llr:";
366  for ( int k=0; k<nvar; k++){
367  if ( H(i,k) ){
368  if ( k != j ) {
369  if (llrs(i,k)>0){
370  llr = llrs(i,k);
371  }else{
372  llr = -llrs(i,k);
373  sign = -sign;
374  }
375  prod = (llr < prod) ? llr: prod;//min( prod, llr);
376 
377  // prod = prod * tanh( llrs(i,k)/2 );
378  /*str += std::to_string(i)+",";
379  str += std::to_string(j)+",";
380  str += std::to_string(k)+",";
381  str += std::to_string(prod)+",";
382  str += std::to_string(llrs(i,k))+",";*/
383  //if (debug) std::cout<<",prod = "<<prod<<" i="<<i <<std::endl;
384  }
385  }
386  }
387  LLR = sign * prod;
388  // double LLR = atanh(prod)*2;
389  if ( syndrome(i) ){
390  LLR = -LLR;
391  }
392  LLRs.set(i,j,LLR);
393 
394  if (debug) if ( std::abs(LLR) > INF_BP ) std::cout<<"LLRs: LLR = "<<LLR<<", prod = "<<prod<<"\n"<<str<<std::endl<<"H.get_row(i)="<<H.get_row(i)<<std::endl <<"llrs.get_row(i)="<<llrs.get_row(i)<<std::endl;
395  }
396  }
397  }
398  }
399 
400  // if (debug) std::cout<<"finish check to variable update"<<std::endl;
401  //variable to check update, llr
402 
403 
404 
405  for ( int i = 0; i< ncheck ; i++){
406  for ( int j=0; j<nvar; j++){
407  if (H(i,j)) {
408  sum= LLRin(j);
409 
410  for ( int t=0; t<ncheck; t++){
411  if ( H(t,j) ){
412  if ( t != i ) {
413  sum += LLRs(t,j);
414 
415  }
416  }
417  }
418  llrs.set(i,j,sum);
419  // if ( std::abs(sum) > 1000) std::cout<<"llrs: sum = "<<sum<<"\n"<<LLRs.get_col(j)<<std::endl;
420  }
421 
422  }
423  }
424 
425  // if (debug) std::cout<<"finish variable to checkupdate"<<std::endl;
426 
427  // get output LLRout and check result
428  // match_syndrome = true;
429  for ( int j=0; j<nvar; j++){
430  sum=LLRin(j);
431  //if (debug) std::cout<<" sum = "<<sum<<std::endl;
432  for ( int t=0; t<ncheck; t++){
433  //if (debug) std::cout<<"t = "<<t<<", sum = "<<sum<<std::endl;
434  if ( H(t,j) ){
435  sum += LLRs(t,j);
436  }
437  }
438  //if (debug) std::cout<<"LLRout = "<<LLRout<<std::endl;
439  LLRout.set(j,sum);
440  }
441  if (debug) std::cout<<"update_count = "<<update_count<<", LLRout = "<<floor(LLRout)<<std::endl ;
442  //if (debug) std::cout<<"update_count = "<<update_count<<std::endl;
443  //if (debug) draw_toric_x_error(LLRout<0);
444  update_count++;
445  if ( match_syndrome( LLRout, syndrome) ){
446  break;
447  }
448  }
449 
450  if (debug) std::cout<<"LLRout = "<<LLRout<<std::endl;
451 
452  // if (debug) std::cout<<"llrs = "<<llrs<<std::endl;
453  //if (debug) std::cout<<"LLRs = "<<LLRs<<std::endl;
454 
455  //not converge, output negative value
456  if (! match_syndrome( LLRout, syndrome) ){
457  update_count = - update_count;
458  }
459 
460  return update_count ;
461 }
462 
463 
464 int BP_Decoder::bp_schedule( itpp::bvec syndrome, const itpp::vec & LLRin, itpp::vec & LLRout){
465  // input: syndrome vector s, loglikelihood ratio LLRin and LLRout
466  // exit_iteration: max number of iteration
467  // decode_mode 1: standard, 2: min sum
468  //LLR(x) = log( p(x)/ (1-p(x)) )
469  // initially we assume zero error, so LLR = LLR(0)=log ( (1-p)/p )>0
470  // bits_out = LLRout < 0;
471  //output: number of iteration, negative if not converge.
472 
473  if ( itpp::GF2mat(syndrome).is_zero() ){
474  //return zero error vector, which is the default input for LLRout
475  return 1;
476  }
477 
478  // bool debug = false;// enable/disable printing
479  //initialize
480  //int nvar = H.cols(), ncheck = H.rows();
481  if (debug) std::cout<<"nvar = "<<nvar <<", ncheck = "<<ncheck<<std::endl;
482  itpp::mat llrs = itpp::zeros(ncheck, nvar), LLRs = itpp::zeros(ncheck, nvar);
483  //LLRout.set_size(nvar);should be the same size
484  // bool match_syndrome = false;// a flag to indicate whether the syndrome has been satisfied
485 
486  for ( int i = 0; i< ncheck ; i++){
487  for ( int j=0; j<nvar; j++){
488  if (H(i,j)) {
489  llrs.set(i,j,LLRin(j));
490  //llrs.set(i,j,log( (1-p)/p ));
491  }
492  }
493  }
494  // if (debug) std::cout<<"finish initialize"<<std::endl;
495 
496  // *********************************
497  int update_count=0;
498  double sum=0;
499  double LLR;//llr is not used yet
500  std::string str="";
501  // int sign; //not used yet
502  double prod=1.0;
503  // bool degree_one=true;
504  while ( update_count < exit_iteration ){
505  //check to variable update, LLR
506  //use standard updating rule, no min sum
507  for ( int i = 0; i< ncheck ; i++){
508  for ( int j=0; j<nvar; j++){
509  if (H(i,j)) {
510  prod=1.0;
511  // str = "prod list: i,j,k,prod,llr:";
512  for ( int k=0; k<nvar; k++){
513  if ( H(i,k) ){
514  if ( k != j ) {
515  prod = prod * tanh( llrs(i,k)/2 );
516  /*str += std::to_string(i)+",";
517  str += std::to_string(j)+",";
518  str += std::to_string(k)+",";
519  str += std::to_string(prod)+",";
520  str += std::to_string(llrs(i,k))+",";*/
521  //if (debug) std::cout<<",prod = "<<prod<<" i="<<i <<std::endl;
522  }
523  }
524  }
525 
526  LLR = atanh(prod)*2;
527  if ( syndrome(i) ){
528  LLR = -LLR;
529  }
530  LLRs.set(i,j,LLR);
531 
532  if (debug) if ( std::abs(LLR) > 1000000.0) std::cout<<"LLRs: LLR = "<<LLR<<", prod = "<<prod<<"\n"<<str<<std::endl<<"H.get_row(i)="<<H.get_row(i)<<std::endl <<"llrs.get_row(i)="<<llrs.get_row(i)<<std::endl;
533  //}
534  //}
535  //}
536 
537 
538  // for ( int i = 0; i< ncheck ; i++){
539  //for ( int j=0; j<nvar; j++){
540  //if (H(i,j)) {
541  sum= LLRin(j);
542  for ( int t=0; t<ncheck; t++){
543  if ( H(t,j) ){
544  if ( t != i ) {
545  sum += LLRs(t,j);
546 
547  }
548  }
549  }
550  llrs.set(i,j,sum);
551  // if ( std::abs(sum) > 1000) std::cout<<"llrs: sum = "<<sum<<"\n"<<LLRs.get_col(j)<<std::endl;
552  }
553 
554  }
555  }
556 
557  // if (debug) std::cout<<"finish variable to checkupdate"<<std::endl;
558 
559  // get output LLRout and check result
560  // match_syndrome = true;
561  for ( int j=0; j<nvar; j++){
562  sum=LLRin(j);
563  //if (debug) std::cout<<" sum = "<<sum<<std::endl;
564  for ( int t=0; t<ncheck; t++){
565  //if (debug) std::cout<<"t = "<<t<<", sum = "<<sum<<std::endl;
566  if ( H(t,j) ){
567  sum += LLRs(t,j);
568  }
569  }
570  //if (debug) std::cout<<"LLRout = "<<LLRout<<std::endl;
571  LLRout.set(j,sum);
572  }
573  if (debug) std::cout<<"update_count = "<<update_count<<", LLRout = "<<floor(LLRout)<<std::endl ;
574  //if (debug) std::cout<<"update_count = "<<update_count<<std::endl;
575  //if (debug) draw_toric_x_error(LLRout<0);
576  update_count++;
577  if ( match_syndrome( LLRout, syndrome) ){
578  break;
579  }
580  }
581 
582  if (debug) std::cout<<"LLRout = "<<LLRout<<std::endl;
583 
584  // if (debug) std::cout<<"llrs = "<<llrs<<std::endl;
585  //if (debug) std::cout<<"LLRs = "<<LLRs<<std::endl;
586 
587  //not converge, output negative value
588  if (! match_syndrome( LLRout, syndrome) ){
589  update_count = - update_count;
590  }
591 
592  return update_count ;
593 
594 }
595 
596 
597 int BP_Decoder::bp_flexible( itpp::bvec syndrome, const itpp::vec & LLRin, itpp::vec & LLRout){
598  // a flexible function to encorporate all variations
599  // input: syndrome vector s, loglikelihood ratio LLRin and LLRout
600  // exit_iteration: max number of iteration
601  // decode_mode 1: standard, 2: min sum
602  //LLR(x) = log( p(x)/ (1-p(x)) )
603  // initially we assume zero error, so LLR = LLR(0)=log ( (1-p)/p )>0
604  // bits_out = LLRout < 0;
605  //output: number of iteration, negative if not converge.
606 
607  if ( itpp::GF2mat(syndrome).is_zero() ) return 1;
608  //return zero error vector, which is the default input for LLRout
609 
610  //initialize
611  if (debug) std::cout<<"nvar = "<<nvar <<", ncheck = "<<ncheck<<std::endl;
612  itpp::mat llrs = itpp::zeros(ncheck, nvar), LLRs = itpp::zeros(ncheck, nvar);
613  //LLRout.set_size(nvar);should be the same size
614 
615  for ( int i = 0; i< ncheck ; i++){
616  for ( int j=0; j<nvar; j++){
617  if (H(i,j)) {
618  llrs.set(i,j,LLRin(j));
619  //llrs.set(i,j,log( (1-p)/p ));
620  }
621  }
622  }
623 
624  // ********************************* start updating cycle
625  int update_count=0;
626  double sum=0;
627  double LLR, llr;
628  std::string str="";
629  int sign;
630  double prod=1.0;
631  while ( update_count < exit_iteration ){
632  int i,j;
633  for ( int is = 0; is < nedge*2; is ++){
634  i = schedule(is,1);
635  j = schedule(is,2);
636  // for ( int i = 0; i< ncheck ; i++){
637  //for ( int j=0; j<nvar; j++){
638  int direction = schedule(is,0);
639  switch ( direction ){
640  case 0: //check to variable update, LLR
641  {
642  switch ( decode_mode ) {
643  case 1: //standard
644  {
645  prod=1.0;
646  for ( int k=0; k<nvar; k++){
647  if ( H(i,k) ){
648  if ( k != j ) prod = prod * tanh( llrs(i,k)/2 );
649  }
650  }
651 
652  LLR = atanh(prod)*2;
653  if ( syndrome(i) ) LLR = -LLR;
654  LLRs.set(i,j,LLR);
655 
656  if (debug) if ( std::abs(LLR) > 1000000.0) std::cout<<"LLRs: LLR = "<<LLR<<", prod = "<<prod<<"\n"<<str<<std::endl<<"H.get_row(i)="<<H.get_row(i)<<std::endl <<"llrs.get_row(i)="<<llrs.get_row(i)<<std::endl;
657  break;
658  }
659 
660  case 2://min sum
661  // for ( int i = 0; i< ncheck ; i++){
662  //for ( int j=0; j<nvar; j++){
663  // if (H(i,j)) {
664  {
665  prod=INF_BP;
666  sign = 1;
667  // str = "prod list: i,j,k,prod,llr:";
668  for ( int k=0; k<nvar; k++){
669  if ( H(i,k) ){
670  if ( k != j ) {
671  if (llrs(i,k)>0){
672  llr = llrs(i,k);
673  }else{
674  llr = -llrs(i,k);
675  sign = -sign;
676  }
677  prod = (llr<prod) ? llr:prod;//min( prod, llr);
678  }
679  }
680  }
681  LLR = sign * prod;
682  if ( syndrome(i) ) LLR = -LLR;
683  LLRs.set(i,j,LLR);
684 
685  if (debug) if ( std::abs(LLR) > INF_BP ) std::cout<<"LLRs: LLR = "<<LLR<<", prod = "<<prod<<"\n"<<str<<std::endl<<"H.get_row(i)="<<H.get_row(i)<<std::endl <<"llrs.get_row(i)="<<llrs.get_row(i)<<std::endl;
686 
687  break;
688  }
689  break;
690  }
691  }
692  case 1:
693  {
694  // variable to check, llr updating
695  sum= LLRin(j);
696  for ( int t=0; t<ncheck; t++){
697  if ( H(t,j) ){
698  if ( t != i ) {
699  sum += LLRs(t,j);
700  }
701  }
702  }
703  llrs.set(i,j,sum);
704  break;
705  }
706  }
707  }
708 
709  // get output LLRout and check result
710  for ( int j=0; j<nvar; j++){
711  sum=LLRin(j);
712  //if (debug) std::cout<<" sum = "<<sum<<std::endl;
713  for ( int t=0; t<ncheck; t++){
714  //if (debug) std::cout<<"t = "<<t<<", sum = "<<sum<<std::endl;
715  if ( H(t,j) ){
716  sum += LLRs(t,j);
717  }
718  }
719  //if (debug) cout<<"LLRout = "<<LLRout<<std::endl;
720  LLRout.set(j,sum);
721  }
722  if (debug) std::cout<<"update_count = "<<update_count<<", LLRout = "<<floor(LLRout)<<std::endl ;
723  //if (debug) std::cout<<"update_count = "<<update_count<<std::endl;
724  //if (debug) draw_toric_x_error(LLRout<0);
725  update_count++;
726  if ( match_syndrome( LLRout, syndrome) ){
727  break;
728  }
729  }
730 
731  if (debug) std::cout<<"LLRout = "<<LLRout<<std::endl;
732 
733  // if (debug) std::cout<<"llrs = "<<llrs<<std::endl;
734  //if (debug) std::cout<<"LLRs = "<<LLRs<<std::std::endl;
735 
736  //not converge, output negative value
737  if (! match_syndrome( LLRout, syndrome) ){
738  update_count = - update_count;
739  }
740 
741  return update_count ;
742 
743 }
BP_Decoder::nedge
int nedge
Definition: bp_decoder.h:33
BP_Decoder::set_exit_iteration
void set_exit_iteration(int exit_iteration_temp)
Definition: bp_decoder.h:114
BP_Decoder::match_syndrome
bool match_syndrome(itpp::vec LLR, itpp::bvec syndrome)
Definition: bp_decoder.h:281
BP_Decoder::set_schedule_mode
void set_schedule_mode(int schedule_mode_temp)
Definition: bp_decoder.h:155
summation
int summation(itpp::bvec u)
Definition: bp_decoder.h:14
BP_Decoder::schedule_mode_str
std::string schedule_mode_str
Definition: bp_decoder.h:54
BP_Decoder::decode_mode
int decode_mode
Definition: bp_decoder.h:31
BP_Decoder::bp_syndrome_llr
int bp_syndrome_llr(itpp::bvec syndrome, const itpp::vec &LLRin, itpp::vec &LLRout)
Definition: bp_decoder.h:287
BP_Decoder::decode
int decode(itpp::bvec syndrome, const itpp::vec &LLRin, itpp::vec &LLRout)
Definition: bp_decoder.h:263
dist.h
distance related functions, defined within namespace common
BP_Decoder::bp_schedule
int bp_schedule(itpp::bvec syndrome, const itpp::vec &LLRin, itpp::vec &LLRout)
Definition: bp_decoder.h:464
BP_Decoder::schedule_mode
int schedule_mode
Definition: bp_decoder.h:53
BP_Decoder::nvar
int nvar
Definition: bp_decoder.h:33
BP_Decoder::exit_iteration
int exit_iteration
Definition: bp_decoder.h:29
BP_Decoder::schedule
itpp::mat schedule
Definition: bp_decoder.h:55
BP_Decoder::set_decode_mode_str
void set_decode_mode_str(std::string decode_mode_str_temp)
Definition: bp_decoder.h:144
BP_Decoder::set_silent_mode
void set_silent_mode(bool silent_mode_temp)
Definition: bp_decoder.h:60
BP_Decoder::bp_flexible
int bp_flexible(itpp::bvec syndrome, const itpp::vec &LLRin, itpp::vec &LLRout)
Definition: bp_decoder.h:597
BP_Decoder::is_initialized
bool is_initialized
Definition: bp_decoder.h:35
BP_Decoder::set_debug_mode
void set_debug_mode(bool debug_mode_temp)
Definition: bp_decoder.h:64
BP_Decoder
Definition: bp_decoder.h:23
BP_Decoder::init
void init(itpp::GF2mat H_temp)
Definition: bp_decoder.h:82
BP_Decoder::debug
bool debug
Definition: bp_decoder.h:26
BP_Decoder::is_H_valid
bool is_H_valid(itpp::GF2mat H_temp)
Definition: bp_decoder.h:70
BP_Decoder::silent_mode
bool silent_mode
Definition: bp_decoder.h:25
BP_Decoder::INF_BP
const double INF_BP
Definition: bp_decoder.h:27
BP_Decoder::print_info
void print_info()
Definition: bp_decoder.h:98
BP_Decoder::H
itpp::GF2mat H
Definition: bp_decoder.h:28
BP_Decoder::decode_mode_str
std::string decode_mode_str
Definition: bp_decoder.h:32
BP_Decoder::ncheck
int ncheck
Definition: bp_decoder.h:33
BP_Decoder::alpha
double alpha
Definition: bp_decoder.h:30
BP_Decoder::set_decode_mode
void set_decode_mode(int decode_mode_temp)
Definition: bp_decoder.h:122