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
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
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
00314
00315
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
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
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
00592
00593 Trellis::TrellisStatesArray forward;
00595
00596 Trellis::TrellisStatesArray back;
00597
00598 simth::Array<int> terminationInput_;
00599
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
00825 MappingScheme* usedMapping;
00826
00827 int symbolsPerStep_;
00828 int bitsPerSymbol_;
00829
00830
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
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00884 virtual ~ConvCodeTrellisExplicit();
00885
00886
00887
00888
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
00902 MappingScheme* usedMapping;
00903
00904
00905
00906
00907
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
00945
00947 Trellis::TrellisStatesArray back;
00948
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
01002
01003 }
01004
01005 inline int AdachiTrellis::getNextState(int state, int input, size_t ,size_t ) const
01006 {
01007 return forward[state][input].new_state;
01008 }
01009
01010 inline int AdachiTrellis::getNextOut(int state, int input, size_t ,size_t ) const
01011 {
01012 return forward[state][input].output;
01013 }
01014
01015 inline int AdachiTrellis::getPrevState(int state, int index, size_t ,size_t ) const
01016 {
01017 return back[state][index].prev_state;
01018 }
01019
01020 inline int AdachiTrellis::getPrevOut(int state, int index, size_t ,size_t ) const
01021 {
01022 return back[state][index].output;
01023 }
01024
01025 inline int AdachiTrellis::getPrevIn(int state, int index, size_t ,size_t ) 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