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

softoutdecoding.h

Go to the documentation of this file.
00001 /*-*-c++-*-****************************************************************
00002                           softoutdecoding.h  -  description
00003                              -------------------
00004     begin                : Mit Mai 22 2002
00005     copyright            : (C) 2002 by Peter Haase
00006     email                : mail@p-haase.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 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   //    virtual void setDecodedLength(int decodedLength) = 0;
00121   //  virtual int  getDecodedLength() const = 0;
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     /* Performs a maximum likelihood sequence estimation of the
00298     data sequence based on the log-likelihood ratios of the
00299     received modulation symbols (soft decision decoding without
00300     soft {\em out}put) This can be usefull in the last step of
00301     an iterative decoding procedure, when no soft-out information
00302     is needed.
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     /* Returns the length of the coded bit sequence which the
00312     coder generates from a data sequence of the given length.
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     /* calculates log-likelihood ratios of the
00332     data sequence based on the log-likelihood values of received
00333     modulation symbols (soft in / soft out decoding) */
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     /* Returns the length of a data bit sequence which can be
00435     encoded into a coded bit sequence of the given length.
00436 
00437     */
00438     virtual int getDataLength(int codedLength) const;
00439 
00440     /* Returns the length of the coded bit sequence which the
00441     coder generates from a data sequence of the given length.
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     /* Performs a maximum likelihood sequence estimation of the
00475     data sequence based on the log-likelihood ratios of the
00476     received modulation symbols (soft decision decoding without
00477     soft em out put) This can be usefull in the last step of
00478     an iterative decoding procedure, when no soft-out information
00479     is needed.
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());} //just in order to make the file compiled. (Zhao)
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   //virtual void updateInputLengths();
00646   //  virtual void updateOutputLengths();
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     /* Performs a maximum likelihood sequence estimation of the
00675     data sequence based on the log-likelihood ratios of the
00676     received modulation symbols (soft decision decoding without
00677     soft put) This can be usefull in the last step of
00678     an iterative decoding procedure when no soft-out information
00679     is needed.  -
00680     */
00681     virtual void normalDecoding(const simth::LlrSeq &llr, simth::BitSeq& bsout);
00682 
00683     /* Returns the length of a data bit sequence which can be
00684     encoded into a coded bit sequence of the given length.
00685 
00686     */
00687     virtual int getDataLength(int codedLength) const;
00688 
00689     /* Returns the length of the coded bit sequence which the
00690     coder generates from a data sequence of the given length.
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

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