00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <it/types.h>
00026 #include <it/vec.h>
00027 #include <it/convcode.h>
00028 #include <it/io.h>
00029 #include <it/hmmalgo.h>
00030
00031 #define bit(x, n) (((x) >> (n)) & 1)
00032
00033 #define DECLARE_CONV_CODE(x, k, n) \
00034 int it_cc_generators_##x[k*n]
00035
00036
00037 DECLARE_CONV_CODE (conv_code_1, 1, 2) = {
00038 02, 03};
00039
00040 DECLARE_CONV_CODE (conv_code_2, 1, 2) = {
00041 05, 07};
00042
00043 DECLARE_CONV_CODE (conv_code_3, 1, 2) = {
00044 015, 017};
00045
00046 DECLARE_CONV_CODE (conv_code_4, 1, 2) = {
00047 023, 033};
00048
00049 DECLARE_CONV_CODE (conv_code_6, 1, 2) = {
00050 0133, 0171};
00051
00052
00053 static int fls (int c);
00054 static int encode_conv (it_convolutional_code_t * cc, int *state, int input,
00055 imat G, int Q, int k, int n);
00056
00057
00058 static void convolutional_code_destructor (it_object_t * it_this);
00059 static bvec convolutional_code_encode (it_convolutional_code_t * cc, bvec b);
00060 static ivec convolutional_code_encode_symbolic (it_convolutional_code_t * cc,
00061 ivec b);
00062
00063
00064 it_instanciate (it_convolutional_code_t)
00065 {
00066 imat generators;
00067 int Q;
00068 int i, j, c;
00069 int s, n, k, l;
00070 int state, symbol;
00071 int n_states, n_symbols, n_labels;
00072
00073 it_new_args_start ();
00074
00075 it_construct (it_object_t);
00076 it_set_magic (it_this, it_convolutional_code_t);
00077
00078 it_overload (it_this, it_object_t, destructor,
00079 convolutional_code_destructor);
00080
00081
00082 it_this->encode = convolutional_code_encode;
00083 it_this->encode_symbolic = convolutional_code_encode_symbolic;
00084
00085
00086 it_this->generators = generators = imat_clone (it_new_args_next (imat));
00087 it_this->Q = Q = it_new_args_next (int);
00088 it_this->k = k = imat_height (generators);
00089 it_this->n = n = imat_width (generators);
00090
00091
00092 l = 0;
00093 for (j = 0; j < k; j++) {
00094 c = Q;
00095 for (i = 0; i < n; i++)
00096 c |= generators[j][i];
00097 l += fls (c) - 1;
00098 }
00099
00100
00101 it_this->memory = l;
00102 it_this->n_states = n_states = 1 << l;
00103 it_this->n_symbols = n_symbols = 1 << k;
00104 it_this->n_labels = n_labels = 1 << n;
00105
00106 it_this->automaton = imat_new_set (DUMM_NODE, 1 << n, n_states);
00107 it_this->output = imat_new (1 << k, n_states);
00108 it_this->input = imat_new_set (NULL_INDEX, 1 << n, n_states);
00109
00110
00111 it_this->logalpha_0 = vec_new_set (-HUGE_VAL, n_states);
00112 it_this->logalpha_0[0] = 0.0;
00113
00114
00115 it_this->logbeta_end = vec_new_zeros (n_states);
00116
00117
00118 it_this->next_state_logpt = mat_new_zeros (n_labels, n_states);
00119
00120
00121 for (state = 0; state < n_states; state++) {
00122 for (symbol = 0; symbol < n_symbols; symbol++) {
00123 s = state;
00124 c = encode_conv (it_this, &s, symbol, generators, Q, k, n);
00125
00126 it_this->automaton[c][state] = s;
00127 it_this->output[symbol][state] = c;
00128 it_this->input[c][state] = symbol;
00129 }
00130 }
00131
00132 it_new_args_stop ();
00133 return (it_this);
00134 }
00135
00136
00137 static void convolutional_code_destructor (it_object_t * it_this)
00138 {
00139 it_convolutional_code_t *convolutional_code =
00140 IT_CONVOLUTIONAL_CODE (it_this);
00141
00142 if (convolutional_code->generators)
00143 imat_delete (convolutional_code->generators);
00144
00145 vec_delete (convolutional_code->logalpha_0);
00146 vec_delete (convolutional_code->logbeta_end);
00147 mat_delete (convolutional_code->next_state_logpt);
00148 imat_delete (convolutional_code->automaton);
00149 imat_delete (convolutional_code->input);
00150 imat_delete (convolutional_code->output);
00151
00152
00153 convolutional_code->it_overloaded (destructor) (it_this);
00154 }
00155
00156
00157 static bvec convolutional_code_encode (it_convolutional_code_t * cc, bvec b)
00158 {
00159 int i, j;
00160 int k = cc->k;
00161 int n = cc->n;
00162 idx_t L = bvec_length (b) / k;
00163 bvec r = bvec_new (L * n);
00164 int state = 0;
00165 int symbol;
00166 int label;
00167
00168 assert (L * k == bvec_length (b));
00169
00170 for (i = 0; i < L; i++) {
00171 symbol = 0;
00172
00173 for (j = 0; j < k; j++) {
00174 assert (!(b[i * k + j] >> 1));
00175 symbol |= b[i * k + j] << (k - 1 - j);
00176 }
00177
00178
00179 label = it_cc_label (cc, state, symbol);
00180 state = it_cc_next (cc, state, symbol);
00181
00182
00183 for (j = 0; j < n; j++)
00184 r[i * n + j] = bit (label, n - 1 - j);
00185 }
00186
00187 return (r);
00188 }
00189
00190
00191 static ivec convolutional_code_encode_symbolic (it_convolutional_code_t * cc,
00192 ivec s)
00193 {
00194 int i;
00195 int L = ivec_length (s);
00196 ivec r = ivec_new (L);
00197 int state = 0;
00198
00199 for (i = 0; i < L; i++) {
00200
00201 r[i] = it_cc_label (cc, state, s[i]);
00202 state = it_cc_next (cc, state, s[i]);
00203 }
00204 return (r);
00205 }
00206
00207
00208
00209 static int encode_conv (it_convolutional_code_t * cc, int *state,
00210 int input,
00211 imat G,
00212 int Q,
00213 int k,
00214 int n)
00215 {
00216 int i, j, b, r, t;
00217 int c, s, l;
00218 int m;
00219 int feedback;
00220
00221 s = *state;
00222 c = m = r = 0;
00223
00224 for (j = 0; j < k; j++) {
00225
00226
00227 t = Q;
00228 for (i = 0; i < n; i++)
00229 t |= G[j][i];
00230 l = fls (t) - 1;
00231
00232
00233 feedback = bit (input, j);
00234 for (i = 0; i < l; i++)
00235 feedback ^= bit (Q, i) & bit (s, i);
00236
00237
00238 for (i = 0; i < n; i++) {
00239 c ^= (bit (G[j][i], l) & feedback) << i;
00240 for (b = 0; b < l; b++)
00241 c ^= (bit (G[j][i], b) & bit (s, b)) << i;
00242 }
00243
00244
00245 r |= ((s & ((1 << l) - 1)) >> 1) << m;
00246 if (l)
00247 r |= feedback << (m + l - 1);
00248 s >>= l;
00249 m += l;
00250 }
00251
00252 *state = r;
00253
00254 return (c);
00255 }
00256
00257
00258
00259 static int fls (int c)
00260 {
00261 int l = 0;
00262
00263 while (c) {
00264 l++;
00265 c >>= 1;
00266 }
00267 return (l);
00268 }
00269
00270
00271 ivec it_viterbi_decode_symbolic (it_convolutional_code_t * cc, mat metrics)
00272 {
00273 ivec branches;
00274 imat next_state = cc->automaton;
00275 mat next_state_logpt = cc->next_state_logpt;
00276 vec logalpha_0 = cc->logalpha_0;
00277 vec logbeta_end = cc->logbeta_end;
00278 int j, l, k;
00279
00280
00281 branches =
00282 logviterbi (metrics, next_state, next_state_logpt, logalpha_0,
00283 logbeta_end);
00284
00285
00286 j = 0;
00287 for (k = 0; k < ivec_length (branches); k++) {
00288 l = branches[k];
00289 branches[k] = cc->input[l][j];
00290 j = next_state[l][j];
00291 }
00292
00293 return (branches);
00294 }
00295
00296
00297 bvec it_viterbi_decode (it_convolutional_code_t * cc, mat metrics)
00298 {
00299 int K, L;
00300 ivec branches;
00301 bvec r;
00302 int i, j;
00303
00304 K = cc->k;
00305 L = mat_width (metrics);
00306 branches = it_viterbi_decode_symbolic (cc, metrics);
00307 r = bvec_new (L * K);
00308
00309 for (i = 0; i < L; i++)
00310 for (j = 0; j < K; j++)
00311 r[i * K + j] = bit (branches[i], K - 1 - j);
00312
00313 ivec_delete (branches);
00314
00315 return (r);
00316 }