Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

trellis.h

Go to the documentation of this file.
00001 /***************************************************************************
00002                           trellis.h  -  description
00003                              -------------------
00004     begin                : Tue Jul 15 2003
00005     copyright            : (C) 2003 by Peter Haase
00006     email                : p.haase@tuhh.de
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU Lesser General Public            *
00013  *   License as published by the Free Software Foundation; either          *
00014  *   version 2.1 of the License, or (at your option) any later version.    *
00015  *                                                                         *
00016  *   This library is distributed in the hope that it will be useful,       *
00017  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00018  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00019  *   Lesser General Public License for more details.                       *
00020  *                                                                         *
00021  *   You should have received a copy of the GNU Lesser General Public      *
00022  *   License along with this library; if not, write to the Free Software   *
00023  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
00024  *   MA  02111-1307  USA                                                   *
00025  *                                                                         *
00026  ***************************************************************************/
00027 
00028 #ifndef TRELLIS_H
00029 #define TRELLIS_H
00030 
00031 #include <iostream>
00032 
00033 #include "phbib.h"
00034 #include "signals.h"
00035 #include "bitmapping.h"
00036 #include "demodulator.h"
00037 #include "diffdemodulator.h"
00038 
00039 namespace simthlib
00040 {
00041 
00042 
00044 struct TrellisPath
00045 {
00047   int prev;
00048 
00050   int data;
00051 
00053   simth::Array<double> metr;
00054 
00055 };
00056 
00057 
00060 struct TrellisBranch
00061 {
00063   int prev_state;
00064 
00066   int input;
00067 
00069   int output;
00070 
00072   int new_state;
00073 };
00074 
00075 
00076 class PhaseAmplitudeConstellationDiagram;
00077 
00078 class Trellis;
00079 std::ostream& operator<<(std::ostream &os, const Trellis &trellis);
00080 
00081 
00099 class Trellis
00100 {
00101 
00102 
00103   public:
00106     Trellis(int states, int inbits, int outbits);
00107 
00109     virtual ~Trellis();
00110 
00111     virtual void print(std::ostream &os) const {os<<"# No printing for trellis bases implemented";}
00112 
00113     void printStateDiagram(std::ostream &os) const
00114     {
00115       os<<"State diagram printing is not implemented"
00116       "for trellis bases implemented";
00117     }
00118 
00123     virtual int getDataLength(int code_length) const;
00124 
00127     virtual int getCodeLength(int data_length) const;
00128 
00130     const int numStates() const {return num_states;}
00131 
00133     const int numInbits() const {return num_inbits;}
00134 
00136     const int numInput() const {return num_input;}
00137 
00139     const int numOutbits() const {return num_outbits;}
00140 
00142     const int numOutput() const {return num_output;}
00143 
00146     virtual int getNextState(int state, int input, size_t step,size_t path_length) const=0;
00147 
00150     virtual int getNextOut(int state, int input, size_t step,size_t path_length) const =0;
00151 
00155     virtual int getPrevState(int state, int index, size_t step,size_t path_length) const =0;
00156 
00160     virtual int getPrevOut(int state, int index, size_t step,size_t path_length) const =0;
00161 
00165     virtual int getPrevIn(int state, int index, size_t step, size_t path_length) const =0;
00166 
00179     typedef std::vector<TrellisBranch> TrellisBranchArray;
00180 
00183     typedef std::vector<TrellisBranchArray> TrellisStatesArray;
00184 
00187     virtual const TrellisStatesArray& 
00188       getPrevTrellisArray(size_t time_step, size_t path_length) const =0;
00189 
00190     inline static const TrellisBranchArray&
00191       getPrevArray_state(const TrellisStatesArray& state_array, int state)
00192       { return state_array[state]; }
00193 
00194     inline static const TrellisBranch& 
00195       getPrevState_branch(const TrellisBranchArray& branch_array, int index)
00196       { return branch_array[index]; }
00197 
00198     inline static int getPrevState(const TrellisBranch& tb)
00199       { return tb.prev_state; }
00200     inline static int getPrevOut(const TrellisBranch& tb)
00201       { return tb.output; }
00202     inline static int getPrevIn(const TrellisBranch& tb)
00203       { return tb.input; }
00205 
00210     virtual int terminationInput(int state) const = 0;
00211 
00215     bool isTerminationStep(size_t path_length, size_t step) const;
00216 
00217     virtual bool isPossibleStartingState(int state) const = 0;
00218 
00222     size_t numTailsteps() const {return num_tailsteps;}
00223 
00227     size_t numTailbits() const {return num_tailbits;}
00228 
00229   protected:
00230 
00231     void setTailstepLength(int newTailsteps);
00232     void setTailbitLength(int newTailbits);
00233     void setPathLength(int newPathLength);
00234 
00236     const int num_states;
00237 
00239     const int num_inbits;
00240 
00242     const int num_input;
00243 
00245     const int num_outbits;
00246 
00248     const int num_output;
00249 
00250   private:
00251 
00252     void invariante() const;
00253 
00254 
00259     size_t num_tailsteps;
00260 
00263     size_t num_tailbits;
00264 
00265 };
00266 
00267 
00268 
00269 
00270 inline void Trellis::invariante() const
00271 {
00272   //if(DEBUG) {}
00273 }
00274 
00275 
00276 inline bool Trellis::isTerminationStep(size_t path_length, size_t step) const
00277 {
00278   if(DEBUG) {
00279     if(step < 0 || step >= path_length || path_length < num_tailsteps) {
00280       throw std::runtime_error("Trellis::isTerminationStep() const :  pathLength() < numTailsteps()");
00281     }
00282   }
00283   return (step >= (path_length- num_tailsteps));
00284 }
00285 
00286 
00287 inline void Trellis::setTailstepLength(int newTailsteps)
00288 {
00289   num_tailsteps = newTailsteps;
00290   num_tailbits = num_tailsteps * num_inbits;
00291 }
00292 
00293 inline void Trellis::setTailbitLength(int newTailbits)
00294 {
00295   num_tailbits = newTailbits;
00296   if(DEBUG) {
00297     if(num_inbits == 0) {
00298       throw std::logic_error("inline void Trellis::setNewTailbitLength(int newTailbits) : error 1");
00299     }
00300     if(num_inbits % num_inbits != 0) {
00301       throw std::logic_error("inline void Trellis::setNewTailbitLength(int newTailbits) : error 3");
00302     }
00303   }
00304   num_tailsteps = num_tailbits/num_inbits;
00305 }
00306 
00307 
00308 
00309 
00310 
00311 
00313 //  Shift register
00314 //  Autor: Peter Haase
00315 //  email: p.haase@tu-harburg.de
00316 
00317 
00318 
00319 
00328 class BestPolynomials
00329 {
00330   public:
00331 
00334     static const int genpol2[9][2];
00335 
00338     static const int genpol3[9][3];
00339 
00342     static const int genpol4[9][4];
00343 
00344 
00345 };
00346 
00347 
00348 
00349 
00356 class ShiftRegister
00357 {
00358   private:
00359 
00361     int mem;
00362     int symbolsPerStep_;
00363     int bitsPerSymbol_;
00364     int M_;
00365 
00366   protected:
00367 
00368     simth::checkedVector<int> polynomials;
00369     int recursivePolynomial;
00370 
00371     int symbolsPerStep() const {return symbolsPerStep_;}
00372     int bitsPerSymbol() const {return bitsPerSymbol_;}
00373     int M() const {return M_;}
00374 
00375 
00376 
00377   public:
00380     ShiftRegister(int symbolsPerStep, int bitsPerSymbol, const simth::checkedVector<int>& octalPolynomials, int recursivePolynomial = 0);
00381 
00382     virtual ~ShiftRegister() = 0;
00383 
00387     virtual int getNextState(int inputPattern, int oldState) const = 0;
00388 
00389     /*Computes the output of the shift register according to a given state and input.
00390     */
00391     virtual int getOutput(int input, int state) const = 0;
00392 
00393     virtual int getRecursive(int state) const = 0;
00394 
00397     int memoryLength() const {return mem;}
00398 
00399     virtual int tailsteps() const = 0;
00400 
00401     virtual void print(std::ostream &os) const;
00402 
00406     static int computeNumOutputBits(int numPolynomials, int symbolsPerStep, int bitsPerSymbol,bool systematic);
00407 
00412     static void getBestPolynomials(int mem, int inbits, int outbits, simth::checkedVector<int>* genPolynomials);
00413 
00416     static int computeMemoryLength(const simth::checkedVector<int>& polynomials, int recursivePolynomial = 0);
00417 
00420     static int computeMemoryLength(int polynomial);
00421 
00422 };
00423 
00424 inline  ShiftRegister::~ShiftRegister(){}
00425 
00426 
00430 class AbstractShiftRegisterBinary : public ShiftRegister
00431 {
00432   private:
00433 
00434 
00435   public:
00438     AbstractShiftRegisterBinary(int inbitsPerStep,
00439                                 const simth::checkedVector<int>& octalPolynomials, int recursivePolynomial = 0);
00440 
00441     virtual ~AbstractShiftRegisterBinary() = 0;
00442 
00446     virtual int getNextState(int inputPattern, int oldState) const;
00447 
00448 
00451     virtual int getOutput(int input, int state) const;
00452 
00453     virtual int getRecursive(int newState) const;
00454 
00455     virtual int tailsteps() const;
00456 
00457 };
00458 
00459 inline  AbstractShiftRegisterBinary::~AbstractShiftRegisterBinary()
00460 {}
00461 
00464 class ShiftRegisterBinary : public AbstractShiftRegisterBinary
00465 {
00466   public:
00467 
00470     ShiftRegisterBinary(int inbitsPerStep, const simth::checkedVector<int>& octalPolynomials,
00471                         int recursivePolynomial = 0);
00472 
00473     ~ShiftRegisterBinary(){};
00474 
00475 };
00476 
00477 
00484 class ShiftRegisterSystematicBinary : public AbstractShiftRegisterBinary
00485 {
00486 
00487   public:
00488 
00491     ShiftRegisterSystematicBinary(int inbitsPerStep, const simth::checkedVector<int>& octalPolynomials,
00492                                   int recursivePolynomial = 0);
00493 
00494     ~ShiftRegisterSystematicBinary(){};
00495 
00496     /* Computes the output of the shift register according to a given state and input.
00497     */
00498     virtual int getOutput(int input, int state) const;
00499 
00500 
00501     virtual void print(std::ostream &os) const;
00502 };
00503 
00504 
00507 class ShiftRegisterM : public ShiftRegister
00508 {
00509   private:
00510 
00511     mutable simth::checkedVector<int> stateVector;
00512 
00513     int M_;
00514 
00515   protected:
00516 
00517 
00518     void binaryState2symbolState(int binState, simth::checkedVector<int>& symbolStates) const;
00519     int symbolState2binaryState(const simth::checkedVector<int>& symbolStates) const;
00520     void shiftVector(simth::checkedVector<int>& vec, int increment) const;
00521 
00522     int getRecursive(const simth::checkedVector<int>& symbolStates) const;
00523 
00524   public:
00527     ShiftRegisterM(int symbolsPerStep, int bitsPerSymbol, const simth::checkedVector<int>& octalPolynomials,
00528                    int recursivePolynomial = 0, int inbits = 1);
00529 
00530     virtual ~ShiftRegisterM(){};
00531 
00535     virtual int getNextState(int inputPattern, int oldState) const;
00536 
00537 
00540     virtual int getOutput(int input, int state) const;
00541 
00542     virtual int getRecursive(int newState) const;
00543 
00544     virtual int tailsteps() const;
00545 };
00546 
00547 
00548 
00554 class ConvCodeTrellis : public Trellis
00555 {
00556   public:
00557 
00562     enum StartingMode {FREE, ZERO, AMBIGOUS};
00563 
00564 
00576     ConvCodeTrellis(int states, int inbits, int outbits, StartingMode startingMode);
00577 
00579     virtual ~ConvCodeTrellis();
00580 
00581     void printStateDiagram(std::ostream &os) const;
00582 
00584     virtual simth::BitSeq* Encode(const simth::BitSeq&)const;
00585 
00586     virtual void Encode(const simth::BitSeq &bsin, simth::BitSeq* bsout) const;
00587 
00588    protected:
00589 
00591     // muss noch effizienter werden ! -> erledigt durch Array2d!
00592     //simth::checkedVector2d<TrellisBranch> forward;
00593     Trellis::TrellisStatesArray forward;
00595     //simth::checkedVector2d<TrellisBranch> back;
00596     Trellis::TrellisStatesArray back;
00597     //TrellisBranch** forward;
00598     simth::Array<int> terminationInput_;
00599     //TrellisBranch** back;
00600     Trellis::TrellisStatesArray terminationForward;
00601     Trellis::TrellisStatesArray terminationBack;
00602 
00607     virtual int getNextState(int state, int input, size_t step,size_t path_length) const;
00608 
00611     virtual int getNextOut(int state, int input, size_t step,size_t path_length) const;
00612 
00616     virtual int getPrevState(int state, int index, size_t step,size_t path_length) const;
00617 
00621     virtual int getPrevOut(int state, int index, size_t step,size_t path_length) const;
00622 
00626     virtual int getPrevIn(int state, int index, size_t step,size_t path_length) const;
00627 
00630     virtual const Trellis::TrellisStatesArray&
00631       getPrevTrellisArray(size_t time_step, size_t path_length) const;
00632 
00633     ConvCodeTrellis::StartingMode startingMode() const {return startingMode_;}
00634 
00638     virtual bool isPossibleStartingState(int state) const = 0;
00639 
00644     virtual int terminationInput(int state) const;
00645  
00646   private:
00647 
00650     static const char *punct2[14][7];
00651 
00654     static const char *punct3[8][4];
00655 
00658     static const char *punct4;
00659 
00662     const StartingMode startingMode_;
00663 
00664 };
00665 
00666 
00667 inline int ConvCodeTrellis::getNextState(int state, int input, size_t step,size_t path_length) const
00668 {
00669   if(DEBUG) {
00670     if(step < 0 || step >= path_length) {
00671       throw std::logic_error("inline int ConvCodeTrellis::getNextState(int state, int input, "
00672                              "size_t step) const : error 1");
00673     }
00674   }
00675   if(!isTerminationStep(path_length,step)) {
00676     return forward[state][input].new_state;
00677   }
00678   else {
00679     return terminationForward[state][input].new_state;
00680   }
00681 }
00682 
00683 inline int ConvCodeTrellis::getNextOut(int state, int input, size_t step,size_t path_length) const
00684 {
00685   if(DEBUG) {
00686     if(step < 0 || step >= path_length) {
00687       throw std::logic_error("inline int ConvCodeTrellis::getNextOut(int state, int input, "
00688                              "size_t step) const : error 1");
00689     }
00690   }
00691   if(!isTerminationStep(path_length,step)) {
00692     return forward[state][input].output;
00693   }
00694   else {
00695     return terminationForward[state][input].output;
00696   }
00697 }
00698 
00699 inline int ConvCodeTrellis::getPrevState(int state, int index, size_t step,size_t path_length) const
00700 {
00701   if(DEBUG) {
00702     if(step < 0 || step >= path_length) {
00703       throw std::logic_error("inline int ConvCodeTrellis::getPrevState(int state, int input, "
00704                              "size_t step) const : error 1");
00705     }
00706   }
00707   if(!isTerminationStep(path_length,step)) {
00708     return back[state][index].prev_state;
00709   }
00710   else {
00711     return terminationBack[state][index].prev_state;
00712   }
00713 }
00714 
00715 inline int ConvCodeTrellis::getPrevOut(int state, int index, size_t step,size_t path_length) const
00716 {
00717   if(DEBUG) {
00718     if(step < 0 || step >= path_length) {
00719       throw std::logic_error("inline int ConvCodeTrellis::getPrevOut(int state, int input, "
00720                              "size_t step) const : error 1");
00721     }
00722   }
00723   if(!isTerminationStep(path_length,step)) {
00724     return back[state][index].output;
00725   }
00726   else {
00727     return terminationBack[state][index].output;
00728   }
00729 }
00730 
00731 inline int ConvCodeTrellis::getPrevIn(int state, int index, size_t step,size_t path_length) const
00732 {
00733   if(DEBUG) {
00734     if(step < 0 || step >= path_length) {
00735       throw std::logic_error("inline int ConvCodeTrellis::getPrevIn(int state, int input, "
00736                              "size_t step) const : error 1");
00737     }
00738   }
00739   if(!isTerminationStep(path_length,step)) {
00740     return back[state][index].input;
00741   }
00742   else {
00743     return terminationBack[state][index].input;
00744   }
00745 }
00746 inline const Trellis::TrellisStatesArray&
00747 ConvCodeTrellis::getPrevTrellisArray(size_t step, size_t path_length) const
00748 {
00749   if(DEBUG) {
00750     if(step < 0 || step >= path_length) {
00751       throw std::logic_error("inline int ConvCodeTrellis::getPrevIn(int state, int input, "
00752                              "size_t step) const : error 1");
00753     }
00754   }
00755   if(!isTerminationStep(path_length,step)) {
00756     return back;
00757   }
00758   else {
00759     return terminationBack;
00760   }
00761 }
00762 
00763 
00764 
00765 
00770 class ConvCodeTrellisShiftRegister : public ConvCodeTrellis
00771 {
00772   public:
00773 
00776     ConvCodeTrellisShiftRegister(int symbolsPerStep,
00777                     const simth::checkedVector<int>& polynomials, int recursivePolynomial, bool systematic);
00778 
00794     ConvCodeTrellisShiftRegister(int symbolsPerStep, 
00795                  int bitsPerSymbol,StartingMode startingMode,
00796                  map_type mappMode,
00797                  const simth::checkedVector<int>& polynomials, 
00798                  int recursivePolynomial, bool systematic=false);
00799 
00800 
00801 
00803     virtual ~ConvCodeTrellisShiftRegister();
00804 
00805 
00806     int symbolsPerStep() const {return symbolsPerStep_;}
00807     int bitsPerSymbol() const {return bitsPerSymbol_;}
00808 
00809     virtual void print(std::ostream &os) const;
00810 
00811  protected:
00812 
00816     virtual bool isPossibleStartingState(int state) const;
00817 
00818  private:
00819 
00821     ShiftRegister* shiftRegister;
00822     ShiftRegister* terminationShiftRegister;
00823 
00824     //mapping
00825     MappingScheme* usedMapping;
00826 
00827     int symbolsPerStep_;
00828     int bitsPerSymbol_;
00829 
00830     //Initializes the array of the base class ConvCodeTrellis:
00831     void initTrellis();
00832 };
00833 
00834 
00835 
00836 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00837 
00838 
00843 class ConvCodeTrellisExplicit : public ConvCodeTrellis
00844 {
00845   public:
00846 
00860     ConvCodeTrellisExplicit(int inbits, int outbits, StartingMode startingMode,map_type mappMode);
00861 
00862      /* Constructor that allows to set each parameter explicitly.
00863         
00864         The second argument specifies the bits per input symbol. For a conventional binary
00865         code this argument equals one. In this case the input symbols are actually input bits. 
00866         Hence in this case the first parameter sets the number of input bits.    
00867  
00868         @param symbolsPerStep  The number of input symbols per step (or bits, see above)
00869         @param bitsPerSymbol   The number of bits per input symbol
00870         @param startingMode    For conventional codes the starting mode should be set to 'ZERO'.
00871         @param mappMode        For conventional codes the mapping mode should be set to 'NATURAL'
00872         @param polynomials     The sequence of forward polynomials specifying the code
00873         @param recursivePolynomial The recursive polynomial (equals 0 for non recursive codes)  
00874         @param systematic      If true a systematic part is considered
00875       
00876     */
00877     //ConvCodeTrellisExplicit(int symbolsPerStep, int bitsPerSymbol,StartingMode startingMode,
00878     //              map_type mappMode,
00879     //              const simth::checkedVector<int>& polynomials, int recursivePolynomial, bool systematic=false);
00880 
00881 
00882 
00884     virtual ~ConvCodeTrellisExplicit();
00885 
00886 
00887     //int symbolsPerStep() const {return symbolsPerStep_;}
00888     //int bitsPerSymbol() const {return bitsPerSymbol_;}
00889 
00890     virtual void print(std::ostream &os) const;
00891 
00892  protected:
00893 
00897     virtual bool isPossibleStartingState(int state) const;
00898 
00899  private:
00900 
00901     //mapping
00902     MappingScheme* usedMapping;
00903 
00904     //    int symbolsPerStep_;
00905     //int bitsPerSymbol_;
00906 
00907     //Initializes the array of the base class ConvCodeTrellis:
00908     void initTrellis();
00909 };
00910 
00911 
00912 
00913 
00914 
00915 
00916 
00917 
00918 
00919 
00920 
00921 
00922 
00923 
00924 
00925 
00926 
00927 
00928 
00929 
00930 
00931 
00932 
00933 
00934 
00935 
00937 class AdachiTrellis : public Trellis
00938 {
00939 
00940   private:
00941 
00943     Trellis::TrellisStatesArray forward;
00944     //TrellisBranch **forward;
00945 
00947     Trellis::TrellisStatesArray back;
00948     //TrellisBranch **back;
00949 
00950   protected:
00951 
00956     virtual int getNextState(int state, int input, size_t step,size_t path_length) const;
00957 
00959     virtual int getNextOut(int state, int input, size_t step, size_t path_length) const;
00960 
00964     virtual int getPrevState(int state, int index, size_t step, size_t path_length) const;
00965 
00967     virtual int getPrevOut(int state, int index, size_t step, size_t path_length) const;
00968 
00972     virtual int getPrevIn(int state, int index, size_t step, size_t path_length) const;
00973 
00976     virtual const Trellis::TrellisStatesArray&
00977       getPrevTrellisArray(size_t time_step, size_t path_length) const;
00978 
00979     virtual bool isPossibleStartingState(int state) const;
00980 
00986     virtual int terminationInput(int state) const;
00987 
00988   public:
00991     AdachiTrellis(const DiffDemodulator& demod);
00992 
00994     ~AdachiTrellis();
00995 
00996 };
00997 
00998 
00999 inline AdachiTrellis::~AdachiTrellis()
01000 {
01001   //DelArray2D(forward);
01002   //DelArray2D(back);
01003 }
01004 
01005 inline int AdachiTrellis::getNextState(int state, int input, size_t /*step*/,size_t /*path_length*/) const
01006 {
01007   return forward[state][input].new_state;
01008 }
01009 
01010 inline int AdachiTrellis::getNextOut(int state, int input, size_t /*step*/,size_t /*path_length*/) const
01011 {
01012   return forward[state][input].output;
01013 }
01014 
01015 inline int AdachiTrellis::getPrevState(int state, int index, size_t /*step*/,size_t /*path_length*/) const
01016 {
01017   return back[state][index].prev_state;
01018 }
01019 
01020 inline int AdachiTrellis::getPrevOut(int state, int index, size_t /*step*/,size_t /*path_length*/) const
01021 {
01022   return back[state][index].output;
01023 }
01024 
01025 inline int AdachiTrellis::getPrevIn(int state, int index, size_t /*step*/,size_t /*path_length*/) const
01026 {
01027   return back[state][index].input;
01028 }
01029 inline const Trellis::TrellisStatesArray&
01030 AdachiTrellis::getPrevTrellisArray(size_t time_step, size_t path_length) const
01031 {
01032   return back;
01033 }
01034 
01035 }
01036 
01037 
01038 
01039 #endif

Generated on Tue Aug 9 14:35:11 2005 for simtheticlib by  doxygen 1.4.1