diff options
Diffstat (limited to 'gr-trellis/src/lib/core_algorithms.cc')
-rw-r--r-- | gr-trellis/src/lib/core_algorithms.cc | 1437 |
1 files changed, 0 insertions, 1437 deletions
diff --git a/gr-trellis/src/lib/core_algorithms.cc b/gr-trellis/src/lib/core_algorithms.cc deleted file mode 100644 index 442565054a..0000000000 --- a/gr-trellis/src/lib/core_algorithms.cc +++ /dev/null @@ -1,1437 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#include <cstring> -#include <stdexcept> -//#include <cstdio> -#include <iostream> -#include "core_algorithms.h" -#include "calc_metric.h" - -static const float INF = 1.0e9; - -float min(float a, float b) -{ - return a <= b ? a : b; -} - -float min_star(float a, float b) -{ - return (a <= b ? a : b)-log(1+exp(a <= b ? a-b : b-a)); -} - - - - -template <class T> -void viterbi_algorithm(int I, int S, int O, - const std::vector<int> &NS, - const std::vector<int> &OS, - const std::vector< std::vector<int> > &PS, - const std::vector< std::vector<int> > &PI, - int K, - int S0,int SK, - const float *in, T *out)//, - //std::vector<int> &trace) -{ - std::vector<int> trace(S*K); - std::vector<float> alpha(S*2); - int alphai; - float norm,mm,minm; - int minmi; - int st; - - - if(S0<0) { // initial state not specified - for(int i=0;i<S;i++) alpha[0*S+i]=0; - } - else { - for(int i=0;i<S;i++) alpha[0*S+i]=INF; - alpha[0*S+S0]=0.0; - } - - alphai=0; - for(int k=0;k<K;k++) { - norm=INF; - for(int j=0;j<S;j++) { // for each next state do ACS - minm=INF; - minmi=0; - for(unsigned int i=0;i<PS[j].size();i++) { - //int i0 = j*I+i; - if((mm=alpha[alphai*S+PS[j][i]]+in[k*O+OS[PS[j][i]*I+PI[j][i]]])<minm) - minm=mm,minmi=i; - } - trace[k*S+j]=minmi; - alpha[((alphai+1)%2)*S+j]=minm; - if(minm<norm) norm=minm; - } - for(int j=0;j<S;j++) - alpha[((alphai+1)%2)*S+j]-=norm; // normalize total metrics so they do not explode - alphai=(alphai+1)%2; - } - - if(SK<0) { // final state not specified - minm=INF; - minmi=0; - for(int i=0;i<S;i++) - if((mm=alpha[alphai*S+i])<minm) minm=mm,minmi=i; - st=minmi; - } - else { - st=SK; - } - - for(int k=K-1;k>=0;k--) { // traceback - int i0=trace[k*S+st]; - out[k]= (T) PI[st][i0]; - st=PS[st][i0]; - } - -} - - -template -void viterbi_algorithm<unsigned char>(int I, int S, int O, - const std::vector<int> &NS, - const std::vector<int> &OS, - const std::vector< std::vector<int> > &PS, - const std::vector< std::vector<int> > &PI, - int K, - int S0,int SK, - const float *in, unsigned char *out); - - -template -void viterbi_algorithm<short>(int I, int S, int O, - const std::vector<int> &NS, - const std::vector<int> &OS, - const std::vector< std::vector<int> > &PS, - const std::vector< std::vector<int> > &PI, - int K, - int S0,int SK, - const float *in, short *out); - -template -void viterbi_algorithm<int>(int I, int S, int O, - const std::vector<int> &NS, - const std::vector<int> &OS, - const std::vector< std::vector<int> > &PS, - const std::vector< std::vector<int> > &PI, - int K, - int S0,int SK, - const float *in, int *out); - - - -//============================================== - -template <class Ti, class To> -void viterbi_algorithm_combined(int I, int S, int O, - const std::vector<int> &NS, - const std::vector<int> &OS, - const std::vector< std::vector<int> > &PS, - const std::vector< std::vector<int> > &PI, - int K, - int S0,int SK, - int D, - const std::vector<Ti> &TABLE, - gr::digital::trellis_metric_type_t TYPE, - const Ti *in, To *out -) -{ - std::vector<int> trace(S*K); - std::vector<float> alpha(S*2); - float *metric = new float[O]; - int alphai; - float norm,mm,minm; - int minmi; - int st; - - if(S0<0) { // initial state not specified - for(int i=0;i<S;i++) alpha[0*S+i]=0; - } - else { - for(int i=0;i<S;i++) alpha[0*S+i]=INF; - alpha[0*S+S0]=0.0; - } - - alphai=0; - for(int k=0;k<K;k++) { - calc_metric(O, D, TABLE, &(in[k*D]), metric,TYPE); // calc metrics - norm=INF; - for(int j=0;j<S;j++) { // for each next state do ACS - minm=INF; - minmi=0; - for(unsigned int i=0;i<PS[j].size();i++) { - //int i0 = j*I+i; - if((mm=alpha[alphai*S+PS[j][i]]+metric[OS[PS[j][i]*I+PI[j][i]]])<minm) - minm=mm,minmi=i; - } - trace[k*S+j]=minmi; - alpha[((alphai+1)%2)*S+j]=minm; - if(minm<norm) norm=minm; - } - for(int j=0;j<S;j++) - alpha[((alphai+1)%2)*S+j]-=norm; // normalize total metrics so they do not explode - alphai=(alphai+1)%2; - } - - if(SK<0) { // final state not specified - minm=INF; - minmi=0; - for(int i=0;i<S;i++) - if((mm=alpha[alphai*S+i])<minm) minm=mm,minmi=i; - st=minmi; - } - else { - st=SK; - } - - for(int k=K-1;k>=0;k--) { // traceback - int i0=trace[k*S+st]; - out[k]= (To) PI[st][i0]; - st=PS[st][i0]; - } - - delete [] metric; - -} - -// Ti = s i f c -// To = b s i - -//--------------- - -template -void viterbi_algorithm_combined<short,unsigned char>(int I, int S, int O, - const std::vector<int> &NS, - const std::vector<int> &OS, - const std::vector< std::vector<int> > &PS, - const std::vector< std::vector<int> > &PI, - int K, - int S0,int SK, - int D, - const std::vector<short> &TABLE, - gr::digital::trellis_metric_type_t TYPE, - const short *in, unsigned char *out -); - -template -void viterbi_algorithm_combined<int,unsigned char>(int I, int S, int O, - const std::vector<int> &NS, - const std::vector<int> &OS, - const std::vector< std::vector<int> > &PS, - const std::vector< std::vector<int> > &PI, - int K, - int S0,int SK, - int D, - const std::vector<int> &TABLE, - gr::digital::trellis_metric_type_t TYPE, - const int *in, unsigned char *out -); - -template -void viterbi_algorithm_combined<float,unsigned char>(int I, int S, int O, - const std::vector<int> &NS, - const std::vector<int> &OS, - const std::vector< std::vector<int> > &PS, - const std::vector< std::vector<int> > &PI, - int K, - int S0,int SK, - int D, - const std::vector<float> &TABLE, - gr::digital::trellis_metric_type_t TYPE, - const float *in, unsigned char *out -); - -template -void viterbi_algorithm_combined<gr_complex,unsigned char>(int I, int S, int O, - const std::vector<int> &NS, - const std::vector<int> &OS, - const std::vector< std::vector<int> > &PS, - const std::vector< std::vector<int> > &PI, - int K, - int S0,int SK, - int D, - const std::vector<gr_complex> &TABLE, - gr::digital::trellis_metric_type_t TYPE, - const gr_complex *in, unsigned char *out -); - -//--------------- - -template -void viterbi_algorithm_combined<short,short>(int I, int S, int O, - const std::vector<int> &NS, - const std::vector<int> &OS, - const std::vector< std::vector<int> > &PS, - const std::vector< std::vector<int> > &PI, - int K, - int S0,int SK, - int D, - const std::vector<short> &TABLE, - gr::digital::trellis_metric_type_t TYPE, - const short *in, short *out -); - -template -void viterbi_algorithm_combined<int,short>(int I, int S, int O, - const std::vector<int> &NS, - const std::vector<int> &OS, - const std::vector< std::vector<int> > &PS, - const std::vector< std::vector<int> > &PI, - int K, - int S0,int SK, - int D, - const std::vector<int> &TABLE, - gr::digital::trellis_metric_type_t TYPE, - const int *in, short *out -); - -template -void viterbi_algorithm_combined<float,short>(int I, int S, int O, - const std::vector<int> &NS, - const std::vector<int> &OS, - const std::vector< std::vector<int> > &PS, - const std::vector< std::vector<int> > &PI, - int K, - int S0,int SK, - int D, - const std::vector<float> &TABLE, - gr::digital::trellis_metric_type_t TYPE, - const float *in, short *out -); - -template -void viterbi_algorithm_combined<gr_complex,short>(int I, int S, int O, - const std::vector<int> &NS, - const std::vector<int> &OS, - const std::vector< std::vector<int> > &PS, - const std::vector< std::vector<int> > &PI, - int K, - int S0,int SK, - int D, - const std::vector<gr_complex> &TABLE, - gr::digital::trellis_metric_type_t TYPE, - const gr_complex *in, short *out -); - -//-------------- - -template -void viterbi_algorithm_combined<short,int>(int I, int S, int O, - const std::vector<int> &NS, - const std::vector<int> &OS, - const std::vector< std::vector<int> > &PS, - const std::vector< std::vector<int> > &PI, - int K, - int S0,int SK, - int D, - const std::vector<short> &TABLE, - gr::digital::trellis_metric_type_t TYPE, - const short *in, int *out -); - -template -void viterbi_algorithm_combined<int,int>(int I, int S, int O, - const std::vector<int> &NS, - const std::vector<int> &OS, - const std::vector< std::vector<int> > &PS, - const std::vector< std::vector<int> > &PI, - int K, - int S0,int SK, - int D, - const std::vector<int> &TABLE, - gr::digital::trellis_metric_type_t TYPE, - const int *in, int *out -); - -template -void viterbi_algorithm_combined<float,int>(int I, int S, int O, - const std::vector<int> &NS, - const std::vector<int> &OS, - const std::vector< std::vector<int> > &PS, - const std::vector< std::vector<int> > &PI, - int K, - int S0,int SK, - int D, - const std::vector<float> &TABLE, - gr::digital::trellis_metric_type_t TYPE, - const float *in, int *out -); - -template -void viterbi_algorithm_combined<gr_complex,int>(int I, int S, int O, - const std::vector<int> &NS, - const std::vector<int> &OS, - const std::vector< std::vector<int> > &PS, - const std::vector< std::vector<int> > &PI, - int K, - int S0,int SK, - int D, - const std::vector<gr_complex> &TABLE, - gr::digital::trellis_metric_type_t TYPE, - const gr_complex *in, int *out -); - - - - - - - - - - - - - - - - - - - - -//=============================================== - - -void siso_algorithm(int I, int S, int O, - const std::vector<int> &NS, - const std::vector<int> &OS, - const std::vector< std::vector<int> > &PS, - const std::vector< std::vector<int> > &PI, - int K, - int S0,int SK, - bool POSTI, bool POSTO, - float (*p2mymin)(float,float), - const float *priori, const float *prioro, float *post//, - //std::vector<float> &alpha, - //std::vector<float> &beta - ) -{ - float norm,mm,minm; - std::vector<float> alpha(S*(K+1)); - std::vector<float> beta(S*(K+1)); - - - if(S0<0) { // initial state not specified - for(int i=0;i<S;i++) alpha[0*S+i]=0; - } - else { - for(int i=0;i<S;i++) alpha[0*S+i]=INF; - alpha[0*S+S0]=0.0; - } - - for(int k=0;k<K;k++) { // forward recursion - norm=INF; - for(int j=0;j<S;j++) { - minm=INF; - for(unsigned int i=0;i<PS[j].size();i++) { - //int i0 = j*I+i; - mm=alpha[k*S+PS[j][i]]+priori[k*I+PI[j][i]]+prioro[k*O+OS[PS[j][i]*I+PI[j][i]]]; - minm=(*p2mymin)(minm,mm); - } - alpha[(k+1)*S+j]=minm; - if(minm<norm) norm=minm; - } - for(int j=0;j<S;j++) - alpha[(k+1)*S+j]-=norm; // normalize total metrics so they do not explode - } - - if(SK<0) { // final state not specified - for(int i=0;i<S;i++) beta[K*S+i]=0; - } - else { - for(int i=0;i<S;i++) beta[K*S+i]=INF; - beta[K*S+SK]=0.0; - } - - for(int k=K-1;k>=0;k--) { // backward recursion - norm=INF; - for(int j=0;j<S;j++) { - minm=INF; - for(int i=0;i<I;i++) { - int i0 = j*I+i; - mm=beta[(k+1)*S+NS[i0]]+priori[k*I+i]+prioro[k*O+OS[i0]]; - minm=(*p2mymin)(minm,mm); - } - beta[k*S+j]=minm; - if(minm<norm) norm=minm; - } - for(int j=0;j<S;j++) - beta[k*S+j]-=norm; // normalize total metrics so they do not explode - } - - -if (POSTI && POSTO) -{ - for(int k=0;k<K;k++) { // input combining - norm=INF; - for(int i=0;i<I;i++) { - minm=INF; - for(int j=0;j<S;j++) { - mm=alpha[k*S+j]+prioro[k*O+OS[j*I+i]]+beta[(k+1)*S+NS[j*I+i]]; - minm=(*p2mymin)(minm,mm); - } - post[k*(I+O)+i]=minm; - if(minm<norm) norm=minm; - } - for(int i=0;i<I;i++) - post[k*(I+O)+i]-=norm; // normalize metrics - } - - - for(int k=0;k<K;k++) { // output combining - norm=INF; - for(int n=0;n<O;n++) { - minm=INF; - for(int j=0;j<S;j++) { - for(int i=0;i<I;i++) { - mm= (n==OS[j*I+i] ? alpha[k*S+j]+priori[k*I+i]+beta[(k+1)*S+NS[j*I+i]] : INF); - minm=(*p2mymin)(minm,mm); - } - } - post[k*(I+O)+I+n]=minm; - if(minm<norm) norm=minm; - } - for(int n=0;n<O;n++) - post[k*(I+O)+I+n]-=norm; // normalize metrics - } -} -else if(POSTI) -{ - for(int k=0;k<K;k++) { // input combining - norm=INF; - for(int i=0;i<I;i++) { - minm=INF; - for(int j=0;j<S;j++) { - mm=alpha[k*S+j]+prioro[k*O+OS[j*I+i]]+beta[(k+1)*S+NS[j*I+i]]; - minm=(*p2mymin)(minm,mm); - } - post[k*I+i]=minm; - if(minm<norm) norm=minm; - } - for(int i=0;i<I;i++) - post[k*I+i]-=norm; // normalize metrics - } -} -else if(POSTO) -{ - for(int k=0;k<K;k++) { // output combining - norm=INF; - for(int n=0;n<O;n++) { - minm=INF; - for(int j=0;j<S;j++) { - for(int i=0;i<I;i++) { - mm= (n==OS[j*I+i] ? alpha[k*S+j]+priori[k*I+i]+beta[(k+1)*S+NS[j*I+i]] : INF); - minm=(*p2mymin)(minm,mm); - } - } - post[k*O+n]=minm; - if(minm<norm) norm=minm; - } - for(int n=0;n<O;n++) - post[k*O+n]-=norm; // normalize metrics - } -} -else - throw std::runtime_error ("Not both POSTI and POSTO can be false."); - -} - - -//=========================================================== - -template <class T> -void siso_algorithm_combined(int I, int S, int O, - const std::vector<int> &NS, - const std::vector<int> &OS, - const std::vector< std::vector<int> > &PS, - const std::vector< std::vector<int> > &PI, - int K, - int S0,int SK, - bool POSTI, bool POSTO, - float (*p2mymin)(float,float), - int D, - const std::vector<T> &TABLE, - gr::digital::trellis_metric_type_t TYPE, - const float *priori, const T *observations, float *post -) -{ - float norm,mm,minm; - std::vector<float> alpha(S*(K+1)); - std::vector<float> beta(S*(K+1)); - float *prioro = new float[O*K]; - - - if(S0<0) { // initial state not specified - for(int i=0;i<S;i++) alpha[0*S+i]=0; - } - else { - for(int i=0;i<S;i++) alpha[0*S+i]=INF; - alpha[0*S+S0]=0.0; - } - - for(int k=0;k<K;k++) { // forward recursion - calc_metric(O, D, TABLE, &(observations[k*D]), &(prioro[k*O]),TYPE); // calc metrics - norm=INF; - for(int j=0;j<S;j++) { - minm=INF; - for(unsigned int i=0;i<PS[j].size();i++) { - //int i0 = j*I+i; - mm=alpha[k*S+PS[j][i]]+priori[k*I+PI[j][i]]+prioro[k*O+OS[PS[j][i]*I+PI[j][i]]]; - minm=(*p2mymin)(minm,mm); - } - alpha[(k+1)*S+j]=minm; - if(minm<norm) norm=minm; - } - for(int j=0;j<S;j++) - alpha[(k+1)*S+j]-=norm; // normalize total metrics so they do not explode - } - - if(SK<0) { // final state not specified - for(int i=0;i<S;i++) beta[K*S+i]=0; - } - else { - for(int i=0;i<S;i++) beta[K*S+i]=INF; - beta[K*S+SK]=0.0; - } - - for(int k=K-1;k>=0;k--) { // backward recursion - norm=INF; - for(int j=0;j<S;j++) { - minm=INF; - for(int i=0;i<I;i++) { - int i0 = j*I+i; - mm=beta[(k+1)*S+NS[i0]]+priori[k*I+i]+prioro[k*O+OS[i0]]; - minm=(*p2mymin)(minm,mm); - } - beta[k*S+j]=minm; - if(minm<norm) norm=minm; - } - for(int j=0;j<S;j++) - beta[k*S+j]-=norm; // normalize total metrics so they do not explode - } - - - if (POSTI && POSTO) - { - for(int k=0;k<K;k++) { // input combining - norm=INF; - for(int i=0;i<I;i++) { - minm=INF; - for(int j=0;j<S;j++) { - mm=alpha[k*S+j]+prioro[k*O+OS[j*I+i]]+beta[(k+1)*S+NS[j*I+i]]; - minm=(*p2mymin)(minm,mm); - } - post[k*(I+O)+i]=minm; - if(minm<norm) norm=minm; - } - for(int i=0;i<I;i++) - post[k*(I+O)+i]-=norm; // normalize metrics - } - - - for(int k=0;k<K;k++) { // output combining - norm=INF; - for(int n=0;n<O;n++) { - minm=INF; - for(int j=0;j<S;j++) { - for(int i=0;i<I;i++) { - mm= (n==OS[j*I+i] ? alpha[k*S+j]+priori[k*I+i]+beta[(k+1)*S+NS[j*I+i]] : INF); - minm=(*p2mymin)(minm,mm); - } - } - post[k*(I+O)+I+n]=minm; - if(minm<norm) norm=minm; - } - for(int n=0;n<O;n++) - post[k*(I+O)+I+n]-=norm; // normalize metrics - } - } - else if(POSTI) - { - for(int k=0;k<K;k++) { // input combining - norm=INF; - for(int i=0;i<I;i++) { - minm=INF; - for(int j=0;j<S;j++) { - mm=alpha[k*S+j]+prioro[k*O+OS[j*I+i]]+beta[(k+1)*S+NS[j*I+i]]; - minm=(*p2mymin)(minm,mm); - } - post[k*I+i]=minm; - if(minm<norm) norm=minm; - } - for(int i=0;i<I;i++) - post[k*I+i]-=norm; // normalize metrics - } - } - else if(POSTO) - { - for(int k=0;k<K;k++) { // output combining - norm=INF; - for(int n=0;n<O;n++) { - minm=INF; - for(int j=0;j<S;j++) { - for(int i=0;i<I;i++) { - mm= (n==OS[j*I+i] ? alpha[k*S+j]+priori[k*I+i]+beta[(k+1)*S+NS[j*I+i]] : INF); - minm=(*p2mymin)(minm,mm); - } - } - post[k*O+n]=minm; - if(minm<norm) norm=minm; - } - for(int n=0;n<O;n++) - post[k*O+n]-=norm; // normalize metrics - } - } - else - throw std::runtime_error ("Not both POSTI and POSTO can be false."); - - delete [] prioro; - -} - -//--------- - -template -void siso_algorithm_combined<short>(int I, int S, int O, - const std::vector<int> &NS, - const std::vector<int> &OS, - const std::vector< std::vector<int> > &PS, - const std::vector< std::vector<int> > &PI, - int K, - int S0,int SK, - bool POSTI, bool POSTO, - float (*p2mymin)(float,float), - int D, - const std::vector<short> &TABLE, - gr::digital::trellis_metric_type_t TYPE, - const float *priori, const short *observations, float *post -); - -template -void siso_algorithm_combined<int>(int I, int S, int O, - const std::vector<int> &NS, - const std::vector<int> &OS, - const std::vector< std::vector<int> > &PS, - const std::vector< std::vector<int> > &PI, - int K, - int S0,int SK, - bool POSTI, bool POSTO, - float (*p2mymin)(float,float), - int D, - const std::vector<int> &TABLE, - gr::digital::trellis_metric_type_t TYPE, - const float *priori, const int *observations, float *post -); - -template -void siso_algorithm_combined<float>(int I, int S, int O, - const std::vector<int> &NS, - const std::vector<int> &OS, - const std::vector< std::vector<int> > &PS, - const std::vector< std::vector<int> > &PI, - int K, - int S0,int SK, - bool POSTI, bool POSTO, - float (*p2mymin)(float,float), - int D, - const std::vector<float> &TABLE, - gr::digital::trellis_metric_type_t TYPE, - const float *priori, const float *observations, float *post -); - -template -void siso_algorithm_combined<gr_complex>(int I, int S, int O, - const std::vector<int> &NS, - const std::vector<int> &OS, - const std::vector< std::vector<int> > &PS, - const std::vector< std::vector<int> > &PI, - int K, - int S0,int SK, - bool POSTI, bool POSTO, - float (*p2mymin)(float,float), - int D, - const std::vector<gr_complex> &TABLE, - gr::digital::trellis_metric_type_t TYPE, - const float *priori, const gr_complex *observations, float *post -); - -//========================================================= - -template<class Ti, class To> -void sccc_decoder_combined( - const fsm &FSMo, int STo0, int SToK, - const fsm &FSMi, int STi0, int STiK, - const interleaver &INTERLEAVER, int blocklength, int iterations, - float (*p2mymin)(float,float), - int D, const std::vector<Ti> &TABLE, - gr::digital::trellis_metric_type_t METRIC_TYPE, - float scaling, - const Ti *observations, To *data -) -{ - -//allocate space for priori, prioro and posti of inner FSM -std::vector<float> ipriori(blocklength*FSMi.I(),0.0); -std::vector<float> iprioro(blocklength*FSMi.O()); -std::vector<float> iposti(blocklength*FSMi.I()); - -//allocate space for priori, prioro and posto of outer FSM -std::vector<float> opriori(blocklength*FSMo.I(),0.0); -std::vector<float> oprioro(blocklength*FSMo.O()); -std::vector<float> oposti(blocklength*FSMo.I()); -std::vector<float> oposto(blocklength*FSMo.O()); - -// turn observations to neg-log-priors -for(int k=0;k<blocklength;k++) { - calc_metric(FSMi.O(), D, TABLE, &(observations[k*D]), &(iprioro[k*FSMi.O()]),METRIC_TYPE); - iprioro[k*FSMi.O()] *= scaling; -} - -for(int rep=0;rep<iterations;rep++) { - // run inner SISO - siso_algorithm(FSMi.I(),FSMi.S(),FSMi.O(), - FSMi.NS(), FSMi.OS(), FSMi.PS(), FSMi.PI(), - blocklength, - STi0,STiK, - true, false, - p2mymin, - &(ipriori[0]), &(iprioro[0]), &(iposti[0]) - ); - - //interleave soft info inner -> outer - for(int k=0;k<blocklength;k++) { - int ki = INTERLEAVER.DEINTER()[k]; - //for(int i=0;i<FSMi.I();i++) { - //oprioro[k*FSMi.I()+i]=iposti[ki*FSMi.I()+i]; - //} - memcpy(&(oprioro[k*FSMi.I()]),&(iposti[ki*FSMi.I()]),FSMi.I()*sizeof(float)); - } - - // run outer SISO - - if(rep<iterations-1) { // do not produce posti - siso_algorithm(FSMo.I(),FSMo.S(),FSMo.O(), - FSMo.NS(), FSMo.OS(), FSMo.PS(), FSMo.PI(), - blocklength, - STo0,SToK, - false, true, - p2mymin, - &(opriori[0]), &(oprioro[0]), &(oposto[0]) - ); - - //interleave soft info outer --> inner - for(int k=0;k<blocklength;k++) { - int ki = INTERLEAVER.DEINTER()[k]; - //for(int i=0;i<FSMi.I();i++) { - //ipriori[ki*FSMi.I()+i]=oposto[k*FSMi.I()+i]; - //} - memcpy(&(ipriori[ki*FSMi.I()]),&(oposto[k*FSMi.I()]),FSMi.I()*sizeof(float)); - } - } - else // produce posti but not posto - - siso_algorithm(FSMo.I(),FSMo.S(),FSMo.O(), - FSMo.NS(), FSMo.OS(), FSMo.PS(), FSMo.PI(), - blocklength, - STo0,SToK, - true, false, - p2mymin, - &(opriori[0]), &(oprioro[0]), &(oposti[0]) - ); - - /* - viterbi_algorithm(FSMo.I(),FSMo.S(),FSMo.O(), - FSMo.NS(), FSMo.OS(), FSMo.PS(), FSMo.PI(), - blocklength, - STo0,SToK, - &(oprioro[0]), data - ); - */ - -} - - -// generate hard decisions -for(int k=0;k<blocklength;k++) { - float min=INF; - int mini=0; - for(int i=0;i<FSMo.I();i++) { - if(oposti[k*FSMo.I()+i]<min) { - min=oposti[k*FSMo.I()+i]; - mini=i; - } - } - data[k]=(To)mini; -} - - - -} - -//------- - -template -void sccc_decoder_combined<float,unsigned char>( - const fsm &FSMo, int STo0, int SToK, - const fsm &FSMi, int STi0, int STiK, - const interleaver &INTERLEAVER, int blocklength, int iterations, - float (*p2mymin)(float,float), - int D, const std::vector<float> &TABLE, - gr::digital::trellis_metric_type_t METRIC_TYPE, - float scaling, - const float *observations, unsigned char *data -); - -template -void sccc_decoder_combined<float,short>( - const fsm &FSMo, int STo0, int SToK, - const fsm &FSMi, int STi0, int STiK, - const interleaver &INTERLEAVER, int blocklength, int iterations, - float (*p2mymin)(float,float), - int D, const std::vector<float> &TABLE, - gr::digital::trellis_metric_type_t METRIC_TYPE, - float scaling, - const float *observations, short *data -); - -template -void sccc_decoder_combined<float,int>( - const fsm &FSMo, int STo0, int SToK, - const fsm &FSMi, int STi0, int STiK, - const interleaver &INTERLEAVER, int blocklength, int iterations, - float (*p2mymin)(float,float), - int D, const std::vector<float> &TABLE, - gr::digital::trellis_metric_type_t METRIC_TYPE, - float scaling, - const float *observations, int *data -); - -template -void sccc_decoder_combined<gr_complex,unsigned char>( - const fsm &FSMo, int STo0, int SToK, - const fsm &FSMi, int STi0, int STiK, - const interleaver &INTERLEAVER, int blocklength, int iterations, - float (*p2mymin)(float,float), - int D, const std::vector<gr_complex> &TABLE, - gr::digital::trellis_metric_type_t METRIC_TYPE, - float scaling, - const gr_complex *observations, unsigned char *data -); - -template -void sccc_decoder_combined<gr_complex,short>( - const fsm &FSMo, int STo0, int SToK, - const fsm &FSMi, int STi0, int STiK, - const interleaver &INTERLEAVER, int blocklength, int iterations, - float (*p2mymin)(float,float), - int D, const std::vector<gr_complex> &TABLE, - gr::digital::trellis_metric_type_t METRIC_TYPE, - float scaling, - const gr_complex *observations, short *data -); - -template -void sccc_decoder_combined<gr_complex,int>( - const fsm &FSMo, int STo0, int SToK, - const fsm &FSMi, int STi0, int STiK, - const interleaver &INTERLEAVER, int blocklength, int iterations, - float (*p2mymin)(float,float), - int D, const std::vector<gr_complex> &TABLE, - gr::digital::trellis_metric_type_t METRIC_TYPE, - float scaling, - const gr_complex *observations, int *data -); - - - -//========================================================= - -template<class T> -void sccc_decoder( - const fsm &FSMo, int STo0, int SToK, - const fsm &FSMi, int STi0, int STiK, - const interleaver &INTERLEAVER, int blocklength, int iterations, - float (*p2mymin)(float,float), - const float *iprioro, T *data -) -{ - //allocate space for priori, and posti of inner FSM - std::vector<float> ipriori(blocklength*FSMi.I(),0.0); - std::vector<float> iposti(blocklength*FSMi.I()); - - //allocate space for priori, prioro and posto of outer FSM - std::vector<float> opriori(blocklength*FSMo.I(),0.0); - std::vector<float> oprioro(blocklength*FSMo.O()); - std::vector<float> oposti(blocklength*FSMo.I()); - std::vector<float> oposto(blocklength*FSMo.O()); - - for(int rep=0;rep<iterations;rep++) { - // run inner SISO - siso_algorithm(FSMi.I(),FSMi.S(),FSMi.O(), - FSMi.NS(), FSMi.OS(), FSMi.PS(), FSMi.PI(), - blocklength, - STi0,STiK, - true, false, - p2mymin, - &(ipriori[0]), &(iprioro[0]), &(iposti[0]) - ); - - //interleave soft info inner -> outer - for(int k=0;k<blocklength;k++) { - int ki = INTERLEAVER.DEINTER()[k]; - //for(int i=0;i<FSMi.I();i++) { - //oprioro[k*FSMi.I()+i]=iposti[ki*FSMi.I()+i]; - //} - memcpy(&(oprioro[k*FSMi.I()]),&(iposti[ki*FSMi.I()]),FSMi.I()*sizeof(float)); - } - - // run outer SISO - - if(rep<iterations-1) { // do not produce posti - siso_algorithm(FSMo.I(),FSMo.S(),FSMo.O(), - FSMo.NS(), FSMo.OS(), FSMo.PS(), FSMo.PI(), - blocklength, - STo0,SToK, - false, true, - p2mymin, - &(opriori[0]), &(oprioro[0]), &(oposto[0]) - ); - - //interleave soft info outer --> inner - for(int k=0;k<blocklength;k++) { - int ki = INTERLEAVER.DEINTER()[k]; - //for(int i=0;i<FSMi.I();i++) { - //ipriori[ki*FSMi.I()+i]=oposto[k*FSMi.I()+i]; - //} - memcpy(&(ipriori[ki*FSMi.I()]),&(oposto[k*FSMi.I()]),FSMi.I()*sizeof(float)); - } - } - else {// produce posti but not posto - - siso_algorithm(FSMo.I(),FSMo.S(),FSMo.O(), - FSMo.NS(), FSMo.OS(), FSMo.PS(), FSMo.PI(), - blocklength, - STo0,SToK, - true, false, - p2mymin, - &(opriori[0]), &(oprioro[0]), &(oposti[0]) - ); - - /* - viterbi_algorithm(FSMo.I(),FSMo.S(),FSMo.O(), - FSMo.NS(), FSMo.OS(), FSMo.PS(), FSMo.PI(), - blocklength, - STo0,SToK, - &(oprioro[0]), data - ); - */ - } - - } // end iterations - - // generate hard decisions - for(int k=0;k<blocklength;k++) { - float min=INF; - int mini=0; - for(int i=0;i<FSMo.I();i++) { - if(oposti[k*FSMo.I()+i]<min) { - min=oposti[k*FSMo.I()+i]; - mini=i; - } - } - data[k]=(T)mini; - } - - - -} - -//------- - -template -void sccc_decoder<unsigned char>( - const fsm &FSMo, int STo0, int SToK, - const fsm &FSMi, int STi0, int STiK, - const interleaver &INTERLEAVER, int blocklength, int iterations, - float (*p2mymin)(float,float), - const float *iprioro, unsigned char *data -); - -template -void sccc_decoder<short>( - const fsm &FSMo, int STo0, int SToK, - const fsm &FSMi, int STi0, int STiK, - const interleaver &INTERLEAVER, int blocklength, int iterations, - float (*p2mymin)(float,float), - const float *iprioro, short *data -); - -template -void sccc_decoder<int>( - const fsm &FSMo, int STo0, int SToK, - const fsm &FSMi, int STi0, int STiK, - const interleaver &INTERLEAVER, int blocklength, int iterations, - float (*p2mymin)(float,float), - const float *iprioro, int *data -); - - -//==================================================== - -template<class T> -void pccc_decoder( - const fsm &FSM1, int ST10, int ST1K, - const fsm &FSM2, int ST20, int ST2K, - const interleaver &INTERLEAVER, int blocklength, int iterations, - float (*p2mymin)(float,float), - const float *cprioro, T *data -) -{ - - //allocate space for priori, prioro and posti of FSM1 - std::vector<float> priori1(blocklength*FSM1.I(),0.0); - std::vector<float> prioro1(blocklength*FSM1.O()); - std::vector<float> posti1(blocklength*FSM1.I()); - - //allocate space for priori, prioro and posti of FSM2 - std::vector<float> priori2(blocklength*FSM2.I(),0.0); - std::vector<float> prioro2(blocklength*FSM2.O()); - std::vector<float> posti2(blocklength*FSM2.I()); - - //generate prioro1,2 (metrics are not updated per iteration: this is not the best you can do...) - for (int k=0;k<blocklength;k++) { - //std::cout << k << std::endl; - for(int i=0;i<FSM1.O();i++) { - float x=cprioro[k*FSM1.O()*FSM2.O()+i*FSM1.O()+0]; - for(int j=1;j<FSM2.O();j++) - x = (*p2mymin)(x,cprioro[k*FSM1.O()*FSM2.O()+i*FSM1.O()+j]); - prioro1[k*FSM1.O()+i]=x; - //std::cout << prioro1[k*FSM1.O()+i] << ", "; - } - //std::cout << std::endl; - for(int i=0;i<FSM2.O();i++) { - float x=cprioro[k*FSM1.O()*FSM2.O()+0*FSM1.O()+i]; - for(int j=1;j<FSM1.O();j++) - x = (*p2mymin)(x,cprioro[k*FSM1.O()*FSM2.O()+j*FSM1.O()+i]); - prioro2[k*FSM2.O()+i]=x; - } - } - - for(int rep=0;rep<iterations;rep++) { - // run SISO 1 - siso_algorithm(FSM1.I(),FSM1.S(),FSM1.O(), - FSM1.NS(), FSM1.OS(), FSM1.PS(), FSM1.PI(), - blocklength, - ST10,ST1K, - true, false, - p2mymin, - &(priori1[0]), &(prioro1[0]), &(posti1[0]) - ); - - //for(int k=0;k<blocklength;k++){ - //for(int i=0;i<FSM1.I();i++) - //std::cout << posti1[k*FSM1.I()+i] << ", "; - //std::cout << std::endl; - //} - - //interleave soft info 1 -> 2 - for(int k=0;k<blocklength;k++) { - int ki = INTERLEAVER.INTER()[k]; - //for(int i=0;i<FSMi.I();i++) { - //oprioro[k*FSMi.I()+i]=iposti[ki*FSMi.I()+i]; - //} - memcpy(&(priori2[k*FSM2.I()]),&(posti1[ki*FSM1.I()]),FSM1.I()*sizeof(float)); - } - - // run SISO 2 - siso_algorithm(FSM2.I(),FSM2.S(),FSM2.O(), - FSM2.NS(), FSM2.OS(), FSM2.PS(), FSM2.PI(), - blocklength, - ST20,ST2K, - true, false, - p2mymin, - &(priori2[0]), &(prioro2[0]), &(posti2[0]) - ); - - //interleave soft info 2 --> 1 - for(int k=0;k<blocklength;k++) { - int ki = INTERLEAVER.INTER()[k]; - //for(int i=0;i<FSMi.I();i++) { - //ipriori[ki*FSMi.I()+i]=oposto[k*FSMi.I()+i]; - //} - memcpy(&(priori1[ki*FSM1.I()]),&(posti2[k*FSM2.I()]),FSM1.I()*sizeof(float)); - } - - } // end iterations - - // generate hard decisions - for(int k=0;k<blocklength;k++) { - for(int i=0;i<FSM1.I();i++) - posti1[k*FSM1.I()+i] = (*p2mymin)(priori1[k*FSM1.I()+i],posti1[k*FSM1.I()+i]); - float min=INF; - int mini=0; - for(int i=0;i<FSM1.I();i++) { - if(posti1[k*FSM1.I()+i]<min) { - min=posti1[k*FSM1.I()+i]; - mini=i; - } - } - data[k]=(T)mini; - //std::cout << data[k] << ", "<< std::endl; - } - //std::cout << std::endl; - -} - -//---------------- - -template -void pccc_decoder<unsigned char>( - const fsm &FSM1, int ST10, int ST1K, - const fsm &FSM2, int ST20, int ST2K, - const interleaver &INTERLEAVER, int blocklength, int iterations, - float (*p2mymin)(float,float), - const float *cprioro, unsigned char *data -); - -template -void pccc_decoder<short>( - const fsm &FSM1, int ST10, int ST1K, - const fsm &FSM2, int ST20, int ST2K, - const interleaver &INTERLEAVER, int blocklength, int iterations, - float (*p2mymin)(float,float), - const float *cprioro, short *data -); - -template -void pccc_decoder<int>( - const fsm &FSM1, int ST10, int ST1K, - const fsm &FSM2, int ST20, int ST2K, - const interleaver &INTERLEAVER, int blocklength, int iterations, - float (*p2mymin)(float,float), - const float *cprioro, int *data -); - - - -//---------------- - - -template<class Ti, class To> -void pccc_decoder_combined( - const fsm &FSM1, int ST10, int ST1K, - const fsm &FSM2, int ST20, int ST2K, - const interleaver &INTERLEAVER, int blocklength, int iterations, - float (*p2mymin)(float,float), - int D, const std::vector<Ti> &TABLE, - gr::digital::trellis_metric_type_t METRIC_TYPE, - float scaling, - const Ti *observations, To *data -) -{ - - //allocate space for cprioro - std::vector<float> cprioro(blocklength*FSM1.O()*FSM2.O(),0.0); - - //allocate space for priori, prioro and posti of FSM1 - std::vector<float> priori1(blocklength*FSM1.I(),0.0); - std::vector<float> prioro1(blocklength*FSM1.O()); - std::vector<float> posti1(blocklength*FSM1.I()); - - //allocate space for priori, prioro and posti of FSM2 - std::vector<float> priori2(blocklength*FSM2.I(),0.0); - std::vector<float> prioro2(blocklength*FSM2.O()); - std::vector<float> posti2(blocklength*FSM2.I()); - - // turn observations to neg-log-priors for cprioiro - int O=FSM1.O()*FSM2.O(); - for(int k=0;k<blocklength;k++) { - calc_metric(O, D, TABLE, &(observations[k*D]), &(cprioro[k*O]),METRIC_TYPE); - cprioro[k*O] *= scaling; - } - - //generate prioro1,2 (metrics are not updated per iteration: this is not the best you can do...) - for (int k=0;k<blocklength;k++) { - //std::cout << k << std::endl; - for(int i=0;i<FSM1.O();i++) { - float x=cprioro[k*FSM1.O()*FSM2.O()+i*FSM1.O()+0]; - for(int j=1;j<FSM2.O();j++) - x = (*p2mymin)(x,cprioro[k*FSM1.O()*FSM2.O()+i*FSM1.O()+j]); - prioro1[k*FSM1.O()+i]=x; - //std::cout << prioro1[k*FSM1.O()+i] << ", "; - } - //std::cout << std::endl; - for(int i=0;i<FSM2.O();i++) { - float x=cprioro[k*FSM1.O()*FSM2.O()+0*FSM1.O()+i]; - for(int j=1;j<FSM1.O();j++) - x = (*p2mymin)(x,cprioro[k*FSM1.O()*FSM2.O()+j*FSM1.O()+i]); - prioro2[k*FSM2.O()+i]=x; - } - } - - for(int rep=0;rep<iterations;rep++) { - // run SISO 1 - siso_algorithm(FSM1.I(),FSM1.S(),FSM1.O(), - FSM1.NS(), FSM1.OS(), FSM1.PS(), FSM1.PI(), - blocklength, - ST10,ST1K, - true, false, - p2mymin, - &(priori1[0]), &(prioro1[0]), &(posti1[0]) - ); - - //for(int k=0;k<blocklength;k++){ - //for(int i=0;i<FSM1.I();i++) - //std::cout << posti1[k*FSM1.I()+i] << ", "; - //std::cout << std::endl; - //} - - //interleave soft info 1 -> 2 - for(int k=0;k<blocklength;k++) { - int ki = INTERLEAVER.INTER()[k]; - //for(int i=0;i<FSMi.I();i++) { - //oprioro[k*FSMi.I()+i]=iposti[ki*FSMi.I()+i]; - //} - memcpy(&(priori2[k*FSM2.I()]),&(posti1[ki*FSM1.I()]),FSM1.I()*sizeof(float)); - } - - // run SISO 2 - siso_algorithm(FSM2.I(),FSM2.S(),FSM2.O(), - FSM2.NS(), FSM2.OS(), FSM2.PS(), FSM2.PI(), - blocklength, - ST20,ST2K, - true, false, - p2mymin, - &(priori2[0]), &(prioro2[0]), &(posti2[0]) - ); - - //interleave soft info 2 --> 1 - for(int k=0;k<blocklength;k++) { - int ki = INTERLEAVER.INTER()[k]; - //for(int i=0;i<FSMi.I();i++) { - //ipriori[ki*FSMi.I()+i]=oposto[k*FSMi.I()+i]; - //} - memcpy(&(priori1[ki*FSM1.I()]),&(posti2[k*FSM2.I()]),FSM1.I()*sizeof(float)); - } - - } // end iterations - - // generate hard decisions - for(int k=0;k<blocklength;k++) { - for(int i=0;i<FSM1.I();i++) - posti1[k*FSM1.I()+i] = (*p2mymin)(priori1[k*FSM1.I()+i],posti1[k*FSM1.I()+i]); - float min=INF; - int mini=0; - for(int i=0;i<FSM1.I();i++) { - if(posti1[k*FSM1.I()+i]<min) { - min=posti1[k*FSM1.I()+i]; - mini=i; - } - } - data[k]=(To)mini; - //std::cout << data[k] << ", "<< std::endl; - } - //std::cout << std::endl; - -} - - -template -void pccc_decoder_combined( - const fsm &FSM1, int ST10, int ST1K, - const fsm &FSM2, int ST20, int ST2K, - const interleaver &INTERLEAVER, int blocklength, int iterations, - float (*p2mymin)(float,float), - int D, const std::vector<float> &TABLE, - gr::digital::trellis_metric_type_t METRIC_TYPE, - float scaling, - const float *observations, unsigned char *data -); - - -template -void pccc_decoder_combined( - const fsm &FSM1, int ST10, int ST1K, - const fsm &FSM2, int ST20, int ST2K, - const interleaver &INTERLEAVER, int blocklength, int iterations, - float (*p2mymin)(float,float), - int D, const std::vector<float> &TABLE, - gr::digital::trellis_metric_type_t METRIC_TYPE, - float scaling, - const float *observations, short *data -); - - -template -void pccc_decoder_combined( - const fsm &FSM1, int ST10, int ST1K, - const fsm &FSM2, int ST20, int ST2K, - const interleaver &INTERLEAVER, int blocklength, int iterations, - float (*p2mymin)(float,float), - int D, const std::vector<float> &TABLE, - gr::digital::trellis_metric_type_t METRIC_TYPE, - float scaling, - const float *observations, int *data -); - - -template -void pccc_decoder_combined( - const fsm &FSM1, int ST10, int ST1K, - const fsm &FSM2, int ST20, int ST2K, - const interleaver &INTERLEAVER, int blocklength, int iterations, - float (*p2mymin)(float,float), - int D, const std::vector<gr_complex> &TABLE, - gr::digital::trellis_metric_type_t METRIC_TYPE, - float scaling, - const gr_complex *observations, unsigned char *data -); - - -template -void pccc_decoder_combined( - const fsm &FSM1, int ST10, int ST1K, - const fsm &FSM2, int ST20, int ST2K, - const interleaver &INTERLEAVER, int blocklength, int iterations, - float (*p2mymin)(float,float), - int D, const std::vector<gr_complex> &TABLE, - gr::digital::trellis_metric_type_t METRIC_TYPE, - float scaling, - const gr_complex *observations, short *data -); - - -template -void pccc_decoder_combined( - const fsm &FSM1, int ST10, int ST1K, - const fsm &FSM2, int ST20, int ST2K, - const interleaver &INTERLEAVER, int blocklength, int iterations, - float (*p2mymin)(float,float), - int D, const std::vector<gr_complex> &TABLE, - gr::digital::trellis_metric_type_t METRIC_TYPE, - float scaling, - const gr_complex *observations, int *data -); |