/* -*- 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 #include //#include #include #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 void viterbi_algorithm(int I, int S, int O, const std::vector &NS, const std::vector &OS, const std::vector< std::vector > &PS, const std::vector< std::vector > &PI, int K, int S0,int SK, const float *in, T *out)//, //std::vector &trace) { std::vector trace(S*K); std::vector 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=0;k--) { // traceback int i0=trace[k*S+st]; out[k]= (T) PI[st][i0]; st=PS[st][i0]; } } template void viterbi_algorithm(int I, int S, int O, const std::vector &NS, const std::vector &OS, const std::vector< std::vector > &PS, const std::vector< std::vector > &PI, int K, int S0,int SK, const float *in, unsigned char *out); template void viterbi_algorithm(int I, int S, int O, const std::vector &NS, const std::vector &OS, const std::vector< std::vector > &PS, const std::vector< std::vector > &PI, int K, int S0,int SK, const float *in, short *out); template void viterbi_algorithm(int I, int S, int O, const std::vector &NS, const std::vector &OS, const std::vector< std::vector > &PS, const std::vector< std::vector > &PI, int K, int S0,int SK, const float *in, int *out); //============================================== template void viterbi_algorithm_combined(int I, int S, int O, const std::vector &NS, const std::vector &OS, const std::vector< std::vector > &PS, const std::vector< std::vector > &PI, int K, int S0,int SK, int D, const std::vector &TABLE, trellis_metric_type_t TYPE, const Ti *in, To *out ) { std::vector trace(S*K); std::vector 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=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(int I, int S, int O, const std::vector &NS, const std::vector &OS, const std::vector< std::vector > &PS, const std::vector< std::vector > &PI, int K, int S0,int SK, int D, const std::vector &TABLE, trellis_metric_type_t TYPE, const short *in, unsigned char *out ); template void viterbi_algorithm_combined(int I, int S, int O, const std::vector &NS, const std::vector &OS, const std::vector< std::vector > &PS, const std::vector< std::vector > &PI, int K, int S0,int SK, int D, const std::vector &TABLE, trellis_metric_type_t TYPE, const int *in, unsigned char *out ); template void viterbi_algorithm_combined(int I, int S, int O, const std::vector &NS, const std::vector &OS, const std::vector< std::vector > &PS, const std::vector< std::vector > &PI, int K, int S0,int SK, int D, const std::vector &TABLE, trellis_metric_type_t TYPE, const float *in, unsigned char *out ); template void viterbi_algorithm_combined(int I, int S, int O, const std::vector &NS, const std::vector &OS, const std::vector< std::vector > &PS, const std::vector< std::vector > &PI, int K, int S0,int SK, int D, const std::vector &TABLE, trellis_metric_type_t TYPE, const gr_complex *in, unsigned char *out ); //--------------- template void viterbi_algorithm_combined(int I, int S, int O, const std::vector &NS, const std::vector &OS, const std::vector< std::vector > &PS, const std::vector< std::vector > &PI, int K, int S0,int SK, int D, const std::vector &TABLE, trellis_metric_type_t TYPE, const short *in, short *out ); template void viterbi_algorithm_combined(int I, int S, int O, const std::vector &NS, const std::vector &OS, const std::vector< std::vector > &PS, const std::vector< std::vector > &PI, int K, int S0,int SK, int D, const std::vector &TABLE, trellis_metric_type_t TYPE, const int *in, short *out ); template void viterbi_algorithm_combined(int I, int S, int O, const std::vector &NS, const std::vector &OS, const std::vector< std::vector > &PS, const std::vector< std::vector > &PI, int K, int S0,int SK, int D, const std::vector &TABLE, trellis_metric_type_t TYPE, const float *in, short *out ); template void viterbi_algorithm_combined(int I, int S, int O, const std::vector &NS, const std::vector &OS, const std::vector< std::vector > &PS, const std::vector< std::vector > &PI, int K, int S0,int SK, int D, const std::vector &TABLE, trellis_metric_type_t TYPE, const gr_complex *in, short *out ); //-------------- template void viterbi_algorithm_combined(int I, int S, int O, const std::vector &NS, const std::vector &OS, const std::vector< std::vector > &PS, const std::vector< std::vector > &PI, int K, int S0,int SK, int D, const std::vector &TABLE, trellis_metric_type_t TYPE, const short *in, int *out ); template void viterbi_algorithm_combined(int I, int S, int O, const std::vector &NS, const std::vector &OS, const std::vector< std::vector > &PS, const std::vector< std::vector > &PI, int K, int S0,int SK, int D, const std::vector &TABLE, trellis_metric_type_t TYPE, const int *in, int *out ); template void viterbi_algorithm_combined(int I, int S, int O, const std::vector &NS, const std::vector &OS, const std::vector< std::vector > &PS, const std::vector< std::vector > &PI, int K, int S0,int SK, int D, const std::vector &TABLE, trellis_metric_type_t TYPE, const float *in, int *out ); template void viterbi_algorithm_combined(int I, int S, int O, const std::vector &NS, const std::vector &OS, const std::vector< std::vector > &PS, const std::vector< std::vector > &PI, int K, int S0,int SK, int D, const std::vector &TABLE, trellis_metric_type_t TYPE, const gr_complex *in, int *out ); //=============================================== void siso_algorithm(int I, int S, int O, const std::vector &NS, const std::vector &OS, const std::vector< std::vector > &PS, const std::vector< std::vector > &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 &alpha, //std::vector &beta ) { float norm,mm,minm; std::vector alpha(S*(K+1)); std::vector beta(S*(K+1)); if(S0<0) { // initial state not specified for(int i=0;i=0;k--) { // backward recursion norm=INF; for(int j=0;j void siso_algorithm_combined(int I, int S, int O, const std::vector &NS, const std::vector &OS, const std::vector< std::vector > &PS, const std::vector< std::vector > &PI, int K, int S0,int SK, bool POSTI, bool POSTO, float (*p2mymin)(float,float), int D, const std::vector &TABLE, trellis_metric_type_t TYPE, const float *priori, const T *observations, float *post ) { float norm,mm,minm; std::vector alpha(S*(K+1)); std::vector beta(S*(K+1)); float *prioro = new float[O*K]; if(S0<0) { // initial state not specified for(int i=0;i=0;k--) { // backward recursion norm=INF; for(int j=0;j(int I, int S, int O, const std::vector &NS, const std::vector &OS, const std::vector< std::vector > &PS, const std::vector< std::vector > &PI, int K, int S0,int SK, bool POSTI, bool POSTO, float (*p2mymin)(float,float), int D, const std::vector &TABLE, trellis_metric_type_t TYPE, const float *priori, const short *observations, float *post ); template void siso_algorithm_combined(int I, int S, int O, const std::vector &NS, const std::vector &OS, const std::vector< std::vector > &PS, const std::vector< std::vector > &PI, int K, int S0,int SK, bool POSTI, bool POSTO, float (*p2mymin)(float,float), int D, const std::vector &TABLE, trellis_metric_type_t TYPE, const float *priori, const int *observations, float *post ); template void siso_algorithm_combined(int I, int S, int O, const std::vector &NS, const std::vector &OS, const std::vector< std::vector > &PS, const std::vector< std::vector > &PI, int K, int S0,int SK, bool POSTI, bool POSTO, float (*p2mymin)(float,float), int D, const std::vector &TABLE, trellis_metric_type_t TYPE, const float *priori, const float *observations, float *post ); template void siso_algorithm_combined(int I, int S, int O, const std::vector &NS, const std::vector &OS, const std::vector< std::vector > &PS, const std::vector< std::vector > &PI, int K, int S0,int SK, bool POSTI, bool POSTO, float (*p2mymin)(float,float), int D, const std::vector &TABLE, trellis_metric_type_t TYPE, const float *priori, const gr_complex *observations, float *post ); //========================================================= template 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 &TABLE, 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 ipriori(blocklength*FSMi.I(),0.0); std::vector iprioro(blocklength*FSMi.O()); std::vector iposti(blocklength*FSMi.I()); //allocate space for priori, prioro and posto of outer FSM std::vector opriori(blocklength*FSMo.I(),0.0); std::vector oprioro(blocklength*FSMo.O()); std::vector oposti(blocklength*FSMo.I()); std::vector oposto(blocklength*FSMo.O()); // turn observations to neg-log-priors for(int k=0;k outer for(int k=0;k inner for(int k=0;k( 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 &TABLE, trellis_metric_type_t METRIC_TYPE, float scaling, const float *observations, unsigned char *data ); template 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 &TABLE, trellis_metric_type_t METRIC_TYPE, float scaling, const float *observations, short *data ); template 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 &TABLE, trellis_metric_type_t METRIC_TYPE, float scaling, const float *observations, int *data ); template 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 &TABLE, trellis_metric_type_t METRIC_TYPE, float scaling, const gr_complex *observations, unsigned char *data ); template 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 &TABLE, trellis_metric_type_t METRIC_TYPE, float scaling, const gr_complex *observations, short *data ); template 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 &TABLE, trellis_metric_type_t METRIC_TYPE, float scaling, const gr_complex *observations, int *data ); //========================================================= template 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 ipriori(blocklength*FSMi.I(),0.0); std::vector iposti(blocklength*FSMi.I()); //allocate space for priori, prioro and posto of outer FSM std::vector opriori(blocklength*FSMo.I(),0.0); std::vector oprioro(blocklength*FSMo.O()); std::vector oposti(blocklength*FSMo.I()); std::vector oposto(blocklength*FSMo.O()); for(int rep=0;rep outer for(int k=0;k inner for(int k=0;k( 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( 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( 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 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 priori1(blocklength*FSM1.I(),0.0); std::vector prioro1(blocklength*FSM1.O()); std::vector posti1(blocklength*FSM1.I()); //allocate space for priori, prioro and posti of FSM2 std::vector priori2(blocklength*FSM2.I(),0.0); std::vector prioro2(blocklength*FSM2.O()); std::vector 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 2 for(int k=0;k 1 for(int k=0;k( 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( 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( 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 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 &TABLE, trellis_metric_type_t METRIC_TYPE, float scaling, const Ti *observations, To *data ) { //allocate space for cprioro std::vector cprioro(blocklength*FSM1.O()*FSM2.O(),0.0); //allocate space for priori, prioro and posti of FSM1 std::vector priori1(blocklength*FSM1.I(),0.0); std::vector prioro1(blocklength*FSM1.O()); std::vector posti1(blocklength*FSM1.I()); //allocate space for priori, prioro and posti of FSM2 std::vector priori2(blocklength*FSM2.I(),0.0); std::vector prioro2(blocklength*FSM2.O()); std::vector posti2(blocklength*FSM2.I()); // turn observations to neg-log-priors for cprioiro int O=FSM1.O()*FSM2.O(); for(int k=0;k 2 for(int k=0;k 1 for(int k=0;k &TABLE, 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 &TABLE, 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 &TABLE, 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 &TABLE, 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 &TABLE, 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 &TABLE, trellis_metric_type_t METRIC_TYPE, float scaling, const gr_complex *observations, int *data );