ccsoft  0.0.0
Convolutional codes library with soft decision decoding
/shared/development/google_code/rssoft/libccsoft/lib/CC_Encoding_base.h
Go to the documentation of this file.
00001 /*
00002  Copyright 2013 Edouard Griffiths <f4exb at free dot fr>
00003 
00004  This file is part of CCSoft. A Convolutional Codes Soft Decoding library
00005 
00006  This program is free software; you can redistribute it and/or modify
00007  it under the terms of the GNU General Public License as published by
00008  the Free Software Foundation; either version 2 of the License, or
00009  (at your option) any later version.
00010 
00011  This program is distributed in the hope that it will be useful,
00012  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  GNU General Public License for more details.
00015 
00016  You should have received a copy of the GNU General Public License
00017  along with this program; if not, write to the Free Software
00018  Foundation, Inc., 51 Franklin Street, Boston, MA  02110-1301  USA
00019 
00020  Convolutional encoder class
00021 
00022  */
00023 #ifndef __CC_ENCODING_BASE_H__
00024 #define __CC_ENCODING_BASE_H__
00025 
00026 #include "CCSoft_Exception.h"
00027 #include <vector>
00028 #include <iostream>
00029 
00030 namespace ccsoft
00031 {
00032 
00039 template<typename T_Register>
00040 void print_register(const T_Register& reg, std::ostream& os)
00041 {
00042     os << std::hex << reg;
00043     os << std::dec;
00044 }
00045 
00051 template<>
00052 void print_register<unsigned char>(const unsigned char& reg, std::ostream& os);
00053 
00060 template<typename T_IOSymbol>
00061 void print_symbol(const T_IOSymbol& sym, std::ostream& os)
00062 {
00063     os << std::dec << sym;
00064 }
00065 
00071 template<>
00072 void print_symbol<unsigned char>(const unsigned char& sym, std::ostream& os);
00073 
00081 template<typename T_Register, typename T_IOSymbol>
00082 class CC_Encoding_base
00083 {
00084 public:
00085 
00086     //=============================================================================================
00096     CC_Encoding_base(const std::vector<unsigned int>& _constraints, const std::vector<std::vector<T_Register> >& _genpoly_representations) :
00097         k(_constraints.size()),
00098         constraints(_constraints),
00099         genpoly_representations(_genpoly_representations),
00100         m(0)
00101     {
00102         if (k < 1)
00103         {
00104             throw CCSoft_Exception("There must be at least one constraint size");
00105         }
00106 
00107         if (k > sizeof(T_IOSymbol)*8)
00108         {
00109             throw CCSoft_Exception("Number of input bits not supported by I/O symbol type");
00110         }
00111 
00112         if (genpoly_representations.size() != k)
00113         {
00114             throw CCSoft_Exception("Generator polynomial representations size error");
00115         }
00116 
00117         unsigned int min_nb_outputs = genpoly_representations[0].size();
00118 
00119         for (unsigned int ci=0; ci < constraints.size(); ci++)
00120         {
00121             if (constraints[ci] > sizeof(T_Register)*8)
00122             {
00123                 throw CCSoft_Exception("One constraint size is too large for the size of the registers");
00124             }
00125 
00126             if (genpoly_representations[ci].size() < min_nb_outputs)
00127             {
00128                 min_nb_outputs = genpoly_representations[ci].size();
00129             }
00130 
00131             if (constraints[ci] > m)
00132             {
00133                 m = constraints[ci];
00134             }
00135         }
00136 
00137         n = min_nb_outputs;
00138 
00139         if (n <= k)
00140         {
00141             throw CCSoft_Exception("The number of outputs must be larger than the number of inputs");
00142         }
00143 
00144         if (n > sizeof(T_IOSymbol)*8)
00145         {
00146             throw CCSoft_Exception("Number of output bits not supported by I/O symbol type");
00147         }
00148     }
00149 
00150     //=============================================================================================
00154     virtual ~CC_Encoding_base()
00155     {}
00156     
00157     //=============================================================================================
00162     virtual T_Register& get_register(unsigned int index) = 0;
00163 
00164     //=============================================================================================
00172     bool encode(const T_IOSymbol& in_symbol, T_IOSymbol& out_symbol, bool no_step = false)
00173     {
00174         T_IOSymbol w_in = in_symbol;
00175 
00176         // load registers with new symbol bits
00177         for (unsigned int ki=0; ki<k; ki++)
00178         {
00179             if (no_step)
00180             {
00181                 get_register(ki) >>= 1; // flush bit
00182             }
00183             get_register(ki) <<= 1; // make room for bit
00184             get_register(ki) += w_in & 1; // insert bit
00185             w_in >>= 1; // move to next input bit
00186         }
00187 
00188         out_symbol = 0;
00189         T_IOSymbol symbol_bit;
00190 
00191         for (unsigned int ni=0; ni<n; ni++)
00192         {
00193             symbol_bit = 0;
00194 
00195             for (unsigned int ki=0; ki<k; ki++)
00196             {
00197                 symbol_bit ^= (xorbits(get_register(ki)&genpoly_representations[ki][ni]) ? 1 : 0);
00198             }
00199 
00200             out_symbol += symbol_bit << ni;
00201         }
00202 
00203         return true;
00204     }
00205 
00206     //=============================================================================================
00211     void print(std::ostream& os)
00212     {
00213         std::cout << "k=" << k << ", n=" << n << ", m=" << m << std::endl;
00214 
00215         for (unsigned int ci=0; ci<k; ci++)
00216         {
00217             os << ci << " (" << constraints[ci] << ") : ";
00218 
00219             for (unsigned int gi=0; gi<n; gi++)
00220             {
00221                 print_register(genpoly_representations[ci][gi], os);
00222                 os << " ";
00223             }
00224 
00225             os << std::endl;
00226         }
00227     }
00228 
00232     unsigned int get_k() const
00233     {
00234         return k;
00235     }
00236 
00240     unsigned int get_n() const
00241     {
00242         return n;
00243     }
00244 
00248     unsigned int get_m() const
00249     {
00250         return m;
00251     }
00252 
00253 protected:
00254 
00261     bool xorbits(const T_Register& reg)
00262     {
00263         T_Register w_reg = reg;
00264         unsigned int nb_ones = 0;
00265 
00266         while(w_reg != 0)
00267         {
00268             nb_ones += w_reg % 2;
00269             w_reg /= 2;
00270         }
00271 
00272         return (nb_ones % 2) == 1;
00273     }
00274 
00275     unsigned int k; 
00276     unsigned int n; 
00277     unsigned int m; 
00278     std::vector<unsigned int> constraints; 
00279     std::vector<std::vector<T_Register> > genpoly_representations; 
00280 };
00281 
00282 } // namespace ccsoft
00283 
00284 
00285 #endif // __CC_ENCODING_H__
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines