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 SOFTOUTDECODING_HEADER
00029 #define SOFTOUTDECODING_HEADER
00030
00031 #include <iostream>
00032 #include <string>
00033 #include <complex>
00034 #include <memory>
00035
00036
00037 #include "trellis.h"
00038 #include "misc.h"
00039 #include "signals.h"
00040 #include "trellissoftout.h"
00041 #include "puncturing.h"
00042
00043
00044
00045
00046 namespace simthlib{
00047
00048 namespace softoutdecoding
00049 {
00050
00058 inline void makeExtrinsic(const simth::LlrSeq& previousInfo,simth::LlrSeq* newInfo)
00059 {
00060 if(DEBUG) {
00061 if(previousInfo.size() != newInfo->size()) {
00062 throw std::runtime_error("inline void makeExtrinsic(const simth::LlrSeq& previousInfo,"
00063 "simth::LlrSeq newInfo) : Error 1");
00064 }
00065 }
00066 for(size_t pos = 0; pos < previousInfo.size(); pos++) {
00067 (*newInfo)[pos] -= previousInfo[pos];
00068 }
00069 }
00070
00076 inline void addExtrinsic(const simth::LlrSeq& sysInfo, simth::LlrSeq* newInfo)
00077 {
00078 if(DEBUG) {
00079 if(sysInfo.size() != newInfo->size()) {
00080 throw std::runtime_error("inline void addExtrinsic(const simth::LlrSeq& sysInfo,"
00081 "simth::LlrSeq newInfo) : Error 1");
00082 }
00083 }
00084 for(size_t pos=0; pos< sysInfo.size(); pos++) {
00085 (*newInfo)[pos] += sysInfo[pos];
00086 }
00087 }
00088
00089
00091 void addAPriori(const simth::LlrSeq& inMain,
00092 const simth::LlrSeq& inAPriori,
00093 simth::LlrSeq* inNew);
00094
00095
00096 }
00097
00110 class SoftoutDecoding
00111 {
00112
00113 protected:
00114
00115
00116 public:
00117
00118 virtual ~SoftoutDecoding();
00119
00120
00121
00122
00123
00124
00128 virtual void softout4InputBits(simth::LlrSeq &metr,
00129 simth::LlrSeq* softout,
00130 simth::LlrSeq* apri = NULL)=0;
00131
00136 virtual void softout4OutputBits(const simth::LlrSeq &metr,
00137 simth::LlrSeq* softout,
00138 simth::LlrSeq* apri = NULL)=0;
00139
00140
00143 virtual void softout4InputBits(simth::LlvSeq &metr, simth::LlrSeq* softout, simth::LlrSeq* apri = NULL)=0;
00144
00148 virtual void softout4OutputBits(const simth::LlvSeq &metr, simth::LlrSeq* softout, simth::LlrSeq* apri = NULL)=0;
00149
00150
00151
00159 virtual void normalDecoding(const simth::LlrSeq &llr, simth::BitSeq& bsout)=0;
00160
00164 virtual int getDataLength(int codedLength) const = 0;
00165
00169 virtual int getCodeLength(int rawLength) const = 0;
00170
00179 virtual void reset() = 0;
00180
00181 virtual void print(std::ostream &os) const = 0;
00182
00183 };
00184
00195 class StreamSoftoutDecoding : public SoftoutDecoding
00196 {
00197
00198 public:
00199
00200 StreamSoftoutDecoding();
00201
00202 virtual ~StreamSoftoutDecoding();
00203
00208 virtual int dataBitsPerStep() const = 0;
00213 virtual int codedBitsPerStep() const = 0;
00214
00215 };
00216
00226 class StreamSoftoutDecodingTailbits : public StreamSoftoutDecoding
00227 {
00228
00229 public:
00230
00231 StreamSoftoutDecodingTailbits();
00232
00233 virtual size_t numTailbits() const = 0;
00234
00235 };
00236
00243 class TrellisSoftoutDecoding : public StreamSoftoutDecodingTailbits
00244 {
00245 private:
00246
00247 TrellisSoftoutAlgorithm* usedAlgorithm;
00248
00249 protected:
00250
00251
00252 public:
00253
00262 TrellisSoftoutDecoding(std::auto_ptr<TrellisSoftoutAlgorithm> algorithm_ptr);
00263
00269 virtual void reset();
00270
00274 virtual void softout4InputBits(simth::LlvSeq &metr, simth::LlrSeq* softout, simth::LlrSeq* apri = NULL);
00275
00281 virtual void softout4OutputBits(const simth::LlvSeq &metr,
00282 simth::LlrSeq* softout,
00283 simth::LlrSeq* apri = NULL);
00284
00285
00286
00289 virtual void softout4InputBits(simth::LlrSeq &metr, simth::LlrSeq* softout, simth::LlrSeq* apri = NULL);
00290
00295 virtual void softout4OutputBits(const simth::LlrSeq &metr, simth::LlrSeq* softout, simth::LlrSeq* apri = NULL);
00296
00297
00298
00299
00300
00301
00302
00303
00304 virtual void normalDecoding(const simth::LlrSeq &llr, simth::BitSeq& bsout);
00305
00306
00307 virtual ~TrellisSoftoutDecoding();
00308
00309 virtual int getDataLength(int codedLength) const;
00310
00311
00312
00313
00314 virtual int getCodeLength(int rawLength) const;
00315
00320 virtual int dataBitsPerStep() const {return usedAlgorithm->getTrellis()->numInbits();}
00325 virtual int codedBitsPerStep() const {return usedAlgorithm->getTrellis()->numOutbits();}
00326
00329 size_t numTailbits() const {return usedAlgorithm->getTrellis()->numTailbits();}
00330
00331
00332
00333
00334
00335 virtual void print(std::ostream &os) const;
00336 };
00337
00338 inline int TrellisSoftoutDecoding::getCodeLength(int dataLength) const
00339 {
00340 return usedAlgorithm->getTrellis()->getCodeLength(dataLength);
00341 }
00342
00343
00344 inline int TrellisSoftoutDecoding::getDataLength(int codeLength) const
00345 {
00346 return usedAlgorithm->getTrellis()->getDataLength(codeLength);
00347 }
00348
00349
00356 class ConvSoftoutDecoding : public TrellisSoftoutDecoding
00357 {
00358 public:
00366 ConvSoftoutDecoding(int mem, int inbits, int outbits, trellissoftout::softoutalgorithmmode soMode);
00367
00368 ConvSoftoutDecoding(int inSymbolsPerStep, const simth::checkedVector<int>& polynome,
00369 trellissoftout::softoutalgorithmmode soMode);
00370
00371 ConvSoftoutDecoding(int inSymbolsPerStep, const simth::checkedVector<int>& polynome,
00372 int recursivePolynomial, bool systematic, trellissoftout::softoutalgorithmmode soMode);
00373
00374 ConvSoftoutDecoding(int inSymbolsPerStep, int bitsPerSymbol, simthlib::ConvCodeTrellis::StartingMode startingMode, simthlib::map_type mapMode,
00375 const simth::checkedVector<int>& polynome, int recursivePolynomial,
00376 trellissoftout::softoutalgorithmmode soMode);
00377
00378 virtual ~ConvSoftoutDecoding();
00379
00380 virtual void print(std::ostream &os) const {TrellisSoftoutDecoding::print(os);}
00381 };
00382
00383
00384
00388 class SoftoutDAPSKDecoding : public StreamSoftoutDecodingTailbits
00389 {
00390 ConvSoftoutDecoding* amplDecoding;
00391 ConvSoftoutDecoding* phaseDecoding;
00392
00393 mutable int numInSize;
00394 mutable int numInAmplSize;
00395 mutable int numInPhaseSize;
00396
00397 int bitsPerAmpl_;
00398 int bitsPerPhase_;
00399
00400 template<class seqT_in, class seqT_out>
00401 void splitSequence(const seqT_in& inputBits,
00402 seqT_out* amplSeq, seqT_out* phaseSeq) const;
00403 template<class T>
00404 void mergeSequences(const T& amplSeq, const T& phaseSeq, T* outSeq) const;
00405
00406 int decodedLength_;
00407
00408 void invariante() const;
00409
00410 protected:
00411
00412 int bitsPerAmpl() const {return bitsPerAmpl_;}
00413 int bitsPerPhase() const {return bitsPerPhase_;}
00414
00415 void computeSplittedSizes(int numInSize, int* amplSize, int* phaseSize) const;
00416
00417 public:
00418
00419 SoftoutDAPSKDecoding(int inSymbolsPerStep, int bitsPerSymbol, simthlib::ConvCodeTrellis::StartingMode starting,
00420 simthlib::map_type mappMode,
00421 const simth::checkedVector<int>& polynomials, const int recursivePolynomial,
00422 trellissoftout::softoutalgorithmmode soMode);
00423
00424
00425 virtual ~SoftoutDAPSKDecoding();
00426
00432 virtual void reset();
00433
00434
00435
00436
00437
00438 virtual int getDataLength(int codedLength) const;
00439
00440
00441
00442
00443 virtual int getCodeLength(int rawLength) const;
00444
00445
00446
00450 virtual void softout4InputBits(simth::LlvSeq &metr, simth::LlrSeq* softout, simth::LlrSeq* apri = NULL);
00451
00457 virtual void softout4OutputBits(const simth::LlvSeq &metr, simth::LlrSeq* softout, simth::LlrSeq* apri = NULL);
00458
00459
00460
00465 virtual void softout4InputBits(simth::LlrSeq &metr, simth::LlrSeq* softout, simth::LlrSeq* apri = NULL);
00466
00472 virtual void softout4OutputBits(const simth::LlrSeq &metr, simth::LlrSeq* softout, simth::LlrSeq* apri = NULL);
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482 virtual void normalDecoding(const simth::LlrSeq &llr, simth::BitSeq& bsout);
00483
00484 virtual int dataBitsPerStep() const {return (amplDecoding->dataBitsPerStep()+phaseDecoding->dataBitsPerStep());}
00485 virtual int codedBitsPerStep() const {return (amplDecoding->codedBitsPerStep()+phaseDecoding->codedBitsPerStep());}
00486
00487 virtual void print(std::ostream &os) const;
00488
00489 virtual size_t numTailbits() const {return (amplDecoding->numTailbits());}
00490
00491 };
00492
00493
00494 inline void SoftoutDAPSKDecoding::invariante() const
00495 {
00496 if(DEBUG) {
00497 if(numInAmplSize + numInPhaseSize != numInSize) {
00498 throw std::logic_error("void SoftoutDAPSKDecoding::invariante() const : error 1");
00499 }
00500 }
00501 }
00502
00503
00504 template<class seqT_in, class seqT_out>
00505 inline void SoftoutDAPSKDecoding::splitSequence(const seqT_in &bsin,
00506 seqT_out* amplSeq,
00507 seqT_out* phaseSeq) const
00508 {
00509 if(DEBUG) {
00510 if(bsin.size() % (bitsPerAmpl()+bitsPerPhase()) != 0) {
00511 throw std::runtime_error("void SoftoutDAPSKDecoding::splitSequence(const simth::BitSeq &bsin, simth::BitSeq* amplSeq, simth::BitSeq* phaseSeq) "
00512 "const : bit size is not a multiplier of bitsPerSymbol");
00513 }
00514 }
00515 if(numInSize != int(bsin.size())) {
00516 numInSize = bsin.size();
00517 computeSplittedSizes(numInSize, &numInAmplSize, &numInPhaseSize);
00518 }
00519 if(int(amplSeq->size()) != numInAmplSize) {
00520 amplSeq->resize(numInAmplSize);
00521 }
00522 if(int(phaseSeq->size()) != numInPhaseSize) {
00523 phaseSeq->resize(numInPhaseSize);
00524 }
00525 typename seqT_in::const_iterator iter = bsin.begin();
00526 typename seqT_out::iterator iterAmpl = amplSeq->begin();
00527 typename seqT_out::iterator iterPhase = phaseSeq->begin();
00528 while(iter != bsin.end()) {
00529 for(int p=0; p<bitsPerPhase();p++) {
00530 (*iterPhase) = (*iter);
00531 iterPhase++;
00532 iter++;
00533 }
00534 for(int a=0; a<bitsPerAmpl();a++) {
00535 (*iterAmpl) = (*iter);
00536 iterAmpl++;
00537 iter++;
00538 }
00539 }
00540 if(DEBUG) {
00541 if(iter != bsin.end()) {
00542 throw std::logic_error("void SoftoutDAPSKDecoding::splitSequence(const simth::BitSeq &bsin, simth::BitSeq* amplSeq, simth::BitSeq* phaseSeq) "
00543 "const : error 1");
00544 }
00545 if(iterAmpl != amplSeq->end()) {
00546 throw std::logic_error("void SoftoutDAPSKDecoding::splitSequence(const simth::BitSeq &bsin, simth::BitSeq* amplSeq, simth::BitSeq* phaseSeq) "
00547 "const : error 2");
00548 }
00549 if(iterPhase != phaseSeq->end()) {
00550 throw std::logic_error("void SoftoutDAPSKDecoding::splitSequence(const simth::BitSeq &bsin, simth::BitSeq* amplSeq, simth::BitSeq* phaseSeq) "
00551 "const : error 3");
00552 }
00553 }
00554 invariante();
00555 }
00556
00557
00558 template<class T>
00559 inline void SoftoutDAPSKDecoding::mergeSequences(const T& amplSeq, const T& phaseSeq, T* outSeq) const
00560 {
00561 if(DEBUG) {
00562 if(amplSeq.size()*bitsPerPhase() != phaseSeq.size()*bitsPerAmpl()) {
00563 throw std::logic_error("void SoftoutDAPSKDecoding::mergeSequences(const simth::BitSeq& amplSeq, const simth::BitSeq& phaseSeq, "
00564 "simth::BitSeq* outSeq) const : error 1");
00565 }
00566 }
00567 outSeq->resize(amplSeq.size()+phaseSeq.size());
00568
00569 typename T::const_iterator iterAmpl = amplSeq.begin();
00570 typename T::const_iterator iterPhase = phaseSeq.begin();
00571 typename T::iterator iter = outSeq->begin();
00572 while(iter != outSeq->end()) {
00573 for(int p=0; p<bitsPerPhase();p++) {
00574 (*iter) = (*iterPhase);
00575 iterPhase++;
00576 iter++;
00577 }
00578 for(int a=0; a<bitsPerAmpl();a++) {
00579 (*iter) = (*iterAmpl);
00580 iterAmpl++;
00581 iter++;
00582 }
00583 }
00584 if(DEBUG) {
00585 if(iter != outSeq->end()) {
00586 throw std::logic_error("void SoftoutDAPSKDecoding::mergeSequence(const simth::BitSeq &bsin, simth::BitSeq* amplSeq, simth::BitSeq* phaseSeq) "
00587 "const : error 1");
00588 }
00589 if(iterAmpl != amplSeq.end()) {
00590 throw std::logic_error("void SoftoutDAPSKDecoding::mergeSequence(const simth::BitSeq &bsin, simth::BitSeq* amplSeq, simth::BitSeq* phaseSeq) "
00591 "const : error 2");
00592 }
00593 if(iterPhase != phaseSeq.end()) {
00594 throw std::logic_error("void SoftoutDAPSKDecoding::mergeSequence(const simth::BitSeq &bsin, simth::BitSeq* amplSeq, simth::BitSeq* phaseSeq) "
00595 "const : error 3");
00596 }
00597 }
00598 }
00599
00600
00601
00602
00611 class PunctConvSoftoutDecoding : public ConvSoftoutDecoding
00612 {
00613 private:
00614
00615 simthlib::Puncturing* usedPuncturing;
00616
00617 protected:
00618
00619
00620 public:
00630 PunctConvSoftoutDecoding(int codeRateNumerator,int codeRateDenumerator,
00631 int mem, int inbits, int outbits,
00632 trellissoftout::softoutalgorithmmode soMode);
00633
00634
00635 PunctConvSoftoutDecoding(int codeRateNumerator,int codeRateDenumerator, int inbitsPerStep,
00636 const simth::checkedVector<int>& polynome, int recursivePolynomial, bool systematic,
00637 trellissoftout::softoutalgorithmmode soMode);
00638
00639 PunctConvSoftoutDecoding(const std::string& puncturingPattern, int inbitsPerStep,
00640 const simth::checkedVector<int>& polynome, int recursivePolynomial, bool systematic,
00641 trellissoftout::softoutalgorithmmode soMode);
00642
00643 ~PunctConvSoftoutDecoding();
00644
00645
00646
00647
00648
00652 virtual void softout4InputBits(simth::LlvSeq &metr, simth::LlrSeq* softout, simth::LlrSeq* apri = NULL);
00653
00659 virtual void softout4OutputBits(const simth::LlvSeq &metr, simth::LlrSeq* softout, simth::LlrSeq* apri = NULL);
00660
00661
00662
00666 virtual void softout4InputBits(simth::LlrSeq &metr, simth::LlrSeq* softout, simth::LlrSeq* apri = NULL);
00667
00672 virtual void softout4OutputBits(const simth::LlrSeq &metr, simth::LlrSeq* softout, simth::LlrSeq* apri = NULL);
00673
00674
00675
00676
00677
00678
00679
00680
00681 virtual void normalDecoding(const simth::LlrSeq &llr, simth::BitSeq& bsout);
00682
00683
00684
00685
00686
00687 virtual int getDataLength(int codedLength) const;
00688
00689
00690
00691
00692 virtual int getCodeLength(int rawLength) const;
00693
00694 virtual int codedBitsPerStep() const {return ConvSoftoutDecoding::codedBitsPerStep();}
00695
00696 void setPuncturing(const std::string& newPuncturePattern);
00697 };
00698
00699
00700
00701
00702 }
00703
00704
00705 #endif