From a75660795e983f7c30961f31ba02847f286c811b Mon Sep 17 00:00:00 2001 From: lucas Date: Fri, 26 Apr 2024 12:33:58 +0200 Subject: [PATCH 1/3] If combination sweep search is used together with osd_order>0, try only osd_order many weight one solutions --- src_cpp/osd.hpp | 140 +++++++++++++++++++++++++----------------------- 1 file changed, 72 insertions(+), 68 deletions(-) diff --git a/src_cpp/osd.hpp b/src_cpp/osd.hpp index e4f895c..df4c4f3 100644 --- a/src_cpp/osd.hpp +++ b/src_cpp/osd.hpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include "bp.hpp" @@ -12,38 +12,37 @@ #include "util.hpp" #include "gf2sparse_linalg.hpp" -namespace ldpc::osd{ +namespace ldpc::osd { -enum OsdMethod{ - OSD_OFF, - OSD_0, - EXHAUSTIVE, - COMBINATION_SWEEP -}; + enum OsdMethod { + OSD_OFF, + OSD_0, + EXHAUSTIVE, + COMBINATION_SWEEP + }; -class OsdDecoder{ + class OsdDecoder { public: OsdMethod osd_method; int osd_order; int k, bit_count, check_count; - ldpc::bp::BpSparse& pcm; - std::vector& channel_probabilities; + ldpc::bp::BpSparse &pcm; + std::vector &channel_probabilities; std::vector osd0_decoding; std::vector osdw_decoding; std::vector> osd_candidate_strings; std::vector column_ordering; - ldpc::gf2sparse_linalg::RowReduce* LuDecomposition; - + ldpc::gf2sparse_linalg::RowReduce *LuDecomposition; + OsdDecoder( - ldpc::bp::BpSparse& parity_check_matrix, - OsdMethod osd_method, - int osd_order, - std::vector& channel_probs): - pcm(parity_check_matrix), - channel_probabilities(channel_probs) - { + ldpc::bp::BpSparse &parity_check_matrix, + OsdMethod osd_method, + int osd_order, + std::vector &channel_probs) : + pcm(parity_check_matrix), + channel_probabilities(channel_probs) { this->bit_count = this->pcm.n; this->check_count = this->pcm.m; @@ -56,44 +55,48 @@ class OsdDecoder{ } - int osd_setup(){ + int osd_setup() { this->osd_candidate_strings.clear(); - - if(this->osd_method == OSD_OFF) return 0; + + if (this->osd_method == OSD_OFF) { + return 0; + } this->LuDecomposition = new ldpc::gf2sparse_linalg::RowReduce(this->pcm); this->column_ordering.resize(this->pcm.n); int osd_candidate_string_count; - this->LuDecomposition->rref(false,true); + this->LuDecomposition->rref(false, true); this->k = this->pcm.n - this->LuDecomposition->rank; - if(this->osd_method == OSD_0 || this->osd_order==0){ + if (this->osd_method == OSD_0 || this->osd_order == 0) { return 1; } - if(this->osd_method == EXHAUSTIVE){ - osd_candidate_string_count = pow(2,this->osd_order); - for(int i=1; iosd_candidate_strings.push_back(ldpc::util::decimal_to_binary_reverse(i,k)); + if (this->osd_method == EXHAUSTIVE) { + osd_candidate_string_count = pow(2, this->osd_order); + for (int i = 1; i < osd_candidate_string_count; i++) { + this->osd_candidate_strings.push_back(ldpc::util::decimal_to_binary_reverse(i, k)); } } - if(this->osd_method == COMBINATION_SWEEP){ - for(int i=0; i0 is used, try lambda first wt 1 solutions, otherwise all + if (this->osd_method == COMBINATION_SWEEP) { + auto lambda = this->osd_order > 0 ? this->osd_order : this->k; + for (int i = 0; i < lambda; i++) { std::vector osd_candidate; - osd_candidate.resize(k,0); - osd_candidate[i]=1; + osd_candidate.resize(k, 0); + osd_candidate[i] = 1; this->osd_candidate_strings.push_back(osd_candidate); } - for(int i = 0; iosd_order;i++){ - for(int j = 0; josd_order; j++){ - if(j<=i) continue; + for (int i = 0; i < this->osd_order; i++) { + for (int j = 0; j < this->osd_order; j++) { + if (j <= i) continue; std::vector osd_candidate; - osd_candidate.resize(k,0); - osd_candidate[i]=1; - osd_candidate[j]=1; + osd_candidate.resize(k, 0); + osd_candidate[i] = 1; + osd_candidate[j] = 1; this->osd_candidate_strings.push_back(osd_candidate); } } @@ -102,22 +105,23 @@ class OsdDecoder{ return 1; } - ~OsdDecoder(){ + ~OsdDecoder() { delete this->LuDecomposition; }; - std::vector& decode(std::vector& syndrome, std::vector& log_prob_ratios) { + std::vector &decode(std::vector &syndrome, std::vector &log_prob_ratios) { - ldpc::sort::soft_decision_col_sort(log_prob_ratios, this->column_ordering,bit_count); + ldpc::sort::soft_decision_col_sort(log_prob_ratios, this->column_ordering, bit_count); - if(this->osd_order == 0){ - this->osd0_decoding = this->osdw_decoding = this->LuDecomposition->fast_solve(syndrome,this->column_ordering); + if (this->osd_order == 0) { + this->osd0_decoding = this->osdw_decoding = this->LuDecomposition->fast_solve(syndrome, + this->column_ordering); return this->osd0_decoding; } //row reduce the matrix according to the new column ordering - this->LuDecomposition->rref(false,true,this->column_ordering); + this->LuDecomposition->rref(false, true, this->column_ordering); // find the OSD0 solution this->osd0_decoding = this->osdw_decoding = LuDecomposition->lu_solve(syndrome); @@ -130,35 +134,35 @@ class OsdDecoder{ double candidate_weight, osd_min_weight; - osd_min_weight=0; - for(int i=0; ipcm.n; i++){ - if(this->osd0_decoding[i]==1){ - osd_min_weight+=log(1/this->channel_probabilities[i]); + osd_min_weight = 0; + for (int i = 0; i < this->pcm.n; i++) { + if (this->osd0_decoding[i] == 1) { + osd_min_weight += log(1 / this->channel_probabilities[i]); } } std::vector non_pivot_columns; - std::vector delete_entries; - for(int i = this->LuDecomposition->rank; ipcm.n; i++){ + std::vector delete_entries; + for (int i = this->LuDecomposition->rank; i < this->pcm.n; i++) { int col = this->LuDecomposition->cols[i]; non_pivot_columns.push_back(col); - - for(auto& e: this->LuDecomposition->U.iterate_column(col)){ + + for (auto &e: this->LuDecomposition->U.iterate_column(col)) { delete_entries.push_back(&e); } } - for (auto e: delete_entries){ + for (auto e: delete_entries) { this->LuDecomposition->U.remove(*e); } - - for(auto& candidate_string: this->osd_candidate_strings){ + + for (auto &candidate_string: this->osd_candidate_strings) { auto t_syndrome = syndrome; int col_index = 0; - for(int col: non_pivot_columns){ - if(candidate_string[col_index]==1){ - for(auto& e: this->pcm.iterate_column(col)){ + for (int col: non_pivot_columns) { + if (candidate_string[col_index] == 1) { + for (auto &e: this->pcm.iterate_column(col)) { t_syndrome[e.row_index] ^= 1; } } @@ -166,18 +170,18 @@ class OsdDecoder{ } auto candidate_solution = this->LuDecomposition->lu_solve(t_syndrome); - for(int i=0; ipcm.n; i++){ - if(candidate_solution[i]==1){ - candidate_weight+=log(1/this->channel_probabilities[i]); + candidate_weight = 0; + for (int i = 0; i < this->pcm.n; i++) { + if (candidate_solution[i] == 1) { + candidate_weight += log(1 / this->channel_probabilities[i]); } } - if(candidate_weightosdw_decoding = candidate_solution; } @@ -188,7 +192,7 @@ class OsdDecoder{ } -}; + }; }//end osd namespace From 0ddf1eac9044374099efde62064ed999865597b2 Mon Sep 17 00:00:00 2001 From: lucas Date: Fri, 26 Apr 2024 12:39:39 +0200 Subject: [PATCH 2/3] code format, remove commented out code --- src_cpp/osd.hpp | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src_cpp/osd.hpp b/src_cpp/osd.hpp index df4c4f3..d69ddad 100644 --- a/src_cpp/osd.hpp +++ b/src_cpp/osd.hpp @@ -111,7 +111,6 @@ namespace ldpc::osd { std::vector &decode(std::vector &syndrome, std::vector &log_prob_ratios) { - ldpc::sort::soft_decision_col_sort(log_prob_ratios, this->column_ordering, bit_count); if (this->osd_order == 0) { @@ -119,19 +118,10 @@ namespace ldpc::osd { this->column_ordering); return this->osd0_decoding; } - //row reduce the matrix according to the new column ordering this->LuDecomposition->rref(false, true, this->column_ordering); - // find the OSD0 solution this->osd0_decoding = this->osdw_decoding = LuDecomposition->lu_solve(syndrome); - - // this->osd0_decoding = this->LuDecomposition->fast_solve(syndrome,this->column_ordering); - - // if(osd_order==0){ - // return this->osd0_decoding; - // } - double candidate_weight, osd_min_weight; osd_min_weight = 0; @@ -157,7 +147,6 @@ namespace ldpc::osd { } for (auto &candidate_string: this->osd_candidate_strings) { - auto t_syndrome = syndrome; int col_index = 0; for (int col: non_pivot_columns) { @@ -181,17 +170,11 @@ namespace ldpc::osd { } if (candidate_weight < osd_min_weight) { osd_min_weight = candidate_weight; - this->osdw_decoding = candidate_solution; - } - } - return this->osdw_decoding; - } - }; }//end osd namespace From 3dc4ac2d666ebd498eed30db296f3c85e0a9aebe Mon Sep 17 00:00:00 2001 From: lucas Date: Sun, 28 Apr 2024 21:24:56 +0200 Subject: [PATCH 3/3] add documentation --- src_python/ldpc/bposd_decoder/_bposd_decoder.pyx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src_python/ldpc/bposd_decoder/_bposd_decoder.pyx b/src_python/ldpc/bposd_decoder/_bposd_decoder.pyx index 7841ac8..3014ebf 100644 --- a/src_python/ldpc/bposd_decoder/_bposd_decoder.pyx +++ b/src_python/ldpc/bposd_decoder/_bposd_decoder.pyx @@ -39,7 +39,8 @@ cdef class BpOsdDecoder(BpDecoderBase): osd_method : int, optional The OSD method used. Must be one of {'OSD_0', 'OSD_E', 'OSD_CS'}. osd_order : int, optional - The OSD order, by default 0. + The OSD order, by default 0. Note that if OSD_CS is chosen with osd_order > 0, the algorithm will consider weight + one solutions of the osd_order many most reliable bits only. Notes ----- @@ -129,6 +130,8 @@ cdef class BpOsdDecoder(BpDecoderBase): for i in range(self.n): out[i] = self.bpd.decoding[i] else: + if self.osdD.osd_method == OSD_CS and self.osd_order > 0: + print(f"Using OSD_CS with osd_order={self.osd_order}, checking osd_order many weight one solutions only.") self.osdD.decode(self._syndrome, self.bpd.log_prob_ratios) for i in range(self.n): out[i] = self.osdD.osdw_decoding[i]