Skip to content

Commit 822690d

Browse files
author
Alexandre Marquet
committed
Fix multiple errors in log_bcjr implementation. Switch most methods to public.
1 parent 9b657cf commit 822690d

File tree

2 files changed

+68
-62
lines changed

2 files changed

+68
-62
lines changed

log_bcjr.cc

Lines changed: 40 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ log_bcjr::generate_PS_PI()
6464
float
6565
log_bcjr::max_star(const float *vec, size_t n_ele)
6666
{
67-
float ret_val = std::numeric_limits<float>::min();
67+
float ret_val = -std::numeric_limits<float>::max();
6868

6969
for (float *vec_it = (float*)vec ; vec_it < (vec + n_ele) ; ++vec_it) {
7070
ret_val = max_star(ret_val, *vec_it);
@@ -77,11 +77,11 @@ void
7777
log_bcjr::compute_fw_metrics(const std::vector<float> &G,
7878
const std::vector<float> &A0, std::vector<float> &A, size_t K)
7979
{
80-
A.resize(d_S*(K+1), std::numeric_limits<float>::max());
80+
A.resize(d_S*(K+1), -std::numeric_limits<float>::max());
8181

82-
float norm_A = std::numeric_limits<float>::min();
82+
float norm_A = -std::numeric_limits<float>::max();
8383
std::vector<float>::iterator A_prev, A_curr;
84-
std::vector<int>::const_iterator PS_it, PI_it;
84+
std::vector<int>::iterator PS_it, PI_it;
8585

8686
//Integrate initial forward metrics
8787
std::copy(A0.begin(), A0.end(), A.begin());
@@ -109,59 +109,62 @@ log_bcjr::compute_fw_metrics(const std::vector<float> &G,
109109

110110
//Update iterators
111111
++A_curr;
112-
++A_prev;
113112
}
114113

114+
//Advance A_prev
115+
A_prev += d_S;
116+
115117
//Metrics normalization
116-
norm_A = max_star(&(*A_prev), d_S);
117-
std::transform(A_prev, A_curr-1, A_prev,
118-
std::bind2nd(std::minus<double>(), norm_A));
118+
norm_A = max_star(&(*(A_prev)), d_S);
119+
std::transform(A_prev, A_curr, A_prev,
120+
std::bind2nd(std::minus<float>(), norm_A));
119121
}
120122
}
121123

122124
void
123125
log_bcjr::compute_bw_metrics(const std::vector<float> &G,
124126
const std::vector<float> &BK, std::vector<float> &B, size_t K)
125127
{
126-
B.resize(d_S*(K+1), std::numeric_limits<float>::max());
128+
B.resize(d_S*(K+1), -std::numeric_limits<float>::max());
127129

128-
float norm_B = std::numeric_limits<float>::min();
129-
std::vector<float>::iterator B_next, B_curr;
130-
std::vector<int>::const_iterator NS_it, OS_it;
130+
float norm_B = -std::numeric_limits<float>::max();
131+
std::vector<float>::reverse_iterator B_next, B_curr;
132+
std::vector<int>::reverse_iterator NS_it, OS_it;
131133

132134
//Integrate initial forward metrics
133-
std::copy(BK.begin(), BK.end(), B.end() - d_S + 1);
135+
std::copy(BK.rbegin(), BK.rend(), B.rbegin());
134136

135137
//Initialize iterators
136-
B_curr = B.end();
137-
B_next = B.begin() - d_S;
138-
for(std::vector<float>::const_iterator G_k = G.end() ;
139-
G_k != G.begin() ; G_k -= d_O) {
140-
141-
for(int s=d_S-1 ; s >= 0 ; --s) {
142-
//Iterators for next state and next output lists
143-
NS_it=d_NS.end();
144-
OS_it=d_OS.end();
145-
138+
B_curr = B.rbegin() + d_S;
139+
B_next = B.rbegin();
140+
for(std::vector<float>::const_reverse_iterator G_k = G.rbegin() ;
141+
G_k != G.rend() ; G_k += d_O) {
142+
143+
//Iterators for next state and next output lists
144+
NS_it=d_NS.rbegin();
145+
OS_it=d_OS.rbegin();
146+
for(int s=0 ; s < d_S ; ++s) {
146147
//Loop
147-
for(size_t i=d_I-1 ; i >= 0 ; --i) {
148+
for(size_t i=0 ; i < d_I ; ++i) {
148149
*B_curr = max_star(*B_curr,
149-
B_next[*NS_it] + G_k[*OS_it]);
150+
B_next[(d_S-1)-*NS_it] + G_k[(d_S-1)-*OS_it]);
150151

151152
//Update PS/PI iterators
152-
--NS_it;
153-
--OS_it;
153+
++NS_it;
154+
++OS_it;
154155
}
155156

156157
//Update iterators
157-
--B_curr;
158-
--B_next;
158+
++B_curr;
159159
}
160160

161+
//Advance B_next (go back, as it is a reverse iterator...)
162+
B_next += d_S;
163+
161164
//Metrics normalization
162-
norm_B = max_star(&(*B_next), d_S);
163-
std::transform(B_next, B_next + d_S-1, B_next,
164-
std::bind2nd(std::minus<double>(), norm_B));
165+
norm_B = max_star(&(*B_curr)+1, d_S);
166+
std::transform(B_next, B_curr, B_next,
167+
std::bind2nd(std::minus<float>(), norm_B));
165168
}
166169
}
167170

@@ -179,7 +182,7 @@ log_bcjr::compute_app(const std::vector<float> &A, const std::vector<float> &B,
179182

180183
for(int s=0 ; s < d_S ; ++s) {
181184
for (int i=0 ; i < d_I ; ++i) {
182-
out.push_back(B_it[d_NS[s*d_I+i]] + G_k[d_OS[s*d_I+i] + *A_it]);
185+
out.push_back(B_it[d_NS[s*d_I+i]] + G_k[d_OS[s*d_I+i]] + *A_it);
183186
}
184187

185188
//Update forward iterator
@@ -196,14 +199,14 @@ log_bcjr::log_bcjr_algorithm(const std::vector<float> &A0,
196199
const std::vector<float> &BK, const std::vector<float> &in,
197200
std::vector<float> &out)
198201
{
199-
std::vector<float> G, A, B;
200-
size_t K = out.size()/d_I;
202+
std::vector<float> A, B;
203+
size_t K = in.size()/d_O;
201204

202205
//Forward recursion
203-
compute_fw_metrics(G, A0, A, K);
206+
compute_fw_metrics(in, A0, A, K);
204207

205208
//Backward recursion
206-
compute_bw_metrics(G, BK, B, K);
209+
compute_bw_metrics(in, BK, B, K);
207210

208211
//Compute branch APP
209212
compute_app(A, B, in, K, out);

log_bcjr.h

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,24 @@ class log_bcjr
6161
//! Generates PS, PI and T tables.
6262
void generate_PS_PI();
6363

64-
protected:
64+
public:
65+
//! Default constructor.
66+
log_bcjr();
67+
68+
/*! Constructs a log_bcjr object.
69+
* \param I The number of input sequences (e.g. 2 for binary codes).
70+
* \param S The number of states in the trellis.
71+
* \param O The number of output sequences (e.g. 4 for a binary code
72+
* with a coding efficiency of 1/2).
73+
* \param NS Gives the next state ns of a branch defined by its
74+
* initial state s and its input symbol i : NS[s*I+i]=ns.
75+
* \param OS Gives the output symbol os of a branch defined by its
76+
* initial state s and its input symbol i : OS[s*I+i]=os.
77+
*/
78+
log_bcjr(int I, int S, int O,
79+
const std::vector<int> &NS,
80+
const std::vector<int> &OS);
81+
6582
//! Computes max* of two value.
6683
/*!
6784
* The returned value is computed as follows:
@@ -152,44 +169,30 @@ class log_bcjr
152169
*
153170
* where s' = NS(s,i) is the next state for transition with initial
154171
* state s and input symbol i (NS[s*I+i]).
172+
* Which is equivalent to log a-posteriori probabilites, up to an
173+
* additive constant.
155174
*
156175
* \param A Const reference to the forward metrics vector (size: d_S*(K+1)).
157176
* \param B Const reference to the backward metrics vector (size: d_S*(K+1)).
158177
* \param G Const reference to the branch log metrics vector (size: d_O*K).
159178
* \param K Number of observations.
160179
* \param out Reference to a posteriori branch log probabilities (will
161-
* have a size of d_S*d_I*K at the end of function execution).
180+
* have a size of d_S*d_I*K at the end of function execution).
162181
*
163182
*/
164183
virtual void compute_app(const std::vector<float> &A,
165184
const std::vector<float> &B, const std::vector<float> &G,
166185
size_t K, std::vector<float> &out);
167186

168-
public:
169-
//! Default constructor.
170-
log_bcjr();
171-
172-
/*! Constructs a log_bcjr object.
173-
* \param I The number of input sequences (e.g. 2 for binary codes).
174-
* \param S The number of states in the trellis.
175-
* \param O The number of output sequences (e.g. 4 for a binary code
176-
* with a coding efficiency of 1/2).
177-
* \param NS Gives the next state ns of a branch defined by its
178-
* initial state s and its input symbol i : NS[s*I+i]=ns.
179-
* \param OS Gives the output symbol os of a branch defined by its
180-
* initial state s and its input symbol i : OS[s*I+i]=os.
181-
*/
182-
log_bcjr(int I, int S, int O,
183-
const std::vector<int> &NS,
184-
const std::vector<int> &OS);
185-
186-
/*! Actually computes logarithm of a posteriori probabilities for a
187+
/*! Actually computes logarithm of a-posteriori probabilities for a
187188
* given observation sequence.
188189
*
189-
* \param A0 Log of initial state probabilities of the encoder.
190-
* \param BK Log of final state probabilities of the encoder.
191-
* \param in Log of input branch metrics for the algorithm.
192-
* \param out Output Log of a posteriori branch probabilities.
190+
* \param A0 Log of initial state probabilities of the encoder (size: d_S).
191+
* \param BK Log of final state probabilities of the encoder (size: d_S).
192+
* \param in Log of input branch metrics for the algorithm (size: d_O*k).
193+
* \param out A quantity equivalent to log a-posteriori probabilites, up
194+
* to an additive constant (will have a size of d_S*d_I*K at the end of
195+
* function execution).
193196
*/
194197
void log_bcjr_algorithm(const std::vector<float> &A0,
195198
const std::vector<float> &BK,

0 commit comments

Comments
 (0)