11import numpy as np
22from anytree import PreOrderIter
33
4- from python_polar_coding .polar_codes .fast_ssc import FastSSCDecoder
5-
6- from ..base import make_hard_decision
7- from .functions import function_1 , function_2
4+ from python_polar_coding .polar_codes .base import BaseTreeDecoder
5+ from python_polar_coding .polar_codes .base .functions import make_hard_decision
6+
7+ from .functions import (
8+ compute_left_alpha ,
9+ compute_parent_beta ,
10+ compute_right_alpha ,
11+ )
812from .node import RCSCANNode
913
1014
11- class RCSCANDecoder (FastSSCDecoder ):
15+ class RCSCANDecoder (BaseTreeDecoder ):
1216 """Implements Reduced-complexity SCAN decoding algorithm.
1317
1418 Based on:
@@ -22,26 +26,24 @@ def __init__(
2226 self ,
2327 n : int ,
2428 mask : np .array ,
25- code_min_size : int = 0 ,
2629 I : int = 1 ,
2730 ):
28- super ().__init__ (n = n , mask = mask , is_systematic = True ,
29- code_min_size = code_min_size )
31+ super ().__init__ (n = n , mask = mask )
3032 self .I = I
3133
32- def decode_internal (self , received_llr : np .array ) -> np .array :
34+ def decode (self , received_llr : np .array ) -> np .array :
3335 """Implementation of SC decoding method."""
34- self .clean_before_decoding ()
36+ self ._clean_before_decoding ()
3537
36- for leaf in self ._decoding_tree . leaves :
38+ for leaf in self .leaves :
3739 leaf .initialize_leaf_beta ()
3840
3941 for _ in range (self .I ):
40- super ().decode_internal (received_llr )
42+ super ().decode (received_llr )
4143
4244 return self .result
4345
44- def clean_before_decoding (self ):
46+ def _clean_before_decoding (self ):
4547 """Reset intermediate BETA values.
4648
4749 Run this before calling `__call__` method.
@@ -51,7 +53,7 @@ def clean_before_decoding(self):
5153 if not (node .is_zero or node .is_one ):
5254 node .beta *= 0
5355
54- def compute_intermediate_alpha (self , leaf ):
56+ def _compute_intermediate_alpha (self , leaf ):
5557 """Compute intermediate Alpha values (LLR)."""
5658 for node in leaf .path [1 :]:
5759 if node .is_computed or node .is_zero or node .is_one :
@@ -61,69 +63,34 @@ def compute_intermediate_alpha(self, leaf):
6163
6264 if node .is_left :
6365 right_beta = node .siblings [0 ].beta
64- node .alpha = self . compute_left_alpha (parent_alpha , right_beta )
66+ node .alpha = compute_left_alpha (parent_alpha , right_beta )
6567
6668 if node .is_right :
6769 left_beta = node .siblings [0 ].beta
68- node .alpha = self . compute_right_alpha (parent_alpha , left_beta )
70+ node .alpha = compute_right_alpha (parent_alpha , left_beta )
6971
7072 node .is_computed = True
7173
72- def compute_intermediate_beta (self , node ):
74+ def _compute_intermediate_beta (self , node ):
7375 """Compute intermediate BETA values."""
7476 parent = node .parent
7577 if node .is_left or node .is_root or parent .is_root :
7678 return
7779
7880 left = node .siblings [0 ]
79- parent .beta = self . compute_parent_beta (left .beta , node .beta , parent .alpha ) # noqa
80- return self .compute_intermediate_beta (parent )
81+ parent .beta = compute_parent_beta (left .beta , node .beta , parent .alpha )
82+ return self ._compute_intermediate_beta (parent )
8183
8284 @property
8385 def result (self ):
84- if not self .is_systematic :
85- raise TypeError ('Code must be systematic' )
86- return make_hard_decision (self .root .alpha + self ._compute_result_beta ())
87-
88- @staticmethod
89- def compute_left_alpha (parent_alpha , beta ):
90- """Compute LLR for left node."""
91- return RCSCANDecoder .compute_alpha (parent_alpha , beta , is_left = True )
92-
93- @staticmethod
94- def compute_right_alpha (parent_alpha , beta ):
95- """Compute LLR for right node."""
96- return RCSCANDecoder .compute_alpha (parent_alpha , beta , is_left = False )
97-
98- @staticmethod
99- def compute_alpha (parent_alpha , beta , is_left ):
100- """Compute ALPHA values for left or right node."""
101- N = parent_alpha .size // 2
102- left_parent_alpha = parent_alpha [:N ]
103- right_parent_alpha = parent_alpha [N :]
104-
105- if is_left :
106- result_alpha = function_1 (left_parent_alpha , right_parent_alpha , beta )
107- else :
108- result_alpha = function_2 (left_parent_alpha , beta , right_parent_alpha )
109- return result_alpha
110-
111- @staticmethod
112- def compute_parent_beta (left_beta , right_beta , parent_alpha ):
113- """Compute bits of a parent Node."""
114- N = parent_alpha .size // 2
115- left_parent_alpha = parent_alpha [:N ]
116- right_parent_alpha = parent_alpha [N :]
117-
118- parent_beta_left = function_1 (left_beta , right_beta , right_parent_alpha )
119- parent_beta_right = function_2 (left_beta , left_parent_alpha , right_beta )
120-
121- return np .append (parent_beta_left , parent_beta_right )
122-
123- def _compute_result_beta (self ):
86+ return make_hard_decision (self .root .alpha +
87+ self ._compute_result_beta ())
88+
89+ def _compute_result_beta (self ) -> np .array :
12490 """Compute result BETA values."""
12591 alpha = self .root .alpha
12692 if not self .root .children :
12793 return self .root .beta
94+
12895 left , right = self .root .children
129- return self . compute_parent_beta (left .beta , right .beta , alpha )
96+ return compute_parent_beta (left .beta , right .beta , alpha )
0 commit comments