00001 /*************************************************************************** 00002 trellisdecoding.h - description 00003 ------------------- 00004 begin : Mit Aug 6 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 TRELLISDECODING_H 00029 #define TRELLISDECODING_H 00030 00031 #include <iostream> 00032 #include <iomanip> 00033 #include <complex> 00034 #include <stdexcept> 00035 #include <algorithm> 00036 #include <memory> 00037 00038 00039 //#include "ofdmlimits.h" 00040 #include "signals.h" 00041 #include "misc.h" 00042 #include "phbib.h" 00043 #include "modulator.h" 00044 #include "demodulator.h" 00045 #include "trellis.h" 00046 00047 00048 00049 00050 namespace simthlib{ 00051 00052 00053 //-------------------------------------------------------------------- 00054 // 00055 // Trellis - Diagramm 00056 // 00057 //-------------------------------------------------------------------- 00058 // 00059 // class Trellis tre 00060 // 00061 // tre ist ein Trellisdiagramm, das einen Automaten mit Speicher m, 00062 // Eingaben i und Ausgaben o beschreibt, wobei 00063 // m' = f(m, i) 00064 // o = g(m, i) 00065 // Eine Eingabesequenz <i> erzeugt eine Ausgabesequenz <o>. Dabei 00066 // wird als Anfangszustand des Automaten NICHT immer der 00067 // Nullzustand angenommen, sondern die angehaengten Nullen werden 00068 // durch eine Beeinflussung der Metrik beruecksichtigt. Wenn eine 00069 // Ausgangssequenz bzw. eine zugehoerige 00070 // Metrik gegeben ist, dann kann mit Hilfe des Viterbi - Algorithmus 00071 // die Eingangssequenz geschaetzt werden. 00072 // 00073 // Folgende Eigenschaften werden fuer jedes Objekt gespeichert: 00074 // Speicherlaenge 00075 // Zahl der Speicherzustaende 00076 // Zahl der Eingangsbits 00077 // Zahl der Eingangszustaende 00078 // Zahl der Ausgangsbits 00079 // Zahl der Ausgangszustaende 00080 // Zahl der an die Daten angehaengten Nullbits 00081 // Zahl der an die Daten angehaengten Nullzustaende 00082 // Zahl der verschiedenen Modulationssymbole 00083 // Zahl der Zeitschritte, die bei einer Sequenzschaetzung 00084 // betrachtet werden 00085 // Laenge des Trellisdiagramms in Zeitschritten 00086 // Gesamtmetriken fuer alle Pfade 00087 // Pfade 00088 // 00089 // Folgende Funktionen sind implementiert: 00090 // ======================================= 00091 // 00092 // Konstruktoren 00093 // Trellis(states, inbits, length) 00094 // states: (maximale) Zahl der Zustaende 00095 // inbits: Zahl der Eingangsbits pro Zeitschritt 00096 // length: Laenge des Trellisdiagramms in Zeitschritten 00097 // 00098 // Operatoren 00099 // llv[i]: Zugriff auf i-ten Vektor mit Metrikinkrementen 00100 // cout << llv: Ausgabe der Metrik 00101 // 00102 // Funktionen 00103 // getNumInbits() Gibt die Zahl der Eingangsbits 00104 // getNumInput() Gibt die Zahl der Eingangszustaende 00105 // getNumOutbits() Gibt die Zahl der Ausgangsbits 00106 // getNumOutput() Gibt die Zahl der Ausgangszustaende 00107 // SeqEstimate(llvSeq &metr, bitSeq* &bs): 00108 // Fuehrt eine Sequenzschaetzung mit dem Viterbi - Algorithmus 00109 // durch und liefert die geschaetzten Eingangsbits als 00110 // Bitsequenz 00111 // 00112 // Pure Virtuelle Funktionen: 00113 // ===================== 00114 // 00115 // getNextState(int state, int input, size_t step)=0; 00116 // Liefert den Folgezustand zum Zustand state bei der Eingabe 00117 // von input im Zeitschritt step 00118 // getNextOut(int state, int input, size_t step)=0; 00119 // Liefert die zugehoerige Ausgabe 00120 // getPrevState(int state, int index, size_t step)=0; 00121 // Liefert den Vorgaengerzustand zum Zustand state, in den im 00122 // Zeitschritt step der Zweig index fuehrt 00123 // getPrevOut(int state, int index, size_t step)=0; 00124 // Liefert die zugehoerige Ausgabe 00125 // getPrevIn(int state, int index, size_t step)=0; 00126 // Liefert die zugehoerige Eingabe 00127 // 00128 // Alle virtuellen Funktionen muessen in den konkreten Trellis- 00129 // diagrammen zu einem bestimmten Automaten definiert werden 00130 // 00131 //-------------------------------------------------------------------- 00132 00133 00154 class TrellisDecodingAlgorithm 00155 { 00156 00157 public: 00158 00159 TrellisDecodingAlgorithm(std::auto_ptr<Trellis> usedTrellis); 00160 virtual ~TrellisDecodingAlgorithm(); 00161 00164 virtual void decode(const simth::LlvSeq &metr, simth::BitSeq* decodedData, const simth::LlrSeq* apri = NULL) = 0; 00165 00166 const Trellis* trellis() {return usedTrellis_;} 00167 00168 protected: 00169 00170 Trellis* usedTrellis() {return usedTrellis_;} 00171 00172 size_t getPathLength() const {return pathLength_;} 00173 void setPathLength(int newPathLength); 00174 00175 // Allow derived classes to use this directly because it is called 00176 // a *lot* of times during the Viterbi 00177 Trellis* usedTrellis_; 00178 00179 private: 00180 00181 size_t pathLength_; 00182 00183 }; 00184 00185 00186 inline void TrellisDecodingAlgorithm::setPathLength(int newPathLength) 00187 { 00188 if(DEBUG){ 00189 if(newPathLength<=0){ 00190 throw std::runtime_error("inline void TrellisDecodingAlgorithm::setPathLength(int newPathLength) : newPathLength <= 0"); 00191 } 00192 } 00193 pathLength_ = newPathLength; 00194 00195 } 00196 00197 00198 namespace trellisdecoding{ 00199 00201 enum DecodingAlgorithmMode{ DA_VITERBI }; 00202 00203 00204 std::auto_ptr<TrellisDecodingAlgorithm> makeDecodingAlgorithm(DecodingAlgorithmMode mode, int mem, 00205 int inSymbols, int outSymbols); 00206 00207 std::auto_ptr<TrellisDecodingAlgorithm> makeDecodingAlgorithm(DecodingAlgorithmMode mode, int inSymbolsPerStep, 00208 const simth::checkedVector<int>& polynomials); 00209 00210 std::auto_ptr<TrellisDecodingAlgorithm> makeDecodingAlgorithm(DecodingAlgorithmMode mode, int inSymbolsPerStep, 00211 const simth::checkedVector<int>& polynomials, int recursivePolynomial, bool systematic); 00212 00213 std::auto_ptr<TrellisDecodingAlgorithm> makeDecodingAlgorithm(DecodingAlgorithmMode mode, int inSymbolsPerStep, 00214 int bitsPerSymbol, ConvCodeTrellis::StartingMode startingMode, map_type mappMode, const simth::checkedVector<int>& polynomials, 00215 int recursivePolynomial, bool systematic); 00216 00217 00218 } 00219 } 00220 00221 #endif