00001
00029 #ifndef CONVCODE_H
00030 #define CONVCODE_H
00031
00032 #include <itpp/base/vec.h>
00033 #include <itpp/base/mat.h>
00034 #include <itpp/base/array.h>
00035 #include <itpp/base/binary.h>
00036 #include <itpp/comm/channel_code.h>
00037
00038
00039 namespace itpp
00040 {
00041
00046 enum CONVOLUTIONAL_CODE_TYPE {MFD, ODS};
00047
00052 enum CONVOLUTIONAL_CODE_METHOD {Trunc, Tail, Tailbite};
00053
00102 class Convolutional_Code : public Channel_Code
00103 {
00104 public:
00106 Convolutional_Code(void): K(0), start_state(0), cc_method(Tail) {
00107 set_code(MFD, 2, 7);
00108 init_encoder();
00109 }
00110
00112 virtual ~Convolutional_Code(void) {}
00113
00115 void set_method(const CONVOLUTIONAL_CODE_METHOD method) {
00116 cc_method = method;
00117 }
00118
00126 void set_code(const CONVOLUTIONAL_CODE_TYPE type_of_code, int inverse_rate,
00127 int constraint_length);
00128
00130 void set_generator_polynomials(const ivec &gen, int constraint_length);
00132 ivec get_generator_polynomials(void) const { return gen_pol; }
00133
00135 void reset();
00136
00137
00139
00140 virtual void encode(const bvec &input, bvec &output);
00141 virtual bvec encode(const bvec &input) {
00142 bvec output;
00143 encode(input, output);
00144 return output;
00145 }
00147
00149
00155 void encode_trunc(const bvec &input, bvec &output);
00156 bvec encode_trunc(const bvec &input) {
00157 bvec output;
00158 encode_trunc(input, output);
00159 return output;
00160 }
00162
00164
00174 void encode_tail(const bvec &input, bvec &output);
00175 bvec encode_tail(const bvec &input) {
00176 bvec output;
00177 encode_tail(input, output);
00178 return output;
00179 }
00181
00183
00197 void encode_tailbite(const bvec &input, bvec &output);
00198 bvec encode_tailbite(const bvec &input) {
00199 bvec output;
00200 encode_tailbite(input, output);
00201 return output;
00202 }
00204
00206
00211 void encode_bit(const bin &input, bvec &output);
00212 bvec encode_bit(const bin &input) {
00213 bvec output;
00214 encode_bit(input, output);
00215 return output;
00216 }
00218
00219
00220 virtual void decode(const bvec &coded_bits, bvec &decoded_bits);
00221 virtual bvec decode(const bvec &coded_bits);
00222
00224
00225 virtual void decode(const vec &received_signal, bvec &output);
00226 virtual bvec decode(const vec &received_signal) {
00227 bvec output;
00228 decode(received_signal, output);
00229 return output;
00230 }
00232
00234
00240 virtual void decode_tail(const vec &received_signal, bvec &output);
00241 virtual bvec decode_tail(const vec &received_signal) {
00242 bvec output;
00243 decode_tail(received_signal, output);
00244 return output;
00245 }
00247
00249
00257 virtual void decode_tailbite(const vec &received_signal, bvec &output);
00258 virtual bvec decode_tailbite(const vec &received_signal) {
00259 bvec output;
00260 decode_tailbite(received_signal, output);
00261 return output;
00262 }
00264
00266
00267 virtual void decode_trunc(const vec &received_signal, bvec &output);
00268 virtual bvec decode_trunc(const vec &received_signal) {
00269 bvec output;
00270 decode_trunc(received_signal, output);
00271 return output;
00272 }
00274
00275
00277 virtual double get_rate(void) const { return rate; }
00278
00279
00281 void set_start_state(int state) {
00282 it_error_if((state < 0) || ((state >= (1 << m)) && m != 0),
00283 "Convolutional_Code::set_start_state(): Invalid start state");
00284 start_state = state;
00285 }
00286
00291 void init_encoder() { encoder_state = start_state; }
00292
00294 int get_encoder_state(void) const { return encoder_state; }
00295
00296
00298 void set_truncation_length(const int length) {
00299 it_error_if(length < K, "Convolutional_Code::set_truncation_length(): "
00300 "Truncation length shorter than K");
00301 trunc_length = length;
00302 }
00303
00305 int get_truncation_length(void) const { return trunc_length; }
00306
00307
00309 bool catastrophic(void);
00310
00311
00320 bool inverse_tail(const bvec coded_sequence, bvec &input);
00321
00322
00325 void distance_profile(ivec &dist_prof, int dmax = 100000,
00326 bool reverse = false);
00327
00343 void calculate_spectrum(Array<ivec> &spectrum, int dmax, int no_terms);
00344
00367 int fast(Array<ivec> &spectrum, const int dfree, const int no_terms,
00368 const int Cdfree = 1000000, const bool test_catastrophic = false);
00369
00370 protected:
00372 int next_state(const int instate, const int input) {
00373 return ((instate >> 1) | (input << (m - 1)));
00374 }
00376 int previous_state(const int state, const int input) {
00377 return (((state << 1) | input) & ((1 << m) - 1));
00378 }
00380 void previous_state(const int state, int &S0, int &S1) {
00381 S0 = (state << 1) & (no_states - 1);
00382 S1 = S0 | 1;
00383 }
00385 int weight(const int state, const int input);
00387 void weight(const int state, int &w0, int &w1);
00390 int weight_reverse(const int state, const int input);
00393 void weight_reverse(const int state, int &w0, int &w1);
00395 bvec output_reverse(const int state, const int input);
00397 void output_reverse(const int state, bvec &zero_output, bvec &one_output);
00399 void output_reverse(const int state, int &zero_output, int &one_output);
00401 void calc_metric_reverse(const int state, const vec &rx_codeword,
00402 double &zero_metric, double &one_metric);
00404 void calc_metric(const vec &rx_codeword, vec &delta_metrics);
00406 int get_input(const int state) { return (state >> (m - 1)); }
00407
00409 int n;
00411 int K;
00413 int m;
00415 int no_states;
00417 ivec gen_pol;
00419 ivec gen_pol_rev;
00421 int encoder_state;
00423 int start_state;
00425 int trunc_length;
00427 double rate;
00429 bvec xor_int_table;
00431 imat output_reverse_int;
00433 CONVOLUTIONAL_CODE_METHOD cc_method;
00435 imat path_memory;
00437 Array<bool> visited_state;
00439 vec sum_metric;
00441 int trunc_ptr;
00443 int trunc_state;
00444 };
00445
00446
00451 int reverse_int(int length, int in);
00452
00457 int weight_int(int length, int in);
00458
00463 int compare_spectra(ivec v1, ivec v2);
00464
00471 int compare_spectra(ivec v1, ivec v2, vec weight_profile);
00472
00473 }
00474
00475 #endif // #ifndef CONVCODE_H