summaryrefslogtreecommitdiff
path: root/gr-trellis/lib
diff options
context:
space:
mode:
Diffstat (limited to 'gr-trellis/lib')
-rw-r--r--gr-trellis/lib/base.cc94
-rw-r--r--gr-trellis/lib/calc_metric.cc440
-rw-r--r--gr-trellis/lib/constellation_metrics_cf_impl.cc100
-rw-r--r--gr-trellis/lib/constellation_metrics_cf_impl.h49
-rw-r--r--gr-trellis/lib/core_algorithms.cc3001
-rw-r--r--gr-trellis/lib/encoder_impl.cc153
-rw-r--r--gr-trellis/lib/encoder_impl.h56
-rw-r--r--gr-trellis/lib/fsm.cc1037
-rw-r--r--gr-trellis/lib/interleaver.cc233
-rw-r--r--gr-trellis/lib/metrics_impl.cc185
-rw-r--r--gr-trellis/lib/metrics_impl.h59
-rw-r--r--gr-trellis/lib/pccc_decoder_blk_impl.cc165
-rw-r--r--gr-trellis/lib/pccc_decoder_blk_impl.h87
-rw-r--r--gr-trellis/lib/pccc_decoder_combined_blk_impl.cc221
-rw-r--r--gr-trellis/lib/pccc_decoder_combined_blk_impl.h113
-rw-r--r--gr-trellis/lib/pccc_encoder_impl.cc119
-rw-r--r--gr-trellis/lib/pccc_encoder_impl.h60
-rw-r--r--gr-trellis/lib/permutation_impl.cc135
-rw-r--r--gr-trellis/lib/permutation_impl.h62
-rw-r--r--gr-trellis/lib/quicksort_index.cc76
-rw-r--r--gr-trellis/lib/sccc_decoder_blk_impl.cc162
-rw-r--r--gr-trellis/lib/sccc_decoder_blk_impl.h87
-rw-r--r--gr-trellis/lib/sccc_decoder_combined_blk_impl.cc237
-rw-r--r--gr-trellis/lib/sccc_decoder_combined_blk_impl.h113
-rw-r--r--gr-trellis/lib/sccc_encoder_impl.cc119
-rw-r--r--gr-trellis/lib/sccc_encoder_impl.h60
-rw-r--r--gr-trellis/lib/siso_combined_f_impl.cc406
-rw-r--r--gr-trellis/lib/siso_combined_f_impl.h109
-rw-r--r--gr-trellis/lib/siso_f_impl.cc361
-rw-r--r--gr-trellis/lib/siso_f_impl.h86
-rw-r--r--gr-trellis/lib/viterbi_combined_impl.cc297
-rw-r--r--gr-trellis/lib/viterbi_combined_impl.h86
-rw-r--r--gr-trellis/lib/viterbi_impl.cc190
-rw-r--r--gr-trellis/lib/viterbi_impl.h60
34 files changed, 4713 insertions, 4105 deletions
diff --git a/gr-trellis/lib/base.cc b/gr-trellis/lib/base.cc
index c5022dac83..15ccc80f75 100644
--- a/gr-trellis/lib/base.cc
+++ b/gr-trellis/lib/base.cc
@@ -26,61 +26,55 @@
#include <gnuradio/trellis/base.h>
namespace gr {
- namespace trellis {
+namespace trellis {
- bool
- dec2base(unsigned int num, int base, std::vector<int> &s)
- {
- int l = s.size();
- unsigned int n=num;
- for(int i=0;i<l;i++) {
- s[l-i-1] = n % base; //MSB first
- n /= base;
- }
- if(n!=0) {
- printf("Number %d requires more than %d digits.",num,l);
- return false;
- }
- else
- return true;
+bool dec2base(unsigned int num, int base, std::vector<int>& s)
+{
+ int l = s.size();
+ unsigned int n = num;
+ for (int i = 0; i < l; i++) {
+ s[l - i - 1] = n % base; // MSB first
+ n /= base;
}
+ if (n != 0) {
+ printf("Number %d requires more than %d digits.", num, l);
+ return false;
+ } else
+ return true;
+}
- unsigned int
- base2dec(const std::vector<int> &s, int base)
- {
- int l = s.size();
- unsigned int num=0;
- for(int i=0;i<l;i++)
- num=num*base+s[i];
- return num;
- }
+unsigned int base2dec(const std::vector<int>& s, int base)
+{
+ int l = s.size();
+ unsigned int num = 0;
+ for (int i = 0; i < l; i++)
+ num = num * base + s[i];
+ return num;
+}
- bool
- dec2bases(unsigned int num, const std::vector<int> &bases, std::vector<int> &s)
- {
- int l = s.size();
- unsigned int n=num;
- for(int i=0;i<l;i++) {
- s[l-i-1] = n % bases[l-i-1];
- n /= bases[l-i-1];
- }
- if(n!=0) {
- printf("Number %d requires more than %d digits.",num,l);
- return false;
- }
- else
- return true;
+bool dec2bases(unsigned int num, const std::vector<int>& bases, std::vector<int>& s)
+{
+ int l = s.size();
+ unsigned int n = num;
+ for (int i = 0; i < l; i++) {
+ s[l - i - 1] = n % bases[l - i - 1];
+ n /= bases[l - i - 1];
}
+ if (n != 0) {
+ printf("Number %d requires more than %d digits.", num, l);
+ return false;
+ } else
+ return true;
+}
- unsigned int
- bases2dec(const std::vector<int> &s, const std::vector<int> &bases)
- {
- int l = s.size();
- unsigned int num=0;
- for(int i=0;i<l;i++)
- num = num * bases[i] + s[i];
- return num;
- }
+unsigned int bases2dec(const std::vector<int>& s, const std::vector<int>& bases)
+{
+ int l = s.size();
+ unsigned int num = 0;
+ for (int i = 0; i < l; i++)
+ num = num * bases[i] + s[i];
+ return num;
+}
- } /* namespace trellis */
+} /* namespace trellis */
} /* namespace gr */
diff --git a/gr-trellis/lib/calc_metric.cc b/gr-trellis/lib/calc_metric.cc
index bdbb13ea08..587edd437e 100644
--- a/gr-trellis/lib/calc_metric.cc
+++ b/gr-trellis/lib/calc_metric.cc
@@ -25,224 +25,252 @@
#include <gnuradio/trellis/calc_metric.h>
namespace gr {
- namespace trellis {
-
- template <class T>
- void calc_metric(int O, int D, const std::vector<T> &TABLE, const T *input,
- float *metric, digital::trellis_metric_type_t type)
- {
- float minm = FLT_MAX;
- int minmi = 0;
-
- switch(type) {
- case digital::TRELLIS_EUCLIDEAN:
- for(int o = 0; o < O; o++) {
- metric[o] = 0.0;
- for(int m = 0; m < D; m++) {
- T s = input[m]-TABLE[o*D+m];
- //gr_complex sc(1.0*s,0);
- //metric[o] += (sc*conj(sc)).real();
- metric[o] += s * s;
- }
- }
- break;
- case digital::TRELLIS_HARD_SYMBOL:
- for(int o = 0; o < O; o++) {
- metric[o] = 0.0;
- for(int m = 0; m < D; m++) {
- T s = input[m]-TABLE[o*D+m];
- //gr_complex sc(1.0*s,0);
- //metric[o] + =(sc*conj(sc)).real();
- metric[o] += s * s;
- }
- if(metric[o] < minm) {
- minm = metric[o];
- minmi = o;
- }
- }
- for(int o = 0; o < O; o++) {
- metric[o] = (o == minmi ? 0.0 : 1.0);
- }
- break;
- case digital::TRELLIS_HARD_BIT:
- throw std::runtime_error("calc_metric: Invalid metric type (not yet implemented).");
- break;
- default:
- throw std::runtime_error("calc_metric: Invalid metric type.");
- }
+namespace trellis {
+
+template <class T>
+void calc_metric(int O,
+ int D,
+ const std::vector<T>& TABLE,
+ const T* input,
+ float* metric,
+ digital::trellis_metric_type_t type)
+{
+ float minm = FLT_MAX;
+ int minmi = 0;
+
+ switch (type) {
+ case digital::TRELLIS_EUCLIDEAN:
+ for (int o = 0; o < O; o++) {
+ metric[o] = 0.0;
+ for (int m = 0; m < D; m++) {
+ T s = input[m] - TABLE[o * D + m];
+ // gr_complex sc(1.0*s,0);
+ // metric[o] += (sc*conj(sc)).real();
+ metric[o] += s * s;
+ }
+ }
+ break;
+ case digital::TRELLIS_HARD_SYMBOL:
+ for (int o = 0; o < O; o++) {
+ metric[o] = 0.0;
+ for (int m = 0; m < D; m++) {
+ T s = input[m] - TABLE[o * D + m];
+ // gr_complex sc(1.0*s,0);
+ // metric[o] + =(sc*conj(sc)).real();
+ metric[o] += s * s;
+ }
+ if (metric[o] < minm) {
+ minm = metric[o];
+ minmi = o;
+ }
+ }
+ for (int o = 0; o < O; o++) {
+ metric[o] = (o == minmi ? 0.0 : 1.0);
+ }
+ break;
+ case digital::TRELLIS_HARD_BIT:
+ throw std::runtime_error(
+ "calc_metric: Invalid metric type (not yet implemented).");
+ break;
+ default:
+ throw std::runtime_error("calc_metric: Invalid metric type.");
}
+}
+
+template void calc_metric<char>(int O,
+ int D,
+ const std::vector<char>& TABLE,
+ const char* input,
+ float* metric,
+ digital::trellis_metric_type_t type);
+
+template void calc_metric<short>(int O,
+ int D,
+ const std::vector<short>& TABLE,
+ const short* input,
+ float* metric,
+ digital::trellis_metric_type_t type);
+
+template void calc_metric<int>(int O,
+ int D,
+ const std::vector<int>& TABLE,
+ const int* input,
+ float* metric,
+ digital::trellis_metric_type_t type);
+
+template void calc_metric<float>(int O,
+ int D,
+ const std::vector<float>& TABLE,
+ const float* input,
+ float* metric,
+ digital::trellis_metric_type_t type);
- template
- void calc_metric<char>(int O, int D, const std::vector<char> &TABLE, const char *input, float *metric, digital::trellis_metric_type_t type);
-
- template
- void calc_metric<short>(int O, int D, const std::vector<short> &TABLE, const short *input, float *metric, digital::trellis_metric_type_t type);
-
- template void calc_metric<int>(int O, int D, const std::vector<int> &TABLE, const int *input, float *metric, digital::trellis_metric_type_t type);
-
- template void calc_metric<float>(int O, int D, const std::vector<float> &TABLE, const float *input, float *metric, digital::trellis_metric_type_t type);
-
- /*
- void calc_metric(int O, int D, const std::vector<short> &TABLE, const short *input, float *metric, digital::trellis_metric_type_t type)
- {
- float minm = FLT_MAX;
- int minmi = 0;
-
- switch(type) {
- case digital::TRELLIS_EUCLIDEAN:
- for(int o = 0; o < O; o++) {
- metric[o] = 0.0;
- for(int m = 0; m < D; m++) {
- float s = input[m]-TABLE[o*D+m];
- metric[o] += s*s;
- }
- }
- break;
- case digital::TRELLIS_HARD_SYMBOL:
- for(int o = 0; o < O; o++) {
- metric[o] = 0.0;
- for(int m = 0; m < D; m++) {
- float s = input[m]-TABLE[o*D+m];
- metric[o] += s*s;
- }
- if(metric[o] < minm) {
- minm = metric[o];
- minmi = o;
- }
- }
- for(int o = 0; o < O; o++) {
- metric[o] = (o == minmi ? 0.0 : 1.0);
- }
- break;
- case digital::TRELLIS_HARD_BIT:
- throw std::runtime_error("calc_metric: Invalid metric type (not yet implemented).");
- break;
- default:
- throw std::runtime_error("calc_metric: Invalid metric type.");
+/*
+void calc_metric(int O, int D, const std::vector<short> &TABLE, const short *input, float
+*metric, digital::trellis_metric_type_t type)
+{
+ float minm = FLT_MAX;
+ int minmi = 0;
+
+ switch(type) {
+ case digital::TRELLIS_EUCLIDEAN:
+ for(int o = 0; o < O; o++) {
+ metric[o] = 0.0;
+ for(int m = 0; m < D; m++) {
+ float s = input[m]-TABLE[o*D+m];
+ metric[o] += s*s;
+ }
+ }
+ break;
+ case digital::TRELLIS_HARD_SYMBOL:
+ for(int o = 0; o < O; o++) {
+ metric[o] = 0.0;
+ for(int m = 0; m < D; m++) {
+ float s = input[m]-TABLE[o*D+m];
+ metric[o] += s*s;
+ }
+ if(metric[o] < minm) {
+ minm = metric[o];
+ minmi = o;
}
}
+ for(int o = 0; o < O; o++) {
+ metric[o] = (o == minmi ? 0.0 : 1.0);
+ }
+ break;
+ case digital::TRELLIS_HARD_BIT:
+ throw std::runtime_error("calc_metric: Invalid metric type (not yet implemented).");
+ break;
+ default:
+ throw std::runtime_error("calc_metric: Invalid metric type.");
+ }
+}
- void calc_metric(int O, int D, const std::vector<int> &TABLE, const int *input,
- float *metric, digital::trellis_metric_type_t type)
- {
- float minm = FLT_MAX;
- int minmi = 0;
-
- switch(type){
- case digital::TRELLIS_EUCLIDEAN:
- for(int o=0;o<O;o++) {
- metric[o]=0.0;
- for(int m=0;m<D;m++) {
- float s=input[m]-TABLE[o*D+m];
- metric[o]+=s*s;
- }
- }
- break;
- case digital::TRELLIS_HARD_SYMBOL:
- for(int o=0;o<O;o++) {
- metric[o]=0.0;
- for(int m=0;m<D;m++) {
- float s=input[m]-TABLE[o*D+m];
- metric[o]+=s*s;
- }
- if(metric[o]<minm) {
- minm=metric[o];
- minmi=o;
- }
- }
- for(int o=0;o<O;o++) {
- metric[o] = (o==minmi?0.0:1.0);
- }
- break;
- case digital::TRELLIS_HARD_BIT:
- throw std::runtime_error("calc_metric: Invalid metric type (not yet implemented).");
- break;
- default:
- throw std::runtime_error("calc_metric: Invalid metric type.");
+void calc_metric(int O, int D, const std::vector<int> &TABLE, const int *input,
+ float *metric, digital::trellis_metric_type_t type)
+{
+ float minm = FLT_MAX;
+ int minmi = 0;
+
+ switch(type){
+ case digital::TRELLIS_EUCLIDEAN:
+ for(int o=0;o<O;o++) {
+ metric[o]=0.0;
+ for(int m=0;m<D;m++) {
+ float s=input[m]-TABLE[o*D+m];
+ metric[o]+=s*s;
+ }
+ }
+ break;
+ case digital::TRELLIS_HARD_SYMBOL:
+ for(int o=0;o<O;o++) {
+ metric[o]=0.0;
+ for(int m=0;m<D;m++) {
+ float s=input[m]-TABLE[o*D+m];
+ metric[o]+=s*s;
+ }
+ if(metric[o]<minm) {
+ minm=metric[o];
+ minmi=o;
}
}
+ for(int o=0;o<O;o++) {
+ metric[o] = (o==minmi?0.0:1.0);
+ }
+ break;
+ case digital::TRELLIS_HARD_BIT:
+ throw std::runtime_error("calc_metric: Invalid metric type (not yet implemented).");
+ break;
+ default:
+ throw std::runtime_error("calc_metric: Invalid metric type.");
+ }
+}
+
+void calc_metric(int O, int D, const std::vector<float> &TABLE, const float *input,
+ float *metric, digital::trellis_metric_type_t type)
+{
+ float minm = FLT_MAX;
+ int minmi = 0;
- void calc_metric(int O, int D, const std::vector<float> &TABLE, const float *input,
- float *metric, digital::trellis_metric_type_t type)
- {
- float minm = FLT_MAX;
- int minmi = 0;
-
- switch(type) {
- case digital::TRELLIS_EUCLIDEAN:
- for(int o=0;o<O;o++) {
- metric[o]=0.0;
- for(int m=0;m<D;m++) {
- float s=input[m]-TABLE[o*D+m];
- metric[o]+=s*s;
- }
- }
- break;
- case digital::TRELLIS_HARD_SYMBOL:
- for(int o=0;o<O;o++) {
- metric[o]=0.0;
- for(int m=0;m<D;m++) {
- float s=input[m]-TABLE[o*D+m];
- metric[o]+=s*s;
- }
- if(metric[o]<minm) {
- minm=metric[o];
- minmi=o;
- }
- }
- for(int o=0;o<O;o++) {
- metric[o] = (o==minmi?0.0:1.0);
- }
- break;
- case digital::TRELLIS_HARD_BIT:
- throw std::runtime_error("calc_metric: Invalid metric type (not yet implemented).");
- break;
- default:
- throw std::runtime_error("calc_metric: Invalid metric type.");
+ switch(type) {
+ case digital::TRELLIS_EUCLIDEAN:
+ for(int o=0;o<O;o++) {
+ metric[o]=0.0;
+ for(int m=0;m<D;m++) {
+ float s=input[m]-TABLE[o*D+m];
+ metric[o]+=s*s;
}
}
+ break;
+ case digital::TRELLIS_HARD_SYMBOL:
+ for(int o=0;o<O;o++) {
+ metric[o]=0.0;
+ for(int m=0;m<D;m++) {
+ float s=input[m]-TABLE[o*D+m];
+ metric[o]+=s*s;
+ }
+ if(metric[o]<minm) {
+ minm=metric[o];
+ minmi=o;
+ }
+ }
+ for(int o=0;o<O;o++) {
+ metric[o] = (o==minmi?0.0:1.0);
+ }
+ break;
+ case digital::TRELLIS_HARD_BIT:
+ throw std::runtime_error("calc_metric: Invalid metric type (not yet implemented).");
+ break;
+ default:
+ throw std::runtime_error("calc_metric: Invalid metric type.");
+ }
+}
*/
- void calc_metric(int O, int D, const std::vector<gr_complex> &TABLE, const gr_complex *input,
- float *metric, digital::trellis_metric_type_t type)
- {
- float minm = FLT_MAX;
- int minmi = 0;
-
- switch(type) {
- case digital::TRELLIS_EUCLIDEAN:
- for(int o = 0; o < O; o++) {
- metric[o] = 0.0;
- for(int m = 0; m < D; m++) {
- gr_complex s = input[m]-TABLE[o*D+m];
- metric[o] += s.real()*s.real()+s.imag()*s.imag();
- }
- }
- break;
- case digital::TRELLIS_HARD_SYMBOL:
- for(int o = 0; o < O; o++) {
- metric[o] = 0.0;
- for(int m = 0; m < D; m++) {
- gr_complex s = input[m]-TABLE[o*D+m];
- metric[o] += s.real()*s.real()+s.imag()*s.imag();
- }
- if(metric[o] < minm) {
- minm = metric[o];
- minmi = o;
- }
- }
- for(int o = 0; o < O; o++) {
- metric[o] = (o == minmi ? 0.0 : 1.0);
- }
- break;
- case digital::TRELLIS_HARD_BIT:
- throw std::runtime_error("calc_metric: Invalid metric type (not yet implemented).");
- break;
- default:
- throw std::runtime_error("calc_metric: Invalid metric type.");
- }
+void calc_metric(int O,
+ int D,
+ const std::vector<gr_complex>& TABLE,
+ const gr_complex* input,
+ float* metric,
+ digital::trellis_metric_type_t type)
+{
+ float minm = FLT_MAX;
+ int minmi = 0;
+
+ switch (type) {
+ case digital::TRELLIS_EUCLIDEAN:
+ for (int o = 0; o < O; o++) {
+ metric[o] = 0.0;
+ for (int m = 0; m < D; m++) {
+ gr_complex s = input[m] - TABLE[o * D + m];
+ metric[o] += s.real() * s.real() + s.imag() * s.imag();
+ }
+ }
+ break;
+ case digital::TRELLIS_HARD_SYMBOL:
+ for (int o = 0; o < O; o++) {
+ metric[o] = 0.0;
+ for (int m = 0; m < D; m++) {
+ gr_complex s = input[m] - TABLE[o * D + m];
+ metric[o] += s.real() * s.real() + s.imag() * s.imag();
+ }
+ if (metric[o] < minm) {
+ minm = metric[o];
+ minmi = o;
+ }
+ }
+ for (int o = 0; o < O; o++) {
+ metric[o] = (o == minmi ? 0.0 : 1.0);
+ }
+ break;
+ case digital::TRELLIS_HARD_BIT:
+ throw std::runtime_error(
+ "calc_metric: Invalid metric type (not yet implemented).");
+ break;
+ default:
+ throw std::runtime_error("calc_metric: Invalid metric type.");
}
+}
- } /* namespace trellis */
+} /* namespace trellis */
} /* namespace gr */
-
diff --git a/gr-trellis/lib/constellation_metrics_cf_impl.cc b/gr-trellis/lib/constellation_metrics_cf_impl.cc
index 79dbe414bd..6658e0e518 100644
--- a/gr-trellis/lib/constellation_metrics_cf_impl.cc
+++ b/gr-trellis/lib/constellation_metrics_cf_impl.cc
@@ -31,66 +31,62 @@
#include <iostream>
namespace gr {
- namespace trellis {
+namespace trellis {
- constellation_metrics_cf::sptr
- constellation_metrics_cf::make(digital::constellation_sptr constellation,
- digital::trellis_metric_type_t TYPE)
- {
- return gnuradio::get_initial_sptr
- (new constellation_metrics_cf_impl(constellation, TYPE));
- }
-
- constellation_metrics_cf_impl::constellation_metrics_cf_impl(digital::constellation_sptr constellation,
- digital::trellis_metric_type_t TYPE)
- : block("constellation_metrics_cf",
- io_signature::make(1, -1, sizeof(gr_complex)),
- io_signature::make(1, -1, sizeof(float))),
- d_constellation(constellation),
- d_TYPE(TYPE),
- d_O(constellation->arity()),
- d_D(constellation->dimensionality())
- {
- set_relative_rate((uint64_t)d_O, (uint64_t)d_D);
- set_output_multiple((int)d_O);
- }
+constellation_metrics_cf::sptr
+constellation_metrics_cf::make(digital::constellation_sptr constellation,
+ digital::trellis_metric_type_t TYPE)
+{
+ return gnuradio::get_initial_sptr(
+ new constellation_metrics_cf_impl(constellation, TYPE));
+}
- constellation_metrics_cf_impl::~constellation_metrics_cf_impl()
- {
- }
+constellation_metrics_cf_impl::constellation_metrics_cf_impl(
+ digital::constellation_sptr constellation, digital::trellis_metric_type_t TYPE)
+ : block("constellation_metrics_cf",
+ io_signature::make(1, -1, sizeof(gr_complex)),
+ io_signature::make(1, -1, sizeof(float))),
+ d_constellation(constellation),
+ d_TYPE(TYPE),
+ d_O(constellation->arity()),
+ d_D(constellation->dimensionality())
+{
+ set_relative_rate((uint64_t)d_O, (uint64_t)d_D);
+ set_output_multiple((int)d_O);
+}
- void
- constellation_metrics_cf_impl::forecast(int noutput_items,
- gr_vector_int &ninput_items_required)
- {
- assert(noutput_items % d_O == 0);
+constellation_metrics_cf_impl::~constellation_metrics_cf_impl() {}
- unsigned int input_required = d_D * noutput_items / d_O;
- unsigned int ninputs = ninput_items_required.size();
- for(unsigned int i = 0; i < ninputs; i++)
- ninput_items_required[i] = input_required;
- }
+void constellation_metrics_cf_impl::forecast(int noutput_items,
+ gr_vector_int& ninput_items_required)
+{
+ assert(noutput_items % d_O == 0);
- int
- constellation_metrics_cf_impl::general_work(int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
- {
- unsigned int nstreams = input_items.size();
+ unsigned int input_required = d_D * noutput_items / d_O;
+ unsigned int ninputs = ninput_items_required.size();
+ for (unsigned int i = 0; i < ninputs; i++)
+ ninput_items_required[i] = input_required;
+}
- for(unsigned int m=0;m<nstreams;m++) {
- const gr_complex *in = (gr_complex*)input_items[m];
- float *out = (float*)output_items[m];
+int constellation_metrics_cf_impl::general_work(int noutput_items,
+ gr_vector_int& ninput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items)
+{
+ unsigned int nstreams = input_items.size();
- for(unsigned int i = 0; i < noutput_items / d_O ; i++) {
- d_constellation->calc_metric(&(in[i*d_D]), &(out[i*d_O]), d_TYPE);
- }
- }
+ for (unsigned int m = 0; m < nstreams; m++) {
+ const gr_complex* in = (gr_complex*)input_items[m];
+ float* out = (float*)output_items[m];
- consume_each(d_D * noutput_items / d_O);
- return noutput_items;
+ for (unsigned int i = 0; i < noutput_items / d_O; i++) {
+ d_constellation->calc_metric(&(in[i * d_D]), &(out[i * d_O]), d_TYPE);
+ }
}
- } /* namespace trellis */
+ consume_each(d_D * noutput_items / d_O);
+ return noutput_items;
+}
+
+} /* namespace trellis */
} /* namespace gr */
diff --git a/gr-trellis/lib/constellation_metrics_cf_impl.h b/gr-trellis/lib/constellation_metrics_cf_impl.h
index a2f165857b..8a3b367c6f 100644
--- a/gr-trellis/lib/constellation_metrics_cf_impl.h
+++ b/gr-trellis/lib/constellation_metrics_cf_impl.h
@@ -27,31 +27,30 @@
#include <gnuradio/trellis/constellation_metrics_cf.h>
namespace gr {
- namespace trellis {
-
- class constellation_metrics_cf_impl : public constellation_metrics_cf
- {
- private:
- digital::constellation_sptr d_constellation;
- digital::trellis_metric_type_t d_TYPE;
- unsigned int d_O;
- unsigned int d_D;
-
- public:
- constellation_metrics_cf_impl(digital::constellation_sptr constellation,
- digital::trellis_metric_type_t TYPE);
- ~constellation_metrics_cf_impl();
-
- void forecast(int noutput_items,
- gr_vector_int &ninput_items_required);
-
- int general_work(int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
- };
-
- } /* namespace trellis */
+namespace trellis {
+
+class constellation_metrics_cf_impl : public constellation_metrics_cf
+{
+private:
+ digital::constellation_sptr d_constellation;
+ digital::trellis_metric_type_t d_TYPE;
+ unsigned int d_O;
+ unsigned int d_D;
+
+public:
+ constellation_metrics_cf_impl(digital::constellation_sptr constellation,
+ digital::trellis_metric_type_t TYPE);
+ ~constellation_metrics_cf_impl();
+
+ void forecast(int noutput_items, gr_vector_int& ninput_items_required);
+
+ int general_work(int noutput_items,
+ gr_vector_int& ninput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items);
+};
+
+} /* namespace trellis */
} /* namespace gr */
#endif /* INCLUDED_TRELLIS_CONSTELLATION_METRICS_CF_IMPL_H */
diff --git a/gr-trellis/lib/core_algorithms.cc b/gr-trellis/lib/core_algorithms.cc
index b26ee331f2..d12896d342 100644
--- a/gr-trellis/lib/core_algorithms.cc
+++ b/gr-trellis/lib/core_algorithms.cc
@@ -27,1337 +27,1720 @@
#include <gnuradio/trellis/calc_metric.h>
namespace gr {
- namespace trellis {
+namespace trellis {
+
+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;
+ }
- static const float INF = 1.0e9;
+ 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;
+ }
- float
- min(float a, float b)
- {
- return a <= b ? a : b;
+ 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;
}
- float
- min_star(float a, float b)
- {
- return (a <= b ? a : b)-log(1+exp(a <= b ? a-b : b-a));
+ 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,
+ 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;
}
- 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];
- }
+ 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;
}
- 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,
- 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;
+ 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];
}
- // Ti = s i f c
- // To = b s i
-
- //---------------
-
- template void
- viterbi_algorithm_combined<char,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<char> &TABLE,
- digital::trellis_metric_type_t TYPE,
- const char *in, unsigned char *out);
-
- 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,
- 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,
- 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,
- 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,
- digital::trellis_metric_type_t TYPE,
- const gr_complex *in, unsigned char *out);
-
- //---------------
-
- template void
- viterbi_algorithm_combined<char,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<char> &TABLE,
- digital::trellis_metric_type_t TYPE,
- const char *in, short *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,
- 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,
- 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,
- 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,
- digital::trellis_metric_type_t TYPE,
- const gr_complex *in, short *out);
-
- //--------------
-
- template void
- viterbi_algorithm_combined<char,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<char> &TABLE,
- digital::trellis_metric_type_t TYPE,
- const char *in, int *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,
- 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,
- 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,
- 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,
- 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.");
+ delete[] metric;
+}
+
+// Ti = s i f c
+// To = b s i
+
+//---------------
+
+template void
+viterbi_algorithm_combined<char, 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<char>& TABLE,
+ digital::trellis_metric_type_t TYPE,
+ const char* in,
+ unsigned char* out);
+
+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,
+ 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,
+ 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,
+ 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,
+ digital::trellis_metric_type_t TYPE,
+ const gr_complex* in,
+ unsigned char* out);
+
+//---------------
+
+template void
+viterbi_algorithm_combined<char, 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<char>& TABLE,
+ digital::trellis_metric_type_t TYPE,
+ const char* in,
+ short* 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,
+ 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,
+ 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,
+ 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,
+ digital::trellis_metric_type_t TYPE,
+ const gr_complex* in,
+ short* out);
+
+//--------------
+
+template void
+viterbi_algorithm_combined<char, 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<char>& TABLE,
+ digital::trellis_metric_type_t TYPE,
+ const char* in,
+ int* 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,
+ 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,
+ 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,
+ 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,
+ 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;
}
- //===========================================================
-
- 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,
- 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);
+ 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+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 * I + i] = minm;
+ if (minm < norm)
+ norm = minm;
}
- 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;
+ 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,
+ 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;
}
- //---------
-
- 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,
- 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,
- 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,
- 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,
- 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,
- 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;
- }
+ 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
}
- //-------
-
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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;
- }
+ 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;
}
- //-------
-
- 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;
+ 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
}
- //----------------
-
- 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,
- 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*O+i*FSM2.O()+0];
- for(int j=1;j<FSM2.O();j++)
- x = (*p2mymin)(x,cprioro[k*O+i*FSM2.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*O+0*FSM2.O()+i];
- for(int j=1;j<FSM1.O();j++)
- x = (*p2mymin)(x,cprioro[k*O+j*FSM2.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;
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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 * O + i * FSM2.O() + 0];
+ for (int j = 1; j < FSM2.O(); j++)
+ x = (*p2mymin)(x, cprioro[k * O + i * FSM2.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 * O + 0 * FSM2.O() + i];
+ for (int j = 1; j < FSM1.O(); j++)
+ x = (*p2mymin)(x, cprioro[k * O + j * FSM2.O() + i]);
+ prioro2[k * FSM2.O() + i] = x;
+ }
}
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- digital::trellis_metric_type_t METRIC_TYPE,
- float scaling,
- const gr_complex *observations, int *data);
-
- } /* namespace trellis */
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ digital::trellis_metric_type_t METRIC_TYPE,
+ float scaling,
+ const gr_complex* observations,
+ int* data);
+
+} /* namespace trellis */
} /* namespace gr */
diff --git a/gr-trellis/lib/encoder_impl.cc b/gr-trellis/lib/encoder_impl.cc
index ecb0410a5f..28c1db304d 100644
--- a/gr-trellis/lib/encoder_impl.cc
+++ b/gr-trellis/lib/encoder_impl.cc
@@ -29,103 +29,100 @@
#include <iostream>
namespace gr {
- namespace trellis {
+namespace trellis {
- template <class IN_T, class OUT_T>
- typename encoder<IN_T,OUT_T>::sptr
- encoder<IN_T,OUT_T>::make(const fsm &FSM, int ST)
- {
- return gnuradio::get_initial_sptr
- (new encoder_impl<IN_T,OUT_T>(FSM,ST,0,false));
- }
+template <class IN_T, class OUT_T>
+typename encoder<IN_T, OUT_T>::sptr encoder<IN_T, OUT_T>::make(const fsm& FSM, int ST)
+{
+ return gnuradio::get_initial_sptr(new encoder_impl<IN_T, OUT_T>(FSM, ST, 0, false));
+}
- template <class IN_T, class OUT_T>
- typename encoder<IN_T,OUT_T>::sptr
- encoder<IN_T,OUT_T>::make(const fsm &FSM, int ST, int K)
- {
- return gnuradio::get_initial_sptr
- (new encoder_impl<IN_T,OUT_T>(FSM,ST,K,true));
- }
+template <class IN_T, class OUT_T>
+typename encoder<IN_T, OUT_T>::sptr
+encoder<IN_T, OUT_T>::make(const fsm& FSM, int ST, int K)
+{
+ return gnuradio::get_initial_sptr(new encoder_impl<IN_T, OUT_T>(FSM, ST, K, true));
+}
- template <class IN_T, class OUT_T>
- encoder_impl<IN_T,OUT_T>::encoder_impl(const fsm &FSM, int ST, int K, bool B)
+template <class IN_T, class OUT_T>
+encoder_impl<IN_T, OUT_T>::encoder_impl(const fsm& FSM, int ST, int K, bool B)
: sync_block("encoder<IN_T,OUT_T>",
- io_signature::make(1, 1, sizeof(IN_T)),
- io_signature::make(1, 1, sizeof(OUT_T))),
+ io_signature::make(1, 1, sizeof(IN_T)),
+ io_signature::make(1, 1, sizeof(OUT_T))),
d_FSM(FSM),
d_ST(ST),
d_K(K),
d_B(B)
- {
- }
+{
+}
- template <class IN_T, class OUT_T>
- void encoder_impl<IN_T,OUT_T>::set_FSM(const fsm &FSM)
- {
- gr::thread::scoped_lock guard(this->d_setlock);
- d_FSM = FSM;
- }
+template <class IN_T, class OUT_T>
+void encoder_impl<IN_T, OUT_T>::set_FSM(const fsm& FSM)
+{
+ gr::thread::scoped_lock guard(this->d_setlock);
+ d_FSM = FSM;
+}
- template <class IN_T, class OUT_T>
- void encoder_impl<IN_T,OUT_T>::set_ST(int ST)
- {
- gr::thread::scoped_lock guard(this->d_setlock);
- d_ST = ST;
- }
+template <class IN_T, class OUT_T>
+void encoder_impl<IN_T, OUT_T>::set_ST(int ST)
+{
+ gr::thread::scoped_lock guard(this->d_setlock);
+ d_ST = ST;
+}
- template <class IN_T, class OUT_T>
- void encoder_impl<IN_T,OUT_T>::set_K(int K)
- {
- gr::thread::scoped_lock guard(this->d_setlock);
- d_K = K;
- }
+template <class IN_T, class OUT_T>
+void encoder_impl<IN_T, OUT_T>::set_K(int K)
+{
+ gr::thread::scoped_lock guard(this->d_setlock);
+ d_K = K;
+}
- template <class IN_T, class OUT_T>
- encoder_impl<IN_T,OUT_T>::~encoder_impl()
- {
- }
+template <class IN_T, class OUT_T>
+encoder_impl<IN_T, OUT_T>::~encoder_impl()
+{
+}
- template <class IN_T, class OUT_T>
- int
- encoder_impl<IN_T,OUT_T>::work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
- {
- gr::thread::scoped_lock guard(this->d_setlock);
- int ST_tmp = 0;
+template <class IN_T, class OUT_T>
+int encoder_impl<IN_T, OUT_T>::work(int noutput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items)
+{
+ gr::thread::scoped_lock guard(this->d_setlock);
+ int ST_tmp = 0;
- if (d_B){ // blockwise operation
- int nblocks = noutput_items /d_K;
- const IN_T *in = (const IN_T*)input_items[0];
- OUT_T *out = (OUT_T *) output_items[0];
- for(int n = 0; n < nblocks; n++) {
- ST_tmp = d_ST;
- for(int i = 0; i < d_K; i++) {
- out[n*d_K+i] = (OUT_T)d_FSM.OS()[ST_tmp*d_FSM.I()+in[n*d_K+i]];
- ST_tmp = (int)d_FSM.NS()[ST_tmp*d_FSM.I()+in[n*d_K+i]];
- }
+ if (d_B) { // blockwise operation
+ int nblocks = noutput_items / d_K;
+ const IN_T* in = (const IN_T*)input_items[0];
+ OUT_T* out = (OUT_T*)output_items[0];
+ for (int n = 0; n < nblocks; n++) {
+ ST_tmp = d_ST;
+ for (int i = 0; i < d_K; i++) {
+ out[n * d_K + i] =
+ (OUT_T)d_FSM.OS()[ST_tmp * d_FSM.I() + in[n * d_K + i]];
+ ST_tmp = (int)d_FSM.NS()[ST_tmp * d_FSM.I() + in[n * d_K + i]];
+ }
}
- return nblocks*d_K;
- } // end blockwise operation
- else{ // streaming operation
- const IN_T *in = (const IN_T*)input_items[0];
- OUT_T *out = (OUT_T *) output_items[0];
+ return nblocks * d_K;
+ } // end blockwise operation
+ else { // streaming operation
+ const IN_T* in = (const IN_T*)input_items[0];
+ OUT_T* out = (OUT_T*)output_items[0];
ST_tmp = d_ST;
- for(int i = 0; i < noutput_items; i++) {
- out[i] = (OUT_T)d_FSM.OS()[ST_tmp*d_FSM.I()+in[i]];
- ST_tmp = (int)d_FSM.NS()[ST_tmp*d_FSM.I()+in[i]];
+ for (int i = 0; i < noutput_items; i++) {
+ out[i] = (OUT_T)d_FSM.OS()[ST_tmp * d_FSM.I() + in[i]];
+ ST_tmp = (int)d_FSM.NS()[ST_tmp * d_FSM.I() + in[i]];
}
d_ST = ST_tmp;
return noutput_items;
- } // end streaming operation
- }
- template class encoder<std::uint8_t, std::uint8_t>;
- template class encoder<std::uint8_t, std::int16_t>;
- template class encoder<std::uint8_t, std::int32_t>;
- template class encoder<std::int16_t, std::int16_t>;
- template class encoder<std::int16_t, std::int32_t>;
- template class encoder<std::int32_t, std::int32_t>;
+ } // end streaming operation
+}
+template class encoder<std::uint8_t, std::uint8_t>;
+template class encoder<std::uint8_t, std::int16_t>;
+template class encoder<std::uint8_t, std::int32_t>;
+template class encoder<std::int16_t, std::int16_t>;
+template class encoder<std::int16_t, std::int32_t>;
+template class encoder<std::int32_t, std::int32_t>;
- } /* namespace trellis */
+} /* namespace trellis */
} /* namespace gr */
diff --git a/gr-trellis/lib/encoder_impl.h b/gr-trellis/lib/encoder_impl.h
index 5832b9d848..d98465c883 100644
--- a/gr-trellis/lib/encoder_impl.h
+++ b/gr-trellis/lib/encoder_impl.h
@@ -26,34 +26,38 @@
#include <gnuradio/trellis/encoder.h>
namespace gr {
- namespace trellis {
+namespace trellis {
- template <class IN_T, class OUT_T>
- class encoder_impl : public encoder<IN_T,OUT_T>
+template <class IN_T, class OUT_T>
+class encoder_impl : public encoder<IN_T, OUT_T>
+{
+private:
+ fsm d_FSM;
+ int d_ST;
+ int d_K;
+ bool d_B;
+
+
+public:
+ encoder_impl(const fsm& FSM, int ST, int K, bool B);
+ ~encoder_impl();
+
+ fsm FSM() const
{
- private:
- fsm d_FSM;
- int d_ST;
- int d_K;
- bool d_B;
-
-
- public:
- encoder_impl(const fsm &FSM, int ST, int K, bool B);
- ~encoder_impl();
-
- fsm FSM() const { return d_FSM;; }
- int ST() const { return d_ST; }
- int K() const { return d_K; }
- void set_FSM(const fsm &FSM);
- void set_ST(int ST);
- void set_K(int K);
- int work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
- };
-
- } /* namespace trellis */
+ return d_FSM;
+ ;
+ }
+ int ST() const { return d_ST; }
+ int K() const { return d_K; }
+ void set_FSM(const fsm& FSM);
+ void set_ST(int ST);
+ void set_K(int K);
+ int work(int noutput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items);
+};
+
+} /* namespace trellis */
} /* namespace gr */
#endif /* ENCODER_IMPL_H */
diff --git a/gr-trellis/lib/fsm.cc b/gr-trellis/lib/fsm.cc
index 4c1fe69285..ca28266b70 100644
--- a/gr-trellis/lib/fsm.cc
+++ b/gr-trellis/lib/fsm.cc
@@ -31,299 +31,311 @@
#include <gnuradio/trellis/fsm.h>
namespace gr {
- namespace trellis {
-
- fsm::fsm()
- {
- d_I=0;
- d_S=0;
- d_O=0;
- d_NS.resize(0);
- d_OS.resize(0);
- d_PS.resize(0);
- d_PI.resize(0);
- d_TMi.resize(0);
- d_TMl.resize(0);
+namespace trellis {
+
+fsm::fsm()
+{
+ d_I = 0;
+ d_S = 0;
+ d_O = 0;
+ d_NS.resize(0);
+ d_OS.resize(0);
+ d_PS.resize(0);
+ d_PI.resize(0);
+ d_TMi.resize(0);
+ d_TMl.resize(0);
+}
+
+fsm::fsm(const fsm& FSM)
+{
+ d_I = FSM.I();
+ d_S = FSM.S();
+ d_O = FSM.O();
+ d_NS = FSM.NS();
+ d_OS = FSM.OS();
+ d_PS = FSM.PS(); // is this going to make a deep copy?
+ d_PI = FSM.PI();
+ d_TMi = FSM.TMi();
+ d_TMl = FSM.TMl();
+}
+
+fsm::fsm(int I, int S, int O, const std::vector<int>& NS, const std::vector<int>& OS)
+{
+ d_I = I;
+ d_S = S;
+ d_O = O;
+ d_NS = NS;
+ d_OS = OS;
+
+ generate_PS_PI();
+ generate_TM();
+}
+
+//######################################################################
+//# Read an FSM specification from a file.
+//# Format (hopefully will become more flexible in the future...):
+//# I S O (in the first line)
+//# blank line
+//# Next state matrix (S lines, each with I integers separated by spaces)
+//# blank line
+//# output symbol matrix (S lines, each with I integers separated by spaces)
+//# optional comments
+//######################################################################
+fsm::fsm(const char* name)
+{
+ FILE* fsmfile;
+
+ if ((fsmfile = fopen(name, "r")) == NULL)
+ throw std::runtime_error("fsm::fsm(const char *name): file open error\n");
+ // printf("file open error in fsm()\n");
+
+ if (fscanf(fsmfile, "%d %d %d\n", &d_I, &d_S, &d_O) == EOF) {
+ if (ferror(fsmfile) != 0)
+ throw std::runtime_error("fsm::fsm(const char *name): file read error\n");
}
- fsm::fsm(const fsm &FSM)
- {
- d_I=FSM.I();
- d_S=FSM.S();
- d_O=FSM.O();
- d_NS=FSM.NS();
- d_OS=FSM.OS();
- d_PS=FSM.PS(); // is this going to make a deep copy?
- d_PI=FSM.PI();
- d_TMi=FSM.TMi();
- d_TMl=FSM.TMl();
- }
-
- fsm::fsm(int I, int S, int O, const std::vector<int> &NS, const std::vector<int> &OS)
- {
- d_I=I;
- d_S=S;
- d_O=O;
- d_NS=NS;
- d_OS=OS;
+ d_NS.resize(d_I * d_S);
+ d_OS.resize(d_I * d_S);
- generate_PS_PI();
- generate_TM();
+ for (int i = 0; i < d_S; i++) {
+ for (int j = 0; j < d_I; j++) {
+ if (fscanf(fsmfile, "%d", &(d_NS[i * d_I + j])) == EOF) {
+ if (ferror(fsmfile) != 0)
+ throw std::runtime_error(
+ "fsm::fsm(const char *name): file read error\n");
+ }
+ }
+ }
+ for (int i = 0; i < d_S; i++) {
+ for (int j = 0; j < d_I; j++) {
+ if (fscanf(fsmfile, "%d", &(d_OS[i * d_I + j])) == EOF) {
+ if (ferror(fsmfile) != 0)
+ throw std::runtime_error(
+ "fsm::fsm(const char *name): file read error\n");
+ }
+ }
}
- //######################################################################
- //# Read an FSM specification from a file.
- //# Format (hopefully will become more flexible in the future...):
- //# I S O (in the first line)
- //# blank line
- //# Next state matrix (S lines, each with I integers separated by spaces)
- //# blank line
- //# output symbol matrix (S lines, each with I integers separated by spaces)
- //# optional comments
- //######################################################################
- fsm::fsm(const char *name)
- {
- FILE *fsmfile;
-
- if((fsmfile=fopen(name,"r"))==NULL)
- throw std::runtime_error ("fsm::fsm(const char *name): file open error\n");
- //printf("file open error in fsm()\n");
-
- if(fscanf(fsmfile,"%d %d %d\n",&d_I,&d_S,&d_O) == EOF) {
- if(ferror(fsmfile) != 0)
- throw std::runtime_error ("fsm::fsm(const char *name): file read error\n");
- }
-
- d_NS.resize(d_I*d_S);
- d_OS.resize(d_I*d_S);
-
- for(int i=0;i<d_S;i++) {
- for(int j=0;j<d_I;j++) {
- if(fscanf(fsmfile,"%d",&(d_NS[i*d_I+j])) == EOF) {
- if(ferror(fsmfile) != 0)
- throw std::runtime_error ("fsm::fsm(const char *name): file read error\n");
- }
- }
- }
- for(int i=0;i<d_S;i++) {
- for(int j=0;j<d_I;j++) {
- if(fscanf(fsmfile,"%d",&(d_OS[i*d_I+j])) == EOF) {
- if(ferror(fsmfile) != 0)
- throw std::runtime_error ("fsm::fsm(const char *name): file read error\n");
- }
- }
- }
-
- fclose(fsmfile);
-
- generate_PS_PI();
- generate_TM();
+ fclose(fsmfile);
+
+ generate_PS_PI();
+ generate_TM();
+}
+
+//######################################################################
+//# Automatically generate the FSM from the generator matrix
+//# of a (n,k) binary convolutional code
+//######################################################################
+fsm::fsm(int k, int n, const std::vector<int>& G)
+{
+ // calculate maximum memory requirements for each input stream
+ std::vector<int> max_mem_x(k, -1);
+ int max_mem = -1;
+ for (int i = 0; i < k; i++) {
+ for (int j = 0; j < n; j++) {
+ int mem = -1;
+ if (G[i * n + j] != 0)
+ mem = (int)(log(double(G[i * n + j])) / log(2.0));
+ if (mem > max_mem_x[i])
+ max_mem_x[i] = mem;
+ if (mem > max_mem)
+ max_mem = mem;
+ }
}
- //######################################################################
- //# Automatically generate the FSM from the generator matrix
- //# of a (n,k) binary convolutional code
- //######################################################################
- fsm::fsm(int k, int n, const std::vector<int> &G)
- {
- // calculate maximum memory requirements for each input stream
- std::vector<int> max_mem_x(k,-1);
- int max_mem = -1;
- for(int i=0;i<k;i++) {
- for(int j=0;j<n;j++) {
- int mem = -1;
- if(G[i*n+j]!=0)
- mem=(int)(log(double(G[i*n+j]))/log(2.0));
- if(mem>max_mem_x[i])
- max_mem_x[i]=mem;
- if(mem>max_mem)
- max_mem=mem;
- }
- }
-
- //printf("max_mem_x\n");
- //for(int j=0;j<max_mem_x.size();j++) printf("%d ",max_mem_x[j]); printf("\n");
-
- // calculate total memory requirements to set S
- int sum_max_mem = 0;
- for(int i=0;i<k;i++)
- sum_max_mem += max_mem_x[i];
-
- //printf("sum_max_mem = %d\n",sum_max_mem);
-
- d_I=1<<k;
- d_S=1<<sum_max_mem;
- d_O=1<<n;
-
- // binary representation of the G matrix
- std::vector<std::vector<int> > Gb(k*n);
- for(int j=0;j<k*n;j++) {
- Gb[j].resize(max_mem+1);
- dec2base(G[j],2,Gb[j]);
- //printf("Gb\n");
- //for(int m=0;m<Gb[j].size();m++) printf("%d ",Gb[j][m]); printf("\n");
- }
-
- // alphabet size of each shift register
- std::vector<int> bases_x(k);
- for(int j=0;j<k ;j++)
- bases_x[j] = 1 << max_mem_x[j];
- //printf("bases_x\n");
- //for(int j=0;j<max_mem_x.size();j++) printf("%d ",max_mem_x[j]); printf("\n");
-
- d_NS.resize(d_I*d_S);
- d_OS.resize(d_I*d_S);
-
- std::vector<int> sx(k);
- std::vector<int> nsx(k);
- std::vector<int> tx(k);
- std::vector<std::vector<int> > tb(k);
- for(int j=0;j<k;j++)
- tb[j].resize(max_mem+1);
- std::vector<int> inb(k);
- std::vector<int> outb(n);
-
- for(int s=0;s<d_S;s++) {
- dec2bases(s,bases_x,sx); // split s into k values, each representing one of the k shift registers
- //printf("state = %d \nstates = ",s);
- //for(int j=0;j<sx.size();j++) printf("%d ",sx[j]); printf("\n");
- for(int i=0;i<d_I;i++) {
- dec2base(i,2,inb); // input in binary
- //printf("input = %d \ninputs = ",i);
- //for(int j=0;j<inb.size();j++) printf("%d ",inb[j]); printf("\n");
-
- // evaluate next state
- for(int j=0;j<k;j++)
- nsx[j] = (inb[j]*bases_x[j]+sx[j])/2; // next state (for each shift register) MSB first
- d_NS[s*d_I+i]=bases2dec(nsx,bases_x); // collect all values into the new state
-
- // evaluate transitions
- for(int j=0;j<k;j++)
- tx[j] = inb[j]*bases_x[j]+sx[j]; // transition (for each shift register)MSB first
- for(int j=0;j<k;j++) {
- dec2base(tx[j],2,tb[j]); // transition in binary
- //printf("transition = %d \ntransitions = ",tx[j]);
- //for(int m=0;m<tb[j].size();m++) printf("%d ",tb[j][m]); printf("\n");
- }
-
- // evaluate outputs
- for(int nn=0;nn<n;nn++) {
- outb[nn] = 0;
- for(int j=0;j<k;j++) {
- for(int m=0;m<max_mem+1;m++)
- outb[nn] = (outb[nn] + Gb[j*n+nn][m]*tb[j][m]) % 2; // careful: polynomial 1+D ir represented as 110, not as 011
- //printf("output %d equals %d\n",nn,outb[nn]);
- }
- }
- d_OS[s*d_I+i] = base2dec(outb,2);
- }
- }
-
- generate_PS_PI();
- generate_TM();
+ // printf("max_mem_x\n");
+ // for(int j=0;j<max_mem_x.size();j++) printf("%d ",max_mem_x[j]); printf("\n");
+
+ // calculate total memory requirements to set S
+ int sum_max_mem = 0;
+ for (int i = 0; i < k; i++)
+ sum_max_mem += max_mem_x[i];
+
+ // printf("sum_max_mem = %d\n",sum_max_mem);
+
+ d_I = 1 << k;
+ d_S = 1 << sum_max_mem;
+ d_O = 1 << n;
+
+ // binary representation of the G matrix
+ std::vector<std::vector<int>> Gb(k * n);
+ for (int j = 0; j < k * n; j++) {
+ Gb[j].resize(max_mem + 1);
+ dec2base(G[j], 2, Gb[j]);
+ // printf("Gb\n");
+ // for(int m=0;m<Gb[j].size();m++) printf("%d ",Gb[j][m]); printf("\n");
}
- //######################################################################
- //# Automatically generate an FSM specification describing the
- //# ISI for a channel
- //# of length ch_length and a modulation of size mod_size
- //######################################################################
- fsm::fsm(int mod_size, int ch_length)
- {
- d_I=mod_size;
- d_S=(int) (pow(1.0*d_I,1.0*ch_length-1)+0.5);
- d_O=d_S*d_I;
-
- d_NS.resize(d_I*d_S);
- d_OS.resize(d_I*d_S);
-
- for(int s=0;s<d_S;s++) {
- for(int i=0;i<d_I;i++) {
- int t=i*d_S+s;
- d_NS[s*d_I+i] = t/d_I;
- d_OS[s*d_I+i] = t;
- }
- }
-
- generate_PS_PI();
- generate_TM();
+ // alphabet size of each shift register
+ std::vector<int> bases_x(k);
+ for (int j = 0; j < k; j++)
+ bases_x[j] = 1 << max_mem_x[j];
+ // printf("bases_x\n");
+ // for(int j=0;j<max_mem_x.size();j++) printf("%d ",max_mem_x[j]); printf("\n");
+
+ d_NS.resize(d_I * d_S);
+ d_OS.resize(d_I * d_S);
+
+ std::vector<int> sx(k);
+ std::vector<int> nsx(k);
+ std::vector<int> tx(k);
+ std::vector<std::vector<int>> tb(k);
+ for (int j = 0; j < k; j++)
+ tb[j].resize(max_mem + 1);
+ std::vector<int> inb(k);
+ std::vector<int> outb(n);
+
+ for (int s = 0; s < d_S; s++) {
+ dec2bases(
+ s,
+ bases_x,
+ sx); // split s into k values, each representing one of the k shift registers
+ // printf("state = %d \nstates = ",s);
+ // for(int j=0;j<sx.size();j++) printf("%d ",sx[j]); printf("\n");
+ for (int i = 0; i < d_I; i++) {
+ dec2base(i, 2, inb); // input in binary
+ // printf("input = %d \ninputs = ",i);
+ // for(int j=0;j<inb.size();j++) printf("%d ",inb[j]); printf("\n");
+
+ // evaluate next state
+ for (int j = 0; j < k; j++)
+ nsx[j] = (inb[j] * bases_x[j] + sx[j]) /
+ 2; // next state (for each shift register) MSB first
+ d_NS[s * d_I + i] =
+ bases2dec(nsx, bases_x); // collect all values into the new state
+
+ // evaluate transitions
+ for (int j = 0; j < k; j++)
+ tx[j] = inb[j] * bases_x[j] +
+ sx[j]; // transition (for each shift register)MSB first
+ for (int j = 0; j < k; j++) {
+ dec2base(tx[j], 2, tb[j]); // transition in binary
+ // printf("transition = %d \ntransitions = ",tx[j]);
+ // for(int m=0;m<tb[j].size();m++) printf("%d ",tb[j][m]); printf("\n");
+ }
+
+ // evaluate outputs
+ for (int nn = 0; nn < n; nn++) {
+ outb[nn] = 0;
+ for (int j = 0; j < k; j++) {
+ for (int m = 0; m < max_mem + 1; m++)
+ outb[nn] = (outb[nn] + Gb[j * n + nn][m] * tb[j][m]) %
+ 2; // careful: polynomial 1+D ir represented as 110,
+ // not as 011
+ // printf("output %d equals %d\n",nn,outb[nn]);
+ }
+ }
+ d_OS[s * d_I + i] = base2dec(outb, 2);
+ }
}
- //######################################################################
- //# Automatically generate an FSM specification describing the
- //# the trellis for a CPM with h=K/P (relatively prime),
- //# alphabet size M, and frequency pulse duration L symbols
- //#
- //# This FSM is based on the paper by B. Rimoldi
- //# "A decomposition approach to CPM", IEEE Trans. Info Theory, March 1988
- //# See also my own notes at http://www.eecs.umich.edu/~anastas/docs/cpm.pdf
- //######################################################################
- fsm::fsm(int P, int M, int L)
- {
- d_I=M;
- d_S=(int)(pow(1.0*M,1.0*L-1)+0.5)*P;
- d_O=(int)(pow(1.0*M,1.0*L)+0.5)*P;
-
- d_NS.resize(d_I*d_S);
- d_OS.resize(d_I*d_S);
- int nv;
- for(int s=0;s<d_S;s++) {
- for(int i=0;i<d_I;i++) {
- int s1=s/P;
- int v=s%P;
- int ns1= (i*(int)(pow(1.0*M,1.0*(L-1))+0.5)+s1)/M;
- if (L==1)
- nv=(i+v)%P;
- else
- nv=(s1%M+v)%P;
- d_NS[s*d_I+i] = ns1*P+nv;
- d_OS[s*d_I+i] = i*d_S+s;
- }
- }
-
- generate_PS_PI();
- generate_TM();
+ generate_PS_PI();
+ generate_TM();
+}
+
+//######################################################################
+//# Automatically generate an FSM specification describing the
+//# ISI for a channel
+//# of length ch_length and a modulation of size mod_size
+//######################################################################
+fsm::fsm(int mod_size, int ch_length)
+{
+ d_I = mod_size;
+ d_S = (int)(pow(1.0 * d_I, 1.0 * ch_length - 1) + 0.5);
+ d_O = d_S * d_I;
+
+ d_NS.resize(d_I * d_S);
+ d_OS.resize(d_I * d_S);
+
+ for (int s = 0; s < d_S; s++) {
+ for (int i = 0; i < d_I; i++) {
+ int t = i * d_S + s;
+ d_NS[s * d_I + i] = t / d_I;
+ d_OS[s * d_I + i] = t;
+ }
}
- //######################################################################
- //# Automatically generate an FSM specification describing the
- //# the joint trellis of fsm1 and fsm2
- //######################################################################
- fsm::fsm(const fsm &FSM1, const fsm &FSM2)
- {
- d_I=FSM1.I()*FSM2.I();
- d_S=FSM1.S()*FSM2.S();
- d_O=FSM1.O()*FSM2.O();
-
- d_NS.resize(d_I*d_S);
- d_OS.resize(d_I*d_S);
-
- for(int s=0;s<d_S;s++) {
- for(int i=0;i<d_I;i++) {
- int s1=s/FSM2.S();
- int s2=s%FSM2.S();
- int i1=i/FSM2.I();
- int i2=i%FSM2.I();
- d_NS[s*d_I+i] = FSM1.NS()[s1 * FSM1.I() + i1] * FSM2.S() + FSM2.NS()[s2 * FSM2.I() + i2];
- d_OS[s*d_I+i] = FSM1.OS()[s1 * FSM1.I() + i1] * FSM2.O() + FSM2.OS()[s2 * FSM2.I() + i2];
- }
- }
-
- generate_PS_PI();
- generate_TM();
+ generate_PS_PI();
+ generate_TM();
+}
+
+//######################################################################
+//# Automatically generate an FSM specification describing the
+//# the trellis for a CPM with h=K/P (relatively prime),
+//# alphabet size M, and frequency pulse duration L symbols
+//#
+//# This FSM is based on the paper by B. Rimoldi
+//# "A decomposition approach to CPM", IEEE Trans. Info Theory, March 1988
+//# See also my own notes at http://www.eecs.umich.edu/~anastas/docs/cpm.pdf
+//######################################################################
+fsm::fsm(int P, int M, int L)
+{
+ d_I = M;
+ d_S = (int)(pow(1.0 * M, 1.0 * L - 1) + 0.5) * P;
+ d_O = (int)(pow(1.0 * M, 1.0 * L) + 0.5) * P;
+
+ d_NS.resize(d_I * d_S);
+ d_OS.resize(d_I * d_S);
+ int nv;
+ for (int s = 0; s < d_S; s++) {
+ for (int i = 0; i < d_I; i++) {
+ int s1 = s / P;
+ int v = s % P;
+ int ns1 = (i * (int)(pow(1.0 * M, 1.0 * (L - 1)) + 0.5) + s1) / M;
+ if (L == 1)
+ nv = (i + v) % P;
+ else
+ nv = (s1 % M + v) % P;
+ d_NS[s * d_I + i] = ns1 * P + nv;
+ d_OS[s * d_I + i] = i * d_S + s;
+ }
}
+ generate_PS_PI();
+ generate_TM();
+}
+
+//######################################################################
+//# Automatically generate an FSM specification describing the
+//# the joint trellis of fsm1 and fsm2
+//######################################################################
+fsm::fsm(const fsm& FSM1, const fsm& FSM2)
+{
+ d_I = FSM1.I() * FSM2.I();
+ d_S = FSM1.S() * FSM2.S();
+ d_O = FSM1.O() * FSM2.O();
+
+ d_NS.resize(d_I * d_S);
+ d_OS.resize(d_I * d_S);
+
+ for (int s = 0; s < d_S; s++) {
+ for (int i = 0; i < d_I; i++) {
+ int s1 = s / FSM2.S();
+ int s2 = s % FSM2.S();
+ int i1 = i / FSM2.I();
+ int i2 = i % FSM2.I();
+ d_NS[s * d_I + i] =
+ FSM1.NS()[s1 * FSM1.I() + i1] * FSM2.S() + FSM2.NS()[s2 * FSM2.I() + i2];
+ d_OS[s * d_I + i] =
+ FSM1.OS()[s1 * FSM1.I() + i1] * FSM2.O() + FSM2.OS()[s2 * FSM2.I() + i2];
+ }
+ }
- //######################################################################
- //# Automatically generate an FSM specification describing the
- //# the joint trellis of two serially concatenated fsms.
- //######################################################################
- fsm::fsm(const fsm &FSMo, const fsm &FSMi, bool serial)
- {
- if(serial==false || FSMo.O()!=FSMi.I()) {
- d_I=0;
- d_S=0;
- d_O=0;
+ generate_PS_PI();
+ generate_TM();
+}
+
+
+//######################################################################
+//# Automatically generate an FSM specification describing the
+//# the joint trellis of two serially concatenated fsms.
+//######################################################################
+fsm::fsm(const fsm& FSMo, const fsm& FSMi, bool serial)
+{
+ if (serial == false || FSMo.O() != FSMi.I()) {
+ d_I = 0;
+ d_S = 0;
+ d_O = 0;
d_NS.resize(0);
d_OS.resize(0);
d_PS.resize(0);
@@ -331,243 +343,260 @@ namespace gr {
d_TMi.resize(0);
d_TMl.resize(0);
return;
- }
-
- d_I=FSMo.I();
- d_S=FSMo.S()*FSMi.S();
- d_O=FSMi.O();
-
- d_NS.resize(d_I*d_S);
- d_OS.resize(d_I*d_S);
-
- for(int s=0;s<d_S;s++) {
- for(int i=0;i<d_I;i++) {
- int so=s/FSMi.S();
- int si=s%FSMi.S();
- int oo=FSMo.OS()[so * FSMo.I() + i];
- int oi=FSMi.OS()[si * FSMi.I() + oo];
- d_NS[s*d_I+i] = FSMo.NS()[so * FSMo.I() + i] * FSMo.S() + FSMi.NS()[si * FSMi.I() + oo];
- d_OS[s*d_I+i] = oi;
- }
- }
-
- generate_PS_PI();
- generate_TM();
}
-
-
-
-
-
-
- //######################################################################
- //# Generate a new FSM representing n stages through the original FSM
- //# AKA radix-n FSM
- //######################################################################
- fsm::fsm(const fsm &FSM, int n)
- {
- d_I=(int) (pow(1.0*FSM.I(),1.0*n)+0.5);
- d_S=FSM.S();
- d_O=(int) (pow(1.0*FSM.O(),1.0*n)+0.5);
-
- d_NS.resize(d_I*d_S);
- d_OS.resize(d_I*d_S);
-
- for(int s=0;s<d_S;s++ ) {
- for(int i=0;i<d_I;i++ ) {
- std::vector<int> ii(n);
- dec2base(i,FSM.I(),ii);
- std::vector<int> oo(n);
- int ns=s;
- for(int k=0;k<n;k++) {
- oo[k]=FSM.OS()[ns*FSM.I()+ii[k]];
- ns=FSM.NS()[ns*FSM.I()+ii[k]];
- }
- d_NS[s*d_I+i]=ns;
- d_OS[s*d_I+i]=base2dec(oo,FSM.O());
- }
- }
-
- generate_PS_PI();
- generate_TM();
+ d_I = FSMo.I();
+ d_S = FSMo.S() * FSMi.S();
+ d_O = FSMi.O();
+
+ d_NS.resize(d_I * d_S);
+ d_OS.resize(d_I * d_S);
+
+ for (int s = 0; s < d_S; s++) {
+ for (int i = 0; i < d_I; i++) {
+ int so = s / FSMi.S();
+ int si = s % FSMi.S();
+ int oo = FSMo.OS()[so * FSMo.I() + i];
+ int oi = FSMi.OS()[si * FSMi.I() + oo];
+ d_NS[s * d_I + i] =
+ FSMo.NS()[so * FSMo.I() + i] * FSMo.S() + FSMi.NS()[si * FSMi.I() + oo];
+ d_OS[s * d_I + i] = oi;
+ }
}
- //######################################################################
- //# generate the PS and PI tables for later use
- //######################################################################
- void
- fsm::generate_PS_PI()
- {
- d_PS.resize(d_S);
- d_PI.resize(d_S);
-
- for(int i=0;i<d_S;i++) {
- d_PS[i].resize(d_I*d_S); // max possible size
- d_PI[i].resize(d_I*d_S);
- int j=0;
- for(int ii=0;ii<d_S;ii++) for(int jj=0;jj<d_I;jj++) {
- if(d_NS[ii*d_I+jj]!=i) continue;
- d_PS[i][j]=ii;
- d_PI[i][j]=jj;
- j++;
- }
- d_PS[i].resize(j);
- d_PI[i].resize(j);
- }
+ generate_PS_PI();
+ generate_TM();
+}
+
+
+//######################################################################
+//# Generate a new FSM representing n stages through the original FSM
+//# AKA radix-n FSM
+//######################################################################
+fsm::fsm(const fsm& FSM, int n)
+{
+ d_I = (int)(pow(1.0 * FSM.I(), 1.0 * n) + 0.5);
+ d_S = FSM.S();
+ d_O = (int)(pow(1.0 * FSM.O(), 1.0 * n) + 0.5);
+
+ d_NS.resize(d_I * d_S);
+ d_OS.resize(d_I * d_S);
+
+ for (int s = 0; s < d_S; s++) {
+ for (int i = 0; i < d_I; i++) {
+ std::vector<int> ii(n);
+ dec2base(i, FSM.I(), ii);
+ std::vector<int> oo(n);
+ int ns = s;
+ for (int k = 0; k < n; k++) {
+ oo[k] = FSM.OS()[ns * FSM.I() + ii[k]];
+ ns = FSM.NS()[ns * FSM.I() + ii[k]];
+ }
+ d_NS[s * d_I + i] = ns;
+ d_OS[s * d_I + i] = base2dec(oo, FSM.O());
+ }
}
- //######################################################################
- //# generate the termination matrices TMl and TMi for later use
- //######################################################################
- void
- fsm::generate_TM()
- {
- d_TMi.resize(d_S*d_S);
- d_TMl.resize(d_S*d_S);
-
- for(int i=0;i<d_S*d_S;i++) {
- d_TMi[i] = -1; // no meaning
- d_TMl[i] = d_S; //infinity: you need at most S-1 steps
- if (i/d_S == i%d_S)
- d_TMl[i] = 0;
- }
-
- for(int s=0;s<d_S;s++) {
- bool done = false;
- int attempts = 0;
- while (done == false && attempts < d_S-1) {
- done = find_es(s);
- attempts ++;
- }
- if (done == false && d_S > 1) {
- //throw std::runtime_error ("fsm::generate_TM(): FSM appears to be disconnected\n");
- printf("fsm::generate_TM(): FSM appears to be disconnected\n");
- printf("state %d cannot be reached from all other states\n",s);
- }
- }
+ generate_PS_PI();
+ generate_TM();
+}
+
+//######################################################################
+//# generate the PS and PI tables for later use
+//######################################################################
+void fsm::generate_PS_PI()
+{
+ d_PS.resize(d_S);
+ d_PI.resize(d_S);
+
+ for (int i = 0; i < d_S; i++) {
+ d_PS[i].resize(d_I * d_S); // max possible size
+ d_PI[i].resize(d_I * d_S);
+ int j = 0;
+ for (int ii = 0; ii < d_S; ii++)
+ for (int jj = 0; jj < d_I; jj++) {
+ if (d_NS[ii * d_I + jj] != i)
+ continue;
+ d_PS[i][j] = ii;
+ d_PI[i][j] = jj;
+ j++;
+ }
+ d_PS[i].resize(j);
+ d_PI[i].resize(j);
}
-
- // find a path from any state to the ending state "es"
- bool
- fsm::find_es(int es)
- {
- bool done = true;
- for(int s=0;s<d_S;s++) {
- if(d_TMl[s*d_S+es] < d_S)
- continue;
- int minl=d_S;
- int mini=-1;
- for(int i=0;i<d_I;i++) {
- if( 1 + d_TMl[d_NS[s*d_I+i]*d_S+es] < minl) {
- minl = 1 + d_TMl[d_NS[s*d_I+i]*d_S+es];
- mini = i;
- }
- }
- if (mini != -1) {
- d_TMl[s*d_S+es]=minl;
- d_TMi[s*d_S+es]=mini;
- }
- else
- done = false;
- }
- return done;
+}
+
+//######################################################################
+//# generate the termination matrices TMl and TMi for later use
+//######################################################################
+void fsm::generate_TM()
+{
+ d_TMi.resize(d_S * d_S);
+ d_TMl.resize(d_S * d_S);
+
+ for (int i = 0; i < d_S * d_S; i++) {
+ d_TMi[i] = -1; // no meaning
+ d_TMl[i] = d_S; // infinity: you need at most S-1 steps
+ if (i / d_S == i % d_S)
+ d_TMl[i] = 0;
}
- //######################################################################
- //# generate trellis representation of FSM as an SVG file
- //######################################################################
- void
- fsm::write_trellis_svg(std::string filename, int number_stages)
- {
- std::ofstream trellis_fname (filename.c_str());
- if(!trellis_fname) {
- std::cout << "file not found " << std::endl ; exit(-1);
- }
- const int TRELLIS_Y_OFFSET = 30;
- const int TRELLIS_X_OFFSET = 20;
- const int STAGE_LABEL_Y_OFFSET = 25;
- const int STAGE_LABEL_X_OFFSET = 20;
- const int STATE_LABEL_Y_OFFSET = 30;
- const int STATE_LABEL_X_OFFSET = 5;
- const int STAGE_STATE_OFFSETS = 10;
- // std::cout << "################## BEGIN SVG TRELLIS PIC #####################" << std::endl;
- trellis_fname <<
- "<?xml version=\"1.0\" standalone=\"no\"?>"
- "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">"
- "<svg viewBox=\"0 0 200 200\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">"
- << std::endl;
-
- for(int stage_num = 0;stage_num < number_stages;stage_num ++) {
- // draw states
- for(int state_num = 0;state_num < d_S ; state_num ++ ) {
- trellis_fname << "<circle cx = \"" << stage_num * STAGE_STATE_OFFSETS + TRELLIS_X_OFFSET <<
- "\" cy = \"" << state_num * STAGE_STATE_OFFSETS + TRELLIS_Y_OFFSET << "\" r = \"1\"/>" << std::endl;
- //draw branches
- if(stage_num != number_stages-1) {
- for(int branch_num = 0;branch_num < d_I; branch_num++) {
- trellis_fname << "<line x1 =\"" << STAGE_STATE_OFFSETS * stage_num+ TRELLIS_X_OFFSET << "\" ";
- trellis_fname << "y1 =\"" << state_num * STAGE_STATE_OFFSETS + TRELLIS_Y_OFFSET<< "\" ";
- trellis_fname << "x2 =\"" << STAGE_STATE_OFFSETS *stage_num + STAGE_STATE_OFFSETS+ TRELLIS_X_OFFSET << "\" ";
- trellis_fname << "y2 =\"" << d_NS[d_I * state_num + branch_num] * STAGE_STATE_OFFSETS + TRELLIS_Y_OFFSET << "\" ";
- trellis_fname << " stroke-dasharray = \"3," << branch_num << "\" ";
- trellis_fname << " stroke = \"black\" stroke-width = \"0.3\"/>" << std::endl;
- }
- }
- }
- }
- // label the stages
- trellis_fname << "<g font-size = \"4\" font= \"times\" fill = \"black\">" << std::endl;
- for(int stage_num = 0;stage_num < number_stages ;stage_num ++) {
- trellis_fname << "<text x = \"" << stage_num * STAGE_STATE_OFFSETS + STAGE_LABEL_X_OFFSET <<
- "\" y = \"" << STAGE_LABEL_Y_OFFSET << "\" >" << std::endl;
- trellis_fname << stage_num << std::endl;
- trellis_fname << "</text>" << std::endl;
- }
- trellis_fname << "</g>" << std::endl;
-
- // label the states
- trellis_fname << "<g font-size = \"4\" font= \"times\" fill = \"black\">" << std::endl;
- for(int state_num = 0;state_num < d_S ; state_num ++) {
- trellis_fname << "<text y = \"" << state_num * STAGE_STATE_OFFSETS + STATE_LABEL_Y_OFFSET <<
- "\" x = \"" << STATE_LABEL_X_OFFSET << "\" >" << std::endl;
- trellis_fname << state_num << std::endl;
- trellis_fname << "</text>" << std::endl;
- }
- trellis_fname << "</g>" << std::endl;
-
- trellis_fname << "</svg>" << std::endl;
- // std::cout << "################## END SVG TRELLIS PIC ##################### " << std::endl;
- trellis_fname.close();
+ for (int s = 0; s < d_S; s++) {
+ bool done = false;
+ int attempts = 0;
+ while (done == false && attempts < d_S - 1) {
+ done = find_es(s);
+ attempts++;
+ }
+ if (done == false && d_S > 1) {
+ // throw std::runtime_error ("fsm::generate_TM(): FSM appears to be
+ // disconnected\n");
+ printf("fsm::generate_TM(): FSM appears to be disconnected\n");
+ printf("state %d cannot be reached from all other states\n", s);
+ }
}
-
- //######################################################################
- //# Write trellis specification to a text file,
- //# in the same format used when reading FSM files
- //######################################################################
- void
- fsm::write_fsm_txt(std::string filename)
- {
- std::ofstream trellis_fname (filename.c_str());
- if(!trellis_fname) {
- std::cout << "file not found " << std::endl ; exit(-1);
- }
- trellis_fname << d_I << ' ' << d_S << ' ' << d_O << std::endl;
- trellis_fname << std::endl;
- for(int i=0;i<d_S;i++) {
- for(int j=0;j<d_I;j++)
- trellis_fname << d_NS[i*d_I+j] << ' ';
- trellis_fname << std::endl;
- }
- trellis_fname << std::endl;
- for(int i=0;i<d_S;i++) {
- for(int j=0;j<d_I;j++)
- trellis_fname << d_OS[i*d_I+j] << ' ';
- trellis_fname << std::endl;
- }
- trellis_fname << std::endl;
- trellis_fname.close();
+}
+
+// find a path from any state to the ending state "es"
+bool fsm::find_es(int es)
+{
+ bool done = true;
+ for (int s = 0; s < d_S; s++) {
+ if (d_TMl[s * d_S + es] < d_S)
+ continue;
+ int minl = d_S;
+ int mini = -1;
+ for (int i = 0; i < d_I; i++) {
+ if (1 + d_TMl[d_NS[s * d_I + i] * d_S + es] < minl) {
+ minl = 1 + d_TMl[d_NS[s * d_I + i] * d_S + es];
+ mini = i;
+ }
+ }
+ if (mini != -1) {
+ d_TMl[s * d_S + es] = minl;
+ d_TMi[s * d_S + es] = mini;
+ } else
+ done = false;
+ }
+ return done;
+}
+
+//######################################################################
+//# generate trellis representation of FSM as an SVG file
+//######################################################################
+void fsm::write_trellis_svg(std::string filename, int number_stages)
+{
+ std::ofstream trellis_fname(filename.c_str());
+ if (!trellis_fname) {
+ std::cout << "file not found " << std::endl;
+ exit(-1);
+ }
+ const int TRELLIS_Y_OFFSET = 30;
+ const int TRELLIS_X_OFFSET = 20;
+ const int STAGE_LABEL_Y_OFFSET = 25;
+ const int STAGE_LABEL_X_OFFSET = 20;
+ const int STATE_LABEL_Y_OFFSET = 30;
+ const int STATE_LABEL_X_OFFSET = 5;
+ const int STAGE_STATE_OFFSETS = 10;
+ // std::cout << "################## BEGIN SVG TRELLIS PIC #####################" <<
+ // std::endl;
+ trellis_fname << "<?xml version=\"1.0\" standalone=\"no\"?>"
+ "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" "
+ "\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">"
+ "<svg viewBox=\"0 0 200 200\" version=\"1.1\" "
+ "xmlns=\"http://www.w3.org/2000/svg\">"
+ << std::endl;
+
+ for (int stage_num = 0; stage_num < number_stages; stage_num++) {
+ // draw states
+ for (int state_num = 0; state_num < d_S; state_num++) {
+ trellis_fname << "<circle cx = \""
+ << stage_num * STAGE_STATE_OFFSETS + TRELLIS_X_OFFSET
+ << "\" cy = \""
+ << state_num * STAGE_STATE_OFFSETS + TRELLIS_Y_OFFSET
+ << "\" r = \"1\"/>" << std::endl;
+ // draw branches
+ if (stage_num != number_stages - 1) {
+ for (int branch_num = 0; branch_num < d_I; branch_num++) {
+ trellis_fname << "<line x1 =\""
+ << STAGE_STATE_OFFSETS * stage_num + TRELLIS_X_OFFSET
+ << "\" ";
+ trellis_fname << "y1 =\""
+ << state_num * STAGE_STATE_OFFSETS + TRELLIS_Y_OFFSET
+ << "\" ";
+ trellis_fname << "x2 =\""
+ << STAGE_STATE_OFFSETS * stage_num +
+ STAGE_STATE_OFFSETS + TRELLIS_X_OFFSET
+ << "\" ";
+ trellis_fname
+ << "y2 =\""
+ << d_NS[d_I * state_num + branch_num] * STAGE_STATE_OFFSETS +
+ TRELLIS_Y_OFFSET
+ << "\" ";
+ trellis_fname << " stroke-dasharray = \"3," << branch_num << "\" ";
+ trellis_fname << " stroke = \"black\" stroke-width = \"0.3\"/>"
+ << std::endl;
+ }
+ }
+ }
+ }
+ // label the stages
+ trellis_fname << "<g font-size = \"4\" font= \"times\" fill = \"black\">"
+ << std::endl;
+ for (int stage_num = 0; stage_num < number_stages; stage_num++) {
+ trellis_fname << "<text x = \""
+ << stage_num * STAGE_STATE_OFFSETS + STAGE_LABEL_X_OFFSET
+ << "\" y = \"" << STAGE_LABEL_Y_OFFSET << "\" >" << std::endl;
+ trellis_fname << stage_num << std::endl;
+ trellis_fname << "</text>" << std::endl;
+ }
+ trellis_fname << "</g>" << std::endl;
+
+ // label the states
+ trellis_fname << "<g font-size = \"4\" font= \"times\" fill = \"black\">"
+ << std::endl;
+ for (int state_num = 0; state_num < d_S; state_num++) {
+ trellis_fname << "<text y = \""
+ << state_num * STAGE_STATE_OFFSETS + STATE_LABEL_Y_OFFSET
+ << "\" x = \"" << STATE_LABEL_X_OFFSET << "\" >" << std::endl;
+ trellis_fname << state_num << std::endl;
+ trellis_fname << "</text>" << std::endl;
+ }
+ trellis_fname << "</g>" << std::endl;
+
+ trellis_fname << "</svg>" << std::endl;
+ // std::cout << "################## END SVG TRELLIS PIC ##################### " <<
+ // std::endl;
+ trellis_fname.close();
+}
+
+//######################################################################
+//# Write trellis specification to a text file,
+//# in the same format used when reading FSM files
+//######################################################################
+void fsm::write_fsm_txt(std::string filename)
+{
+ std::ofstream trellis_fname(filename.c_str());
+ if (!trellis_fname) {
+ std::cout << "file not found " << std::endl;
+ exit(-1);
+ }
+ trellis_fname << d_I << ' ' << d_S << ' ' << d_O << std::endl;
+ trellis_fname << std::endl;
+ for (int i = 0; i < d_S; i++) {
+ for (int j = 0; j < d_I; j++)
+ trellis_fname << d_NS[i * d_I + j] << ' ';
+ trellis_fname << std::endl;
+ }
+ trellis_fname << std::endl;
+ for (int i = 0; i < d_S; i++) {
+ for (int j = 0; j < d_I; j++)
+ trellis_fname << d_OS[i * d_I + j] << ' ';
+ trellis_fname << std::endl;
}
+ trellis_fname << std::endl;
+ trellis_fname.close();
+}
- } /* namespace trellis */
+} /* namespace trellis */
} /* namespace gr */
diff --git a/gr-trellis/lib/interleaver.cc b/gr-trellis/lib/interleaver.cc
index 72bb296e5f..ae6fb05aa2 100644
--- a/gr-trellis/lib/interleaver.cc
+++ b/gr-trellis/lib/interleaver.cc
@@ -32,131 +32,132 @@
#include <gnuradio/xoroshiro128p.h>
namespace gr {
- namespace trellis {
-
- interleaver::interleaver()
- {
- d_K=0;
- d_INTER.resize(0);
- d_DEINTER.resize(0);
+namespace trellis {
+
+interleaver::interleaver()
+{
+ d_K = 0;
+ d_INTER.resize(0);
+ d_DEINTER.resize(0);
+}
+
+interleaver::interleaver(const interleaver& INTERLEAVER)
+{
+ d_K = INTERLEAVER.K();
+ d_INTER = INTERLEAVER.INTER();
+ d_DEINTER = INTERLEAVER.DEINTER();
+}
+
+interleaver::interleaver(unsigned int K, const std::vector<int>& INTER)
+{
+ d_K = K;
+ d_INTER = INTER;
+ d_DEINTER.resize(d_K);
+
+ // generate DEINTER table
+ for (unsigned int i = 0; i < d_K; i++) {
+ d_DEINTER[d_INTER[i]] = i;
}
-
- interleaver::interleaver(const interleaver &INTERLEAVER)
- {
- d_K=INTERLEAVER.K();
- d_INTER=INTERLEAVER.INTER();
- d_DEINTER=INTERLEAVER.DEINTER();
+}
+
+//######################################################################
+//# Read an INTERLEAVER specification from a file.
+//# Format (hopefully will become more flexible in the future...):
+//# K
+//# blank line
+//# list of space separated K integers from 0 to K-1 in appropriate order
+//# optional comments
+//######################################################################
+interleaver::interleaver(const char* name)
+{
+ FILE* interleaverfile;
+
+ if ((interleaverfile = fopen(name, "r")) == NULL)
+ throw std::runtime_error("file open error in interleaver()");
+ // printf("file open error in interleaver()\n");
+
+ if (fscanf(interleaverfile, "%d\n", &d_K) == EOF) {
+ if (ferror(interleaverfile) != 0)
+ throw std::runtime_error(
+ "interleaver::interleaver(const char *name): file read error\n");
}
- interleaver::interleaver(unsigned int K, const std::vector<int> &INTER)
- {
- d_K=K;
- d_INTER=INTER;
- d_DEINTER.resize(d_K);
+ d_INTER.resize(d_K);
+ d_DEINTER.resize(d_K);
- // generate DEINTER table
- for(unsigned int i = 0; i < d_K; i++) {
- d_DEINTER[d_INTER[i]]=i;
- }
+ for (unsigned int i = 0; i < d_K; i++) {
+ if (fscanf(interleaverfile, "%d", &(d_INTER[i])) == EOF) {
+ if (ferror(interleaverfile) != 0)
+ throw std::runtime_error(
+ "interleaver::interleaver(const char *name): file read error\n");
+ }
}
- //######################################################################
- //# Read an INTERLEAVER specification from a file.
- //# Format (hopefully will become more flexible in the future...):
- //# K
- //# blank line
- //# list of space separated K integers from 0 to K-1 in appropriate order
- //# optional comments
- //######################################################################
- interleaver::interleaver(const char *name)
- {
- FILE *interleaverfile;
-
- if((interleaverfile=fopen(name,"r")) == NULL)
- throw std::runtime_error ("file open error in interleaver()");
- //printf("file open error in interleaver()\n");
-
- if(fscanf(interleaverfile,"%d\n",&d_K) == EOF) {
- if(ferror(interleaverfile) != 0)
- throw std::runtime_error ("interleaver::interleaver(const char *name): file read error\n");
- }
-
- d_INTER.resize(d_K);
- d_DEINTER.resize(d_K);
-
- for (unsigned int i = 0; i < d_K; i++) {
- if (fscanf(interleaverfile, "%d", &(d_INTER[i])) == EOF) {
- if (ferror(interleaverfile) != 0)
- throw std::runtime_error(
- "interleaver::interleaver(const char *name): file read error\n");
- }
- }
-
- // generate DEINTER table
- for (unsigned int i = 0; i < d_K; i++) {
- d_DEINTER[d_INTER[i]] = i;
- }
-
- fclose(interleaverfile);
+ // generate DEINTER table
+ for (unsigned int i = 0; i < d_K; i++) {
+ d_DEINTER[d_INTER[i]] = i;
}
- //######################################################################
- //# Generate a random interleaver
- //######################################################################
- interleaver::interleaver(unsigned int K, int seed)
- {
- d_K=K;
- d_INTER.resize(d_K);
- d_DEINTER.resize(d_K);
-
- uint64_t rng_state[2];
- xoroshiro128p_seed(rng_state, seed);
- std::vector<int> tmp(d_K);
- unsigned char *bytes = reinterpret_cast<unsigned char*>(&tmp[0]);
-
- for(unsigned int i = 0; i < d_K; i += 8) {
- *(reinterpret_cast<uint64_t*>(bytes + i)) = xoroshiro128p_next(rng_state);
- }
- if(d_K % 8) {
- uint64_t randval = xoroshiro128p_next(rng_state);
- unsigned char *valptr = reinterpret_cast<unsigned char*>(&randval);
- for(unsigned int idx = (d_K / 8)*8; idx < d_K; ++idx) {
- bytes[idx] = *valptr++;
- }
- }
- for (unsigned int i = 0; i < d_K; i++) {
- d_INTER[i] = i;
- }
- quicksort_index <int> (tmp,d_INTER,0,d_K-1);
-
- // generate DEINTER table
- for(unsigned int i=0;i<d_K;i++) {
- d_DEINTER[d_INTER[i]]=i;
- }
+ fclose(interleaverfile);
+}
+
+//######################################################################
+//# Generate a random interleaver
+//######################################################################
+interleaver::interleaver(unsigned int K, int seed)
+{
+ d_K = K;
+ d_INTER.resize(d_K);
+ d_DEINTER.resize(d_K);
+
+ uint64_t rng_state[2];
+ xoroshiro128p_seed(rng_state, seed);
+ std::vector<int> tmp(d_K);
+ unsigned char* bytes = reinterpret_cast<unsigned char*>(&tmp[0]);
+
+ for (unsigned int i = 0; i < d_K; i += 8) {
+ *(reinterpret_cast<uint64_t*>(bytes + i)) = xoroshiro128p_next(rng_state);
}
-
- //######################################################################
- //# Write an INTERLEAVER specification to a file.
- //# Format
- //# K
- //# blank line
- //# list of space separated K integers from 0 to K-1 in appropriate order
- //# optional comments
- //######################################################################
- void
- interleaver::write_interleaver_txt(std::string filename)
- {
- std::ofstream interleaver_fname (filename.c_str());
- if(!interleaver_fname) {
- std::cout << "file not found " << std::endl ; exit(-1);
- }
- interleaver_fname << d_K << std::endl;
- interleaver_fname << std::endl;
- for(unsigned int i=0;i<d_K;i++)
- interleaver_fname << d_INTER[i] << ' ';
- interleaver_fname << std::endl;
- interleaver_fname.close();
+ if (d_K % 8) {
+ uint64_t randval = xoroshiro128p_next(rng_state);
+ unsigned char* valptr = reinterpret_cast<unsigned char*>(&randval);
+ for (unsigned int idx = (d_K / 8) * 8; idx < d_K; ++idx) {
+ bytes[idx] = *valptr++;
+ }
}
+ for (unsigned int i = 0; i < d_K; i++) {
+ d_INTER[i] = i;
+ }
+ quicksort_index<int>(tmp, d_INTER, 0, d_K - 1);
- } /* namespace trellis */
+ // generate DEINTER table
+ for (unsigned int i = 0; i < d_K; i++) {
+ d_DEINTER[d_INTER[i]] = i;
+ }
+}
+
+//######################################################################
+//# Write an INTERLEAVER specification to a file.
+//# Format
+//# K
+//# blank line
+//# list of space separated K integers from 0 to K-1 in appropriate order
+//# optional comments
+//######################################################################
+void interleaver::write_interleaver_txt(std::string filename)
+{
+ std::ofstream interleaver_fname(filename.c_str());
+ if (!interleaver_fname) {
+ std::cout << "file not found " << std::endl;
+ exit(-1);
+ }
+ interleaver_fname << d_K << std::endl;
+ interleaver_fname << std::endl;
+ for (unsigned int i = 0; i < d_K; i++)
+ interleaver_fname << d_INTER[i] << ' ';
+ interleaver_fname << std::endl;
+ interleaver_fname.close();
+}
+
+} /* namespace trellis */
} /* namespace gr */
diff --git a/gr-trellis/lib/metrics_impl.cc b/gr-trellis/lib/metrics_impl.cc
index 1ed6c69803..f3ebb4f5d3 100644
--- a/gr-trellis/lib/metrics_impl.cc
+++ b/gr-trellis/lib/metrics_impl.cc
@@ -32,104 +32,105 @@
#include <iostream>
namespace gr {
- namespace trellis {
-
- template <class T>
- typename metrics<T>::sptr
- metrics<T>::make(int O, int D, const std::vector<T> &TABLE,
- digital::trellis_metric_type_t TYPE)
- {
- return gnuradio::get_initial_sptr
- (new metrics_impl<T>(O,D,TABLE,TYPE));
- }
-
- template <class T>
- metrics_impl<T>::metrics_impl(int O, int D, const std::vector<T> &TABLE,
- digital::trellis_metric_type_t TYPE)
+namespace trellis {
+
+template <class T>
+typename metrics<T>::sptr metrics<T>::make(int O,
+ int D,
+ const std::vector<T>& TABLE,
+ digital::trellis_metric_type_t TYPE)
+{
+ return gnuradio::get_initial_sptr(new metrics_impl<T>(O, D, TABLE, TYPE));
+}
+
+template <class T>
+metrics_impl<T>::metrics_impl(int O,
+ int D,
+ const std::vector<T>& TABLE,
+ digital::trellis_metric_type_t TYPE)
: block("metrics",
- io_signature::make(1, -1, sizeof (T)),
- io_signature::make(1, -1, sizeof (float))),
- d_O(O), d_D(D), d_TYPE(TYPE), d_TABLE(TABLE)
- {
- this->set_relative_rate ((uint64_t)d_O, (uint64_t)d_D);
- this->set_output_multiple ((int)d_O);
- }
-
- template <class T>
- void metrics_impl<T>::set_O(int O)
- {
- gr::thread::scoped_lock guard(this->d_setlock);
- d_O = O;
- this->set_relative_rate ((uint64_t)d_O, (uint64_t)d_D);
- this->set_output_multiple ((int)d_O);
- }
-
- template <class T>
- void metrics_impl<T>::set_D(int D)
- {
- gr::thread::scoped_lock guard(this->d_setlock);
- d_D = D;
- this->set_relative_rate ((uint64_t)d_O, (uint64_t)d_D);
- }
-
- template <class T>
- void
- metrics_impl<T>::set_TYPE(digital::trellis_metric_type_t type)
- {
- gr::thread::scoped_lock guard(this->d_setlock);
- d_TYPE = type;
+ io_signature::make(1, -1, sizeof(T)),
+ io_signature::make(1, -1, sizeof(float))),
+ d_O(O),
+ d_D(D),
+ d_TYPE(TYPE),
+ d_TABLE(TABLE)
+{
+ this->set_relative_rate((uint64_t)d_O, (uint64_t)d_D);
+ this->set_output_multiple((int)d_O);
+}
+
+template <class T>
+void metrics_impl<T>::set_O(int O)
+{
+ gr::thread::scoped_lock guard(this->d_setlock);
+ d_O = O;
+ this->set_relative_rate((uint64_t)d_O, (uint64_t)d_D);
+ this->set_output_multiple((int)d_O);
+}
+
+template <class T>
+void metrics_impl<T>::set_D(int D)
+{
+ gr::thread::scoped_lock guard(this->d_setlock);
+ d_D = D;
+ this->set_relative_rate((uint64_t)d_O, (uint64_t)d_D);
+}
+
+template <class T>
+void metrics_impl<T>::set_TYPE(digital::trellis_metric_type_t type)
+{
+ gr::thread::scoped_lock guard(this->d_setlock);
+ d_TYPE = type;
+}
+
+template <class T>
+void metrics_impl<T>::set_TABLE(const std::vector<T>& table)
+{
+ gr::thread::scoped_lock guard(this->d_setlock);
+ d_TABLE = table;
+}
+
+template <class T>
+metrics_impl<T>::~metrics_impl()
+{
+}
+
+
+template <class T>
+void metrics_impl<T>::forecast(int noutput_items, gr_vector_int& ninput_items_required)
+{
+ int input_required = d_D * noutput_items / d_O;
+ unsigned ninputs = ninput_items_required.size();
+ for (unsigned int i = 0; i < ninputs; i++)
+ ninput_items_required[i] = input_required;
+}
+
+template <class T>
+int metrics_impl<T>::general_work(int noutput_items,
+ gr_vector_int& ninput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items)
+{
+ gr::thread::scoped_lock guard(this->d_setlock);
+ int nstreams = input_items.size();
+
+ for (int m = 0; m < nstreams; m++) {
+ const T* in = (T*)input_items[m];
+ float* out = (float*)output_items[m];
+
+ for (int i = 0; i < noutput_items / d_O; i++) {
+ calc_metric(d_O, d_D, d_TABLE, &(in[i * d_D]), &(out[i * d_O]), d_TYPE);
+ }
}
- template <class T>
- void
- metrics_impl<T>::set_TABLE(const std::vector<T> &table)
- {
- gr::thread::scoped_lock guard(this->d_setlock);
- d_TABLE = table;
- }
-
- template <class T>
- metrics_impl<T>::~metrics_impl()
- {
- }
-
-
- template <class T>
- void
- metrics_impl<T>::forecast(int noutput_items, gr_vector_int &ninput_items_required)
- {
- int input_required = d_D * noutput_items / d_O;
- unsigned ninputs = ninput_items_required.size();
- for(unsigned int i = 0; i < ninputs; i++)
- ninput_items_required[i] = input_required;
- }
-
- template <class T>
- int
- metrics_impl<T>::general_work(int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
- {
- gr::thread::scoped_lock guard(this->d_setlock);
- int nstreams = input_items.size();
-
- for(int m = 0; m < nstreams; m++) {
- const T *in = (T*)input_items[m];
- float *out = (float*)output_items[m];
-
- for(int i = 0; i < noutput_items / d_O ; i++) {
- calc_metric(d_O, d_D, d_TABLE,&(in[i*d_D]), &(out[i*d_O]), d_TYPE);
- }
- }
-
- this->consume_each(d_D * noutput_items / d_O);
- return noutput_items;
- }
+ this->consume_each(d_D * noutput_items / d_O);
+ return noutput_items;
+}
template class metrics<std::int16_t>;
template class metrics<std::int32_t>;
template class metrics<float>;
template class metrics<gr_complex>;
- } /* namespace trellis */
+} /* namespace trellis */
} /* namespace gr */
diff --git a/gr-trellis/lib/metrics_impl.h b/gr-trellis/lib/metrics_impl.h
index 95c5f44845..a6f6d8baa4 100644
--- a/gr-trellis/lib/metrics_impl.h
+++ b/gr-trellis/lib/metrics_impl.h
@@ -27,42 +27,43 @@
#include <gnuradio/trellis/metrics.h>
namespace gr {
- namespace trellis {
+namespace trellis {
-template<class T>
- class metrics_impl : public metrics<T>
- {
- private:
- int d_O;
- int d_D;
- digital::trellis_metric_type_t d_TYPE;
- std::vector<T> d_TABLE;
+template <class T>
+class metrics_impl : public metrics<T>
+{
+private:
+ int d_O;
+ int d_D;
+ digital::trellis_metric_type_t d_TYPE;
+ std::vector<T> d_TABLE;
- public:
- metrics_impl(int O, int D, const std::vector<T> &TABLE,
- digital::trellis_metric_type_t TYPE);
- ~metrics_impl();
+public:
+ metrics_impl(int O,
+ int D,
+ const std::vector<T>& TABLE,
+ digital::trellis_metric_type_t TYPE);
+ ~metrics_impl();
- int O() const { return d_O; }
- int D() const { return d_D; }
- digital::trellis_metric_type_t TYPE() const { return d_TYPE; }
- std::vector<T> TABLE() const { return d_TABLE; }
+ int O() const { return d_O; }
+ int D() const { return d_D; }
+ digital::trellis_metric_type_t TYPE() const { return d_TYPE; }
+ std::vector<T> TABLE() const { return d_TABLE; }
- void set_O(int O);
- void set_D(int D);
- void set_TYPE(digital::trellis_metric_type_t type);
- void set_TABLE(const std::vector<T> &table);
+ void set_O(int O);
+ void set_D(int D);
+ void set_TYPE(digital::trellis_metric_type_t type);
+ void set_TABLE(const std::vector<T>& table);
- void forecast(int noutput_items,
- gr_vector_int &ninput_items_required);
+ void forecast(int noutput_items, gr_vector_int& ninput_items_required);
- int general_work(int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
- };
+ int general_work(int noutput_items,
+ gr_vector_int& ninput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items);
+};
- } /* namespace trellis */
+} /* namespace trellis */
} /* namespace gr */
#endif /* METRICS_IMPL_H */
diff --git a/gr-trellis/lib/pccc_decoder_blk_impl.cc b/gr-trellis/lib/pccc_decoder_blk_impl.cc
index b001998416..d6c817685d 100644
--- a/gr-trellis/lib/pccc_decoder_blk_impl.cc
+++ b/gr-trellis/lib/pccc_decoder_blk_impl.cc
@@ -31,95 +31,114 @@
#include <gnuradio/trellis/core_algorithms.h>
namespace gr {
- namespace trellis {
+namespace trellis {
- template <class T>
- typename pccc_decoder_blk<T>::sptr
- pccc_decoder_blk<T>::make(const fsm &FSM1, int ST10, int ST1K,
- const fsm &FSM2, int ST20, int ST2K,
- const interleaver &INTERLEAVER,
- int blocklength,
- int repetitions,
- siso_type_t SISO_TYPE)
- {
- return gnuradio::get_initial_sptr
- (new pccc_decoder_blk_impl<T>(FSM1, ST10, ST1K,
- FSM2, ST20, ST2K,
- INTERLEAVER,
- blocklength,
- repetitions,
- SISO_TYPE));
- }
+template <class T>
+typename pccc_decoder_blk<T>::sptr
+pccc_decoder_blk<T>::make(const fsm& FSM1,
+ int ST10,
+ int ST1K,
+ const fsm& FSM2,
+ int ST20,
+ int ST2K,
+ const interleaver& INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ siso_type_t SISO_TYPE)
+{
+ return gnuradio::get_initial_sptr(new pccc_decoder_blk_impl<T>(FSM1,
+ ST10,
+ ST1K,
+ FSM2,
+ ST20,
+ ST2K,
+ INTERLEAVER,
+ blocklength,
+ repetitions,
+ SISO_TYPE));
+}
- template <class T>
- pccc_decoder_blk_impl<T>::pccc_decoder_blk_impl(const fsm &FSM1, int ST10, int ST1K,
- const fsm &FSM2, int ST20, int ST2K,
- const interleaver &INTERLEAVER,
- int blocklength,
- int repetitions,
- siso_type_t SISO_TYPE)
+template <class T>
+pccc_decoder_blk_impl<T>::pccc_decoder_blk_impl(const fsm& FSM1,
+ int ST10,
+ int ST1K,
+ const fsm& FSM2,
+ int ST20,
+ int ST2K,
+ const interleaver& INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ siso_type_t SISO_TYPE)
: block("pccc_decoder_blk",
- io_signature::make(1, 1, sizeof(float)),
- io_signature::make(1, 1, sizeof(T))),
- d_FSM1(FSM1), d_ST10(ST10), d_ST1K(ST1K),
- d_FSM2(FSM2), d_ST20(ST20), d_ST2K(ST2K),
+ io_signature::make(1, 1, sizeof(float)),
+ io_signature::make(1, 1, sizeof(T))),
+ d_FSM1(FSM1),
+ d_ST10(ST10),
+ d_ST1K(ST1K),
+ d_FSM2(FSM2),
+ d_ST20(ST20),
+ d_ST2K(ST2K),
d_INTERLEAVER(INTERLEAVER),
d_blocklength(blocklength),
d_repetitions(repetitions),
d_SISO_TYPE(SISO_TYPE)
- {
- this->set_relative_rate (1, (uint64_t)(d_FSM1.O() * d_FSM2.O()));
- this->set_output_multiple (d_blocklength);
- }
-
- template <class T>
- pccc_decoder_blk_impl<T>::~pccc_decoder_blk_impl()
- {
- }
+{
+ this->set_relative_rate(1, (uint64_t)(d_FSM1.O() * d_FSM2.O()));
+ this->set_output_multiple(d_blocklength);
+}
- template <class T>
- void
- pccc_decoder_blk_impl<T>::forecast(int noutput_items,
- gr_vector_int &ninput_items_required)
- {
- int input_required = d_FSM1.O() * d_FSM2.O() * noutput_items;
- ninput_items_required[0] = input_required;
- }
+template <class T>
+pccc_decoder_blk_impl<T>::~pccc_decoder_blk_impl()
+{
+}
- //===========================================================
+template <class T>
+void pccc_decoder_blk_impl<T>::forecast(int noutput_items,
+ gr_vector_int& ninput_items_required)
+{
+ int input_required = d_FSM1.O() * d_FSM2.O() * noutput_items;
+ ninput_items_required[0] = input_required;
+}
- template <class T>
- int
- pccc_decoder_blk_impl<T>::general_work(int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
- {
- int nblocks = noutput_items / d_blocklength;
+//===========================================================
- float (*p2min)(float, float) = NULL;
- if(d_SISO_TYPE == TRELLIS_MIN_SUM)
- p2min = &min;
- else if(d_SISO_TYPE == TRELLIS_SUM_PRODUCT)
- p2min = &min_star;
+template <class T>
+int pccc_decoder_blk_impl<T>::general_work(int noutput_items,
+ gr_vector_int& ninput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items)
+{
+ int nblocks = noutput_items / d_blocklength;
- const float *in = (const float *) input_items[0];
- T *out = (T *) output_items[0];
- for(int n=0;n<nblocks;n++) {
- pccc_decoder(d_FSM1, d_ST10, d_ST1K,
- d_FSM2, d_ST20, d_ST2K,
- d_INTERLEAVER, d_blocklength, d_repetitions,
- p2min,
- &(in[n*d_blocklength*d_FSM1.O()*d_FSM2.O()]),
- &(out[n*d_blocklength]));
- }
+ float (*p2min)(float, float) = NULL;
+ if (d_SISO_TYPE == TRELLIS_MIN_SUM)
+ p2min = &min;
+ else if (d_SISO_TYPE == TRELLIS_SUM_PRODUCT)
+ p2min = &min_star;
- this->consume_each(d_FSM1.O() * d_FSM2.O() * noutput_items);
- return noutput_items;
+ const float* in = (const float*)input_items[0];
+ T* out = (T*)output_items[0];
+ for (int n = 0; n < nblocks; n++) {
+ pccc_decoder(d_FSM1,
+ d_ST10,
+ d_ST1K,
+ d_FSM2,
+ d_ST20,
+ d_ST2K,
+ d_INTERLEAVER,
+ d_blocklength,
+ d_repetitions,
+ p2min,
+ &(in[n * d_blocklength * d_FSM1.O() * d_FSM2.O()]),
+ &(out[n * d_blocklength]));
}
+ this->consume_each(d_FSM1.O() * d_FSM2.O() * noutput_items);
+ return noutput_items;
+}
+
template class pccc_decoder_blk<std::uint8_t>;
template class pccc_decoder_blk<std::int16_t>;
template class pccc_decoder_blk<std::int32_t>;
- } /* namespace trellis */
+} /* namespace trellis */
} /* namespace gr */
diff --git a/gr-trellis/lib/pccc_decoder_blk_impl.h b/gr-trellis/lib/pccc_decoder_blk_impl.h
index ed4e2d24a6..047951f02f 100644
--- a/gr-trellis/lib/pccc_decoder_blk_impl.h
+++ b/gr-trellis/lib/pccc_decoder_blk_impl.h
@@ -27,54 +27,57 @@
#include <gnuradio/trellis/pccc_decoder_blk.h>
namespace gr {
- namespace trellis {
+namespace trellis {
-template<class T>
- class pccc_decoder_blk_impl : public pccc_decoder_blk<T>
- {
- private:
- fsm d_FSM1;
- int d_ST10;
- int d_ST1K;
- fsm d_FSM2;
- int d_ST20;
- int d_ST2K;
- interleaver d_INTERLEAVER;
- int d_blocklength;
- int d_repetitions;
- siso_type_t d_SISO_TYPE;
- std::vector<float> d_buffer;
+template <class T>
+class pccc_decoder_blk_impl : public pccc_decoder_blk<T>
+{
+private:
+ fsm d_FSM1;
+ int d_ST10;
+ int d_ST1K;
+ fsm d_FSM2;
+ int d_ST20;
+ int d_ST2K;
+ interleaver d_INTERLEAVER;
+ int d_blocklength;
+ int d_repetitions;
+ siso_type_t d_SISO_TYPE;
+ std::vector<float> d_buffer;
- public:
- pccc_decoder_blk_impl(const fsm &FSM1, int ST10, int ST1K,
- const fsm &FSM2, int ST20, int ST2K,
- const interleaver &INTERLEAVER,
- int blocklength,
- int repetitions,
- siso_type_t SISO_TYPE);
- ~pccc_decoder_blk_impl();
+public:
+ pccc_decoder_blk_impl(const fsm& FSM1,
+ int ST10,
+ int ST1K,
+ const fsm& FSM2,
+ int ST20,
+ int ST2K,
+ const interleaver& INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ siso_type_t SISO_TYPE);
+ ~pccc_decoder_blk_impl();
- fsm FSM1() const { return d_FSM1; }
- fsm FSM2() const { return d_FSM2; }
- int ST10() const { return d_ST10; }
- int ST1K() const { return d_ST1K; }
- int ST20() const { return d_ST20; }
- int ST2K() const { return d_ST2K; }
- interleaver INTERLEAVER() const { return d_INTERLEAVER; }
- int blocklength() const { return d_blocklength; }
- int repetitions() const { return d_repetitions; }
- siso_type_t SISO_TYPE() const { return d_SISO_TYPE; }
+ fsm FSM1() const { return d_FSM1; }
+ fsm FSM2() const { return d_FSM2; }
+ int ST10() const { return d_ST10; }
+ int ST1K() const { return d_ST1K; }
+ int ST20() const { return d_ST20; }
+ int ST2K() const { return d_ST2K; }
+ interleaver INTERLEAVER() const { return d_INTERLEAVER; }
+ int blocklength() const { return d_blocklength; }
+ int repetitions() const { return d_repetitions; }
+ siso_type_t SISO_TYPE() const { return d_SISO_TYPE; }
- void forecast(int noutput_items,
- gr_vector_int &ninput_items_required);
+ void forecast(int noutput_items, gr_vector_int& ninput_items_required);
- int general_work(int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
- };
+ int general_work(int noutput_items,
+ gr_vector_int& ninput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items);
+};
- } /* namespace trellis */
+} /* namespace trellis */
} /* namespace gr */
#endif /* PCCC_DECODER_BLK_IMPL_H */
diff --git a/gr-trellis/lib/pccc_decoder_combined_blk_impl.cc b/gr-trellis/lib/pccc_decoder_combined_blk_impl.cc
index a1e0772ab8..b8a93d9118 100644
--- a/gr-trellis/lib/pccc_decoder_combined_blk_impl.cc
+++ b/gr-trellis/lib/pccc_decoder_combined_blk_impl.cc
@@ -30,43 +30,67 @@
#include <gnuradio/trellis/core_algorithms.h>
namespace gr {
- namespace trellis {
+namespace trellis {
- template <class IN_T,class OUT_T>
- typename pccc_decoder_combined_blk<IN_T,OUT_T>::sptr
- pccc_decoder_combined_blk<IN_T,OUT_T>::make(const fsm &FSMo, int STo0, int SToK,
- const fsm &FSMi, int STi0, int STiK,
- const interleaver &INTERLEAVER,
- int blocklength,
- int repetitions,
- siso_type_t SISO_TYPE,
- int D,
- const std::vector<IN_T> &TABLE,
- digital::trellis_metric_type_t METRIC_TYPE,
- float scaling)
- {
- return gnuradio::get_initial_sptr
- (new pccc_decoder_combined_blk_impl<IN_T,OUT_T>(FSMo, STo0, SToK, FSMi, STi0, STiK,
- INTERLEAVER, blocklength, repetitions,
- SISO_TYPE, D, TABLE,METRIC_TYPE, scaling));
- }
+template <class IN_T, class OUT_T>
+typename pccc_decoder_combined_blk<IN_T, OUT_T>::sptr
+pccc_decoder_combined_blk<IN_T, OUT_T>::make(const fsm& FSMo,
+ int STo0,
+ int SToK,
+ const fsm& FSMi,
+ int STi0,
+ int STiK,
+ const interleaver& INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ siso_type_t SISO_TYPE,
+ int D,
+ const std::vector<IN_T>& TABLE,
+ digital::trellis_metric_type_t METRIC_TYPE,
+ float scaling)
+{
+ return gnuradio::get_initial_sptr(
+ new pccc_decoder_combined_blk_impl<IN_T, OUT_T>(FSMo,
+ STo0,
+ SToK,
+ FSMi,
+ STi0,
+ STiK,
+ INTERLEAVER,
+ blocklength,
+ repetitions,
+ SISO_TYPE,
+ D,
+ TABLE,
+ METRIC_TYPE,
+ scaling));
+}
- template <class IN_T,class OUT_T>
- pccc_decoder_combined_blk_impl<IN_T,OUT_T>::pccc_decoder_combined_blk_impl(const fsm &FSMo, int STo0, int SToK,
- const fsm &FSMi, int STi0, int STiK,
- const interleaver &INTERLEAVER,
- int blocklength,
- int repetitions,
- siso_type_t SISO_TYPE,
- int D,
- const std::vector<IN_T> &TABLE,
- digital::trellis_metric_type_t METRIC_TYPE,
- float scaling)
+template <class IN_T, class OUT_T>
+pccc_decoder_combined_blk_impl<IN_T, OUT_T>::pccc_decoder_combined_blk_impl(
+ const fsm& FSMo,
+ int STo0,
+ int SToK,
+ const fsm& FSMi,
+ int STi0,
+ int STiK,
+ const interleaver& INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ siso_type_t SISO_TYPE,
+ int D,
+ const std::vector<IN_T>& TABLE,
+ digital::trellis_metric_type_t METRIC_TYPE,
+ float scaling)
: block("pccc_decoder_combined_blk<IN_T,OUT_T>",
- io_signature::make(1, 1, sizeof(IN_T)),
- io_signature::make(1, 1, sizeof(OUT_T))),
- d_FSMo(FSMo), d_STo0(STo0), d_SToK(SToK),
- d_FSMi(FSMi), d_STi0(STi0), d_STiK(STiK),
+ io_signature::make(1, 1, sizeof(IN_T)),
+ io_signature::make(1, 1, sizeof(OUT_T))),
+ d_FSMo(FSMo),
+ d_STo0(STo0),
+ d_SToK(SToK),
+ d_FSMi(FSMi),
+ d_STi0(STi0),
+ d_STiK(STiK),
d_INTERLEAVER(INTERLEAVER),
d_blocklength(blocklength),
d_repetitions(repetitions),
@@ -75,76 +99,81 @@ namespace gr {
d_TABLE(TABLE),
d_METRIC_TYPE(METRIC_TYPE),
d_scaling(scaling)
- {
- assert(d_FSMo.I() == d_FSMi.I());
- this->set_relative_rate (1, (uint64_t) d_D);
- this->set_output_multiple (d_blocklength);
- }
+{
+ assert(d_FSMo.I() == d_FSMi.I());
+ this->set_relative_rate(1, (uint64_t)d_D);
+ this->set_output_multiple(d_blocklength);
+}
- template <class IN_T,class OUT_T>
- pccc_decoder_combined_blk_impl<IN_T,OUT_T>::~pccc_decoder_combined_blk_impl()
- {
- }
+template <class IN_T, class OUT_T>
+pccc_decoder_combined_blk_impl<IN_T, OUT_T>::~pccc_decoder_combined_blk_impl()
+{
+}
- template <class IN_T,class OUT_T>
- void
- pccc_decoder_combined_blk_impl<IN_T,OUT_T>::set_scaling(float scaling)
- {
- gr::thread::scoped_lock guard(this->d_setlock);
- d_scaling = scaling;
- }
+template <class IN_T, class OUT_T>
+void pccc_decoder_combined_blk_impl<IN_T, OUT_T>::set_scaling(float scaling)
+{
+ gr::thread::scoped_lock guard(this->d_setlock);
+ d_scaling = scaling;
+}
- template <class IN_T,class OUT_T>
- void
- pccc_decoder_combined_blk_impl<IN_T,OUT_T>::forecast(int noutput_items,
- gr_vector_int &ninput_items_required)
- {
- int input_required = d_D * noutput_items;
- ninput_items_required[0] = input_required;
- }
-
- //===========================================================
+template <class IN_T, class OUT_T>
+void pccc_decoder_combined_blk_impl<IN_T, OUT_T>::forecast(
+ int noutput_items, gr_vector_int& ninput_items_required)
+{
+ int input_required = d_D * noutput_items;
+ ninput_items_required[0] = input_required;
+}
- template <class IN_T,class OUT_T>
- int
- pccc_decoder_combined_blk_impl<IN_T,OUT_T>::general_work(int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
- {
- gr::thread::scoped_lock guard(this->d_setlock);
- int nblocks = noutput_items / d_blocklength;
+//===========================================================
- float (*p2min)(float, float) = NULL;
- if(d_SISO_TYPE == TRELLIS_MIN_SUM)
- p2min = &min;
- else if(d_SISO_TYPE == TRELLIS_SUM_PRODUCT)
- p2min = &min_star;
+template <class IN_T, class OUT_T>
+int pccc_decoder_combined_blk_impl<IN_T, OUT_T>::general_work(
+ int noutput_items,
+ gr_vector_int& ninput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items)
+{
+ gr::thread::scoped_lock guard(this->d_setlock);
+ int nblocks = noutput_items / d_blocklength;
- const IN_T *in = (const IN_T *) input_items[0];
- OUT_T *out = (OUT_T *) output_items[0];
- for (int n=0;n<nblocks;n++) {
- pccc_decoder_combined(d_FSMo, d_STo0, d_SToK,
- d_FSMi, d_STi0, d_STiK,
- d_INTERLEAVER, d_blocklength, d_repetitions,
- p2min,
- d_D,d_TABLE,
- d_METRIC_TYPE,
- d_scaling,
- &(in[n*d_blocklength*d_D]),
- &(out[n*d_blocklength]));
- }
+ float (*p2min)(float, float) = NULL;
+ if (d_SISO_TYPE == TRELLIS_MIN_SUM)
+ p2min = &min;
+ else if (d_SISO_TYPE == TRELLIS_SUM_PRODUCT)
+ p2min = &min_star;
- this->consume_each(d_D * noutput_items);
- return noutput_items;
+ const IN_T* in = (const IN_T*)input_items[0];
+ OUT_T* out = (OUT_T*)output_items[0];
+ for (int n = 0; n < nblocks; n++) {
+ pccc_decoder_combined(d_FSMo,
+ d_STo0,
+ d_SToK,
+ d_FSMi,
+ d_STi0,
+ d_STiK,
+ d_INTERLEAVER,
+ d_blocklength,
+ d_repetitions,
+ p2min,
+ d_D,
+ d_TABLE,
+ d_METRIC_TYPE,
+ d_scaling,
+ &(in[n * d_blocklength * d_D]),
+ &(out[n * d_blocklength]));
}
- template class pccc_decoder_combined_blk<float, std::uint8_t>;
- template class pccc_decoder_combined_blk<float, std::int16_t>;
- template class pccc_decoder_combined_blk<float, std::int32_t>;
- template class pccc_decoder_combined_blk<gr_complex, std::uint8_t>;
- template class pccc_decoder_combined_blk<gr_complex, std::int16_t>;
- template class pccc_decoder_combined_blk<gr_complex, std::int32_t>;
+
+ this->consume_each(d_D * noutput_items);
+ return noutput_items;
+}
+template class pccc_decoder_combined_blk<float, std::uint8_t>;
+template class pccc_decoder_combined_blk<float, std::int16_t>;
+template class pccc_decoder_combined_blk<float, std::int32_t>;
+template class pccc_decoder_combined_blk<gr_complex, std::uint8_t>;
+template class pccc_decoder_combined_blk<gr_complex, std::int16_t>;
+template class pccc_decoder_combined_blk<gr_complex, std::int32_t>;
- } /* namespace trellis */
+} /* namespace trellis */
} /* namespace gr */
diff --git a/gr-trellis/lib/pccc_decoder_combined_blk_impl.h b/gr-trellis/lib/pccc_decoder_combined_blk_impl.h
index 544a965607..3a25fad4b1 100644
--- a/gr-trellis/lib/pccc_decoder_combined_blk_impl.h
+++ b/gr-trellis/lib/pccc_decoder_combined_blk_impl.h
@@ -26,67 +26,70 @@
#include <gnuradio/trellis/pccc_decoder_combined_blk.h>
namespace gr {
- namespace trellis {
+namespace trellis {
- template <class IN_T,class OUT_T>
- class pccc_decoder_combined_blk_impl : public pccc_decoder_combined_blk<IN_T,OUT_T>
- {
- private:
- fsm d_FSMo;
- int d_STo0;
- int d_SToK;
- fsm d_FSMi;
- int d_STi0;
- int d_STiK;
- interleaver d_INTERLEAVER;
- int d_blocklength;
- int d_repetitions;
- siso_type_t d_SISO_TYPE;
- int d_D;
- std::vector<IN_T> d_TABLE;
- digital::trellis_metric_type_t d_METRIC_TYPE;
- float d_scaling;
- std::vector<float> d_buffer;
+template <class IN_T, class OUT_T>
+class pccc_decoder_combined_blk_impl : public pccc_decoder_combined_blk<IN_T, OUT_T>
+{
+private:
+ fsm d_FSMo;
+ int d_STo0;
+ int d_SToK;
+ fsm d_FSMi;
+ int d_STi0;
+ int d_STiK;
+ interleaver d_INTERLEAVER;
+ int d_blocklength;
+ int d_repetitions;
+ siso_type_t d_SISO_TYPE;
+ int d_D;
+ std::vector<IN_T> d_TABLE;
+ digital::trellis_metric_type_t d_METRIC_TYPE;
+ float d_scaling;
+ std::vector<float> d_buffer;
- public:
- pccc_decoder_combined_blk_impl(const fsm &FSMo, int STo0, int SToK,
- const fsm &FSMi, int STi0, int STiK,
- const interleaver &INTERLEAVER,
- int blocklength,
- int repetitions,
- siso_type_t SISO_TYPE,
- int D,
- const std::vector<IN_T> &TABLE,
- digital::trellis_metric_type_t METRIC_TYPE,
- float scaling);
- ~pccc_decoder_combined_blk_impl();
+public:
+ pccc_decoder_combined_blk_impl(const fsm& FSMo,
+ int STo0,
+ int SToK,
+ const fsm& FSMi,
+ int STi0,
+ int STiK,
+ const interleaver& INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ siso_type_t SISO_TYPE,
+ int D,
+ const std::vector<IN_T>& TABLE,
+ digital::trellis_metric_type_t METRIC_TYPE,
+ float scaling);
+ ~pccc_decoder_combined_blk_impl();
- fsm FSM1() const { return d_FSMo; }
- fsm FSM2() const { return d_FSMi; }
- int ST10() const { return d_STo0; }
- int ST1K() const { return d_SToK; }
- int ST20() const { return d_STi0; }
- int ST2K() const { return d_STiK; }
- interleaver INTERLEAVER() const { return d_INTERLEAVER; }
- int blocklength() const { return d_blocklength; }
- int repetitions() const { return d_repetitions; }
- int D() const { return d_D; }
- std::vector<IN_T> TABLE() const { return d_TABLE; }
- digital::trellis_metric_type_t METRIC_TYPE() const { return d_METRIC_TYPE; }
- siso_type_t SISO_TYPE() const { return d_SISO_TYPE; }
- float scaling() const { return d_scaling; }
- void set_scaling(float scaling);
+ fsm FSM1() const { return d_FSMo; }
+ fsm FSM2() const { return d_FSMi; }
+ int ST10() const { return d_STo0; }
+ int ST1K() const { return d_SToK; }
+ int ST20() const { return d_STi0; }
+ int ST2K() const { return d_STiK; }
+ interleaver INTERLEAVER() const { return d_INTERLEAVER; }
+ int blocklength() const { return d_blocklength; }
+ int repetitions() const { return d_repetitions; }
+ int D() const { return d_D; }
+ std::vector<IN_T> TABLE() const { return d_TABLE; }
+ digital::trellis_metric_type_t METRIC_TYPE() const { return d_METRIC_TYPE; }
+ siso_type_t SISO_TYPE() const { return d_SISO_TYPE; }
+ float scaling() const { return d_scaling; }
+ void set_scaling(float scaling);
- void forecast(int noutput_items,
- gr_vector_int &ninput_items_required);
+ void forecast(int noutput_items, gr_vector_int& ninput_items_required);
- int general_work(int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
- };
+ int general_work(int noutput_items,
+ gr_vector_int& ninput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items);
+};
- } /* namespace trellis */
+} /* namespace trellis */
} /* namespace gr */
#endif /* PCCC_DECODER_COMBINED_BLK_IMPL_H */
diff --git a/gr-trellis/lib/pccc_encoder_impl.cc b/gr-trellis/lib/pccc_encoder_impl.cc
index 2804f4b39c..f6ee50b65e 100644
--- a/gr-trellis/lib/pccc_encoder_impl.cc
+++ b/gr-trellis/lib/pccc_encoder_impl.cc
@@ -29,71 +29,76 @@
#include <iostream>
namespace gr {
- namespace trellis {
+namespace trellis {
- template <class IN_T, class OUT_T>
- typename pccc_encoder<IN_T,OUT_T>::sptr
- pccc_encoder<IN_T,OUT_T>::make(const fsm &FSM1, int ST1,
- const fsm &FSM2, int ST2,
- const interleaver &INTERLEAVER,
- int blocklength)
- {
- return gnuradio::get_initial_sptr
- (new pccc_encoder_impl<IN_T,OUT_T>(FSM1, ST1, FSM2, ST2, INTERLEAVER, blocklength));
- }
+template <class IN_T, class OUT_T>
+typename pccc_encoder<IN_T, OUT_T>::sptr
+pccc_encoder<IN_T, OUT_T>::make(const fsm& FSM1,
+ int ST1,
+ const fsm& FSM2,
+ int ST2,
+ const interleaver& INTERLEAVER,
+ int blocklength)
+{
+ return gnuradio::get_initial_sptr(new pccc_encoder_impl<IN_T, OUT_T>(
+ FSM1, ST1, FSM2, ST2, INTERLEAVER, blocklength));
+}
- template <class IN_T, class OUT_T>
- pccc_encoder_impl<IN_T,OUT_T>::pccc_encoder_impl(const fsm &FSM1, int ST1,
- const fsm &FSM2, int ST2,
- const interleaver &INTERLEAVER,
- int blocklength)
+template <class IN_T, class OUT_T>
+pccc_encoder_impl<IN_T, OUT_T>::pccc_encoder_impl(const fsm& FSM1,
+ int ST1,
+ const fsm& FSM2,
+ int ST2,
+ const interleaver& INTERLEAVER,
+ int blocklength)
: sync_block("pccc_encoder<IN_T,OUT_T>",
- io_signature::make(1, 1, sizeof(IN_T)),
- io_signature::make(1, 1, sizeof(OUT_T))),
- d_FSM1(FSM1), d_ST1(ST1),
- d_FSM2(FSM2), d_ST2(ST2),
+ io_signature::make(1, 1, sizeof(IN_T)),
+ io_signature::make(1, 1, sizeof(OUT_T))),
+ d_FSM1(FSM1),
+ d_ST1(ST1),
+ d_FSM2(FSM2),
+ d_ST2(ST2),
d_INTERLEAVER(INTERLEAVER),
d_blocklength(blocklength)
- {
- assert(d_FSM1.I() == d_FSM2.I());
- this->set_output_multiple(d_blocklength);
- d_buffer.resize(d_blocklength);
- }
+{
+ assert(d_FSM1.I() == d_FSM2.I());
+ this->set_output_multiple(d_blocklength);
+ d_buffer.resize(d_blocklength);
+}
- template <class IN_T, class OUT_T>
- pccc_encoder_impl<IN_T,OUT_T>::~pccc_encoder_impl()
- {
- }
+template <class IN_T, class OUT_T>
+pccc_encoder_impl<IN_T, OUT_T>::~pccc_encoder_impl()
+{
+}
- template <class IN_T, class OUT_T>
- int
- pccc_encoder_impl<IN_T,OUT_T>::work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
- {
- for(int b = 0 ; b<noutput_items/d_blocklength; b++) {
- const IN_T *in = (const IN_T*)input_items[0]+b*d_blocklength;
- OUT_T *out = (OUT_T*)output_items[0]+b*d_blocklength;
+template <class IN_T, class OUT_T>
+int pccc_encoder_impl<IN_T, OUT_T>::work(int noutput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items)
+{
+ for (int b = 0; b < noutput_items / d_blocklength; b++) {
+ const IN_T* in = (const IN_T*)input_items[0] + b * d_blocklength;
+ OUT_T* out = (OUT_T*)output_items[0] + b * d_blocklength;
- int ST1_tmp = d_ST1;
- int ST2_tmp = d_ST2;
- for(int i = 0; i < d_blocklength; i++) {
- int k = d_INTERLEAVER.INTER()[i];
- int o1 = d_FSM1.OS()[ST1_tmp*d_FSM1.I()+in[i]];
- ST1_tmp = (int) d_FSM1.NS()[ST1_tmp*d_FSM1.I()+in[i]];
- int o2 = d_FSM2.OS()[ST2_tmp*d_FSM2.I()+in[k]];
- ST2_tmp = (int) d_FSM2.NS()[ST2_tmp*d_FSM2.I()+in[k]];
- out[i] = (OUT_T) (o1*d_FSM2.O() + o2);
- }
- }
- return noutput_items;
+ int ST1_tmp = d_ST1;
+ int ST2_tmp = d_ST2;
+ for (int i = 0; i < d_blocklength; i++) {
+ int k = d_INTERLEAVER.INTER()[i];
+ int o1 = d_FSM1.OS()[ST1_tmp * d_FSM1.I() + in[i]];
+ ST1_tmp = (int)d_FSM1.NS()[ST1_tmp * d_FSM1.I() + in[i]];
+ int o2 = d_FSM2.OS()[ST2_tmp * d_FSM2.I() + in[k]];
+ ST2_tmp = (int)d_FSM2.NS()[ST2_tmp * d_FSM2.I() + in[k]];
+ out[i] = (OUT_T)(o1 * d_FSM2.O() + o2);
+ }
}
- template class pccc_encoder<std::uint8_t, std::uint8_t>;
- template class pccc_encoder<std::uint8_t, std::int16_t>;
- template class pccc_encoder<std::uint8_t, std::int32_t>;
- template class pccc_encoder<std::int16_t, std::int16_t>;
- template class pccc_encoder<std::int16_t, std::int32_t>;
- template class pccc_encoder<std::int32_t, std::int32_t>;
+ return noutput_items;
+}
+template class pccc_encoder<std::uint8_t, std::uint8_t>;
+template class pccc_encoder<std::uint8_t, std::int16_t>;
+template class pccc_encoder<std::uint8_t, std::int32_t>;
+template class pccc_encoder<std::int16_t, std::int16_t>;
+template class pccc_encoder<std::int16_t, std::int32_t>;
+template class pccc_encoder<std::int32_t, std::int32_t>;
- } /* namespace trellis */
+} /* namespace trellis */
} /* namespace gr */
diff --git a/gr-trellis/lib/pccc_encoder_impl.h b/gr-trellis/lib/pccc_encoder_impl.h
index 834e8986c4..67ff36918b 100644
--- a/gr-trellis/lib/pccc_encoder_impl.h
+++ b/gr-trellis/lib/pccc_encoder_impl.h
@@ -26,40 +26,42 @@
#include <gnuradio/trellis/pccc_encoder.h>
namespace gr {
- namespace trellis {
+namespace trellis {
- template <class IN_T, class OUT_T>
- class pccc_encoder_impl : public pccc_encoder<IN_T,OUT_T>
- {
- private:
- fsm d_FSM1;
- int d_ST1;
- fsm d_FSM2;
- int d_ST2;
- interleaver d_INTERLEAVER;
- int d_blocklength;
- std::vector<int> d_buffer;
+template <class IN_T, class OUT_T>
+class pccc_encoder_impl : public pccc_encoder<IN_T, OUT_T>
+{
+private:
+ fsm d_FSM1;
+ int d_ST1;
+ fsm d_FSM2;
+ int d_ST2;
+ interleaver d_INTERLEAVER;
+ int d_blocklength;
+ std::vector<int> d_buffer;
- public:
- pccc_encoder_impl(const fsm &FSM1, int ST1,
- const fsm &FSM2, int ST2,
- const interleaver &INTERLEAVER,
- int blocklength);
- ~pccc_encoder_impl();
+public:
+ pccc_encoder_impl(const fsm& FSM1,
+ int ST1,
+ const fsm& FSM2,
+ int ST2,
+ const interleaver& INTERLEAVER,
+ int blocklength);
+ ~pccc_encoder_impl();
- fsm FSM1() const { return d_FSM1; }
- int ST1() const { return d_ST1; }
- fsm FSM2() const { return d_FSM2; }
- int ST2() const { return d_ST2; }
- interleaver INTERLEAVER() const { return d_INTERLEAVER; }
- int blocklength() const { return d_blocklength; }
+ fsm FSM1() const { return d_FSM1; }
+ int ST1() const { return d_ST1; }
+ fsm FSM2() const { return d_FSM2; }
+ int ST2() const { return d_ST2; }
+ interleaver INTERLEAVER() const { return d_INTERLEAVER; }
+ int blocklength() const { return d_blocklength; }
- int work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
- };
+ int work(int noutput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items);
+};
- } /* namespace trellis */
+} /* namespace trellis */
} /* namespace gr */
#endif /* PCCC_ENCODER_IMPL_H */
diff --git a/gr-trellis/lib/permutation_impl.cc b/gr-trellis/lib/permutation_impl.cc
index 5a212a01a7..c0e732e1c3 100644
--- a/gr-trellis/lib/permutation_impl.cc
+++ b/gr-trellis/lib/permutation_impl.cc
@@ -30,82 +30,83 @@
#include <string.h>
namespace gr {
- namespace trellis {
+namespace trellis {
- permutation::sptr
- permutation::make(int K, const std::vector<int> &TABLE,
- int SYMS_PER_BLOCK, size_t BYTES_PER_SYMBOL)
- {
- return gnuradio::get_initial_sptr
- (new permutation_impl(K,TABLE,SYMS_PER_BLOCK,BYTES_PER_SYMBOL));
- }
+permutation::sptr permutation::make(int K,
+ const std::vector<int>& TABLE,
+ int SYMS_PER_BLOCK,
+ size_t BYTES_PER_SYMBOL)
+{
+ return gnuradio::get_initial_sptr(
+ new permutation_impl(K, TABLE, SYMS_PER_BLOCK, BYTES_PER_SYMBOL));
+}
- permutation_impl::permutation_impl(int K, const std::vector<int> &TABLE,
- int SYMS_PER_BLOCK, size_t BYTES_PER_SYMBOL)
- : sync_block("permutation",
- io_signature::make(1, -1, BYTES_PER_SYMBOL),
- io_signature::make(1, -1, BYTES_PER_SYMBOL)),
- d_K(K), d_TABLE(TABLE),
- d_SYMS_PER_BLOCK(SYMS_PER_BLOCK),
- d_BYTES_PER_SYMBOL(BYTES_PER_SYMBOL)
- {
- set_output_multiple(d_K*d_SYMS_PER_BLOCK);
- //std::cout << d_K << "\n";
- }
+permutation_impl::permutation_impl(int K,
+ const std::vector<int>& TABLE,
+ int SYMS_PER_BLOCK,
+ size_t BYTES_PER_SYMBOL)
+ : sync_block("permutation",
+ io_signature::make(1, -1, BYTES_PER_SYMBOL),
+ io_signature::make(1, -1, BYTES_PER_SYMBOL)),
+ d_K(K),
+ d_TABLE(TABLE),
+ d_SYMS_PER_BLOCK(SYMS_PER_BLOCK),
+ d_BYTES_PER_SYMBOL(BYTES_PER_SYMBOL)
+{
+ set_output_multiple(d_K * d_SYMS_PER_BLOCK);
+ // std::cout << d_K << "\n";
+}
- void permutation_impl::set_K(int K)
- {
- gr::thread::scoped_lock guard(d_setlock);
- d_K=K;
- set_output_multiple(d_K*d_SYMS_PER_BLOCK);
- }
+void permutation_impl::set_K(int K)
+{
+ gr::thread::scoped_lock guard(d_setlock);
+ d_K = K;
+ set_output_multiple(d_K * d_SYMS_PER_BLOCK);
+}
- void permutation_impl::set_TABLE (const std::vector<int> &table)
- {
- gr::thread::scoped_lock guard(d_setlock);
- d_TABLE = table;
- }
+void permutation_impl::set_TABLE(const std::vector<int>& table)
+{
+ gr::thread::scoped_lock guard(d_setlock);
+ d_TABLE = table;
+}
- void permutation_impl::set_SYMS_PER_BLOCK(int spb)
- {
- gr::thread::scoped_lock guard(d_setlock);
- d_SYMS_PER_BLOCK=spb;
- set_output_multiple(d_K*d_SYMS_PER_BLOCK);
- }
+void permutation_impl::set_SYMS_PER_BLOCK(int spb)
+{
+ gr::thread::scoped_lock guard(d_setlock);
+ d_SYMS_PER_BLOCK = spb;
+ set_output_multiple(d_K * d_SYMS_PER_BLOCK);
+}
- permutation_impl::~permutation_impl()
- {
- }
+permutation_impl::~permutation_impl() {}
- int
- permutation_impl::work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
- {
- gr::thread::scoped_lock guard(d_setlock);
- int nstreams = input_items.size();
+int permutation_impl::work(int noutput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items)
+{
+ gr::thread::scoped_lock guard(d_setlock);
+ int nstreams = input_items.size();
- for(int m=0;m<nstreams;m++) {
- const char *in = (const char *) input_items[m];
- char *out = (char *) output_items[m];
+ for (int m = 0; m < nstreams; m++) {
+ const char* in = (const char*)input_items[m];
+ char* out = (char*)output_items[m];
- // per stream processing
- for(int i = 0; i < noutput_items/d_SYMS_PER_BLOCK; i++) {
- // Index i refers to blocks.
- // Beginning of packet (in blocks)
- int i0 = d_K*(i/d_K);
- // position of block within packet (in blocks)
- int j0 = i%d_K;
- // new position of block within packet (in blocks)
- int k0 = d_TABLE[j0];
- memcpy(&(out[i*d_SYMS_PER_BLOCK*d_BYTES_PER_SYMBOL]),
- &(in[(i0+k0)*d_SYMS_PER_BLOCK*d_BYTES_PER_SYMBOL]),
- d_BYTES_PER_SYMBOL*d_SYMS_PER_BLOCK);
- }
- // end per stream processing
- }
- return noutput_items;
+ // per stream processing
+ for (int i = 0; i < noutput_items / d_SYMS_PER_BLOCK; i++) {
+ // Index i refers to blocks.
+ // Beginning of packet (in blocks)
+ int i0 = d_K * (i / d_K);
+ // position of block within packet (in blocks)
+ int j0 = i % d_K;
+ // new position of block within packet (in blocks)
+ int k0 = d_TABLE[j0];
+ memcpy(&(out[i * d_SYMS_PER_BLOCK * d_BYTES_PER_SYMBOL]),
+ &(in[(i0 + k0) * d_SYMS_PER_BLOCK * d_BYTES_PER_SYMBOL]),
+ d_BYTES_PER_SYMBOL * d_SYMS_PER_BLOCK);
+ }
+ // end per stream processing
}
+ return noutput_items;
+}
- } /* namespace trellis */
+} /* namespace trellis */
} /* namespace gr */
diff --git a/gr-trellis/lib/permutation_impl.h b/gr-trellis/lib/permutation_impl.h
index e013e52a20..f8adcca38d 100644
--- a/gr-trellis/lib/permutation_impl.h
+++ b/gr-trellis/lib/permutation_impl.h
@@ -27,36 +27,38 @@
#include <gnuradio/trellis/permutation.h>
namespace gr {
- namespace trellis {
-
- class permutation_impl : public permutation
- {
- private:
- int d_K;
- std::vector<int> d_TABLE;
- int d_SYMS_PER_BLOCK;
- size_t d_BYTES_PER_SYMBOL;
-
- public:
- permutation_impl(int K, const std::vector<int> &TABLE,
- int SYMS_PER_BLOCK, size_t NBYTES);
- ~permutation_impl();
-
- int K() const { return d_K; }
- std::vector<int> TABLE() const { return d_TABLE; }
- int SYMS_PER_BLOCK() const { return d_SYMS_PER_BLOCK; }
- size_t BYTES_PER_SYMBOL() const { return d_BYTES_PER_SYMBOL; }
-
- void set_K(int K) ;
- void set_TABLE (const std::vector<int> &table);
- void set_SYMS_PER_BLOCK(int spb) ;
-
- int work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
- };
-
- } /* namespace trellis */
+namespace trellis {
+
+class permutation_impl : public permutation
+{
+private:
+ int d_K;
+ std::vector<int> d_TABLE;
+ int d_SYMS_PER_BLOCK;
+ size_t d_BYTES_PER_SYMBOL;
+
+public:
+ permutation_impl(int K,
+ const std::vector<int>& TABLE,
+ int SYMS_PER_BLOCK,
+ size_t NBYTES);
+ ~permutation_impl();
+
+ int K() const { return d_K; }
+ std::vector<int> TABLE() const { return d_TABLE; }
+ int SYMS_PER_BLOCK() const { return d_SYMS_PER_BLOCK; }
+ size_t BYTES_PER_SYMBOL() const { return d_BYTES_PER_SYMBOL; }
+
+ void set_K(int K);
+ void set_TABLE(const std::vector<int>& table);
+ void set_SYMS_PER_BLOCK(int spb);
+
+ int work(int noutput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items);
+};
+
+} /* namespace trellis */
} /* namespace gr */
#endif /* INCLUDED_TRELLIS_PERMUTATION_IMPL_H */
diff --git a/gr-trellis/lib/quicksort_index.cc b/gr-trellis/lib/quicksort_index.cc
index 2e7c21907a..aeccdb65ef 100644
--- a/gr-trellis/lib/quicksort_index.cc
+++ b/gr-trellis/lib/quicksort_index.cc
@@ -23,48 +23,46 @@
#include <gnuradio/trellis/quicksort_index.h>
namespace gr {
- namespace trellis {
+namespace trellis {
- template <class T> void
- SWAP(T & a, T & b)
- {
- T temp = a;
- a = b;
- b = temp;
- }
+template <class T>
+void SWAP(T& a, T& b)
+{
+ T temp = a;
+ a = b;
+ b = temp;
+}
- template <class T> void
- quicksort_index (std::vector<T> & p, std::vector<int> & index,
- int left, int right)
- {
- if(left < right) {
- int i = left;
- int j = right + 1;
- T pivot = p[left];
- do {
- do
- i++;
- while ((p[i] < pivot) && (i < right));
- do
- j--;
- while ((p[j] > pivot) && (j > left));
- if (i < j) {
- SWAP <T> (p[i],p[j]);
- SWAP <int> (index[i],index[j]);
- }
- } while (i < j);
- SWAP <T> (p[left], p[j]);
- SWAP <int> (index[left], index[j]);
- quicksort_index <T> (p,index, left, j-1);
- quicksort_index <T> (p,index, j+1, right);
- }
+template <class T>
+void quicksort_index(std::vector<T>& p, std::vector<int>& index, int left, int right)
+{
+ if (left < right) {
+ int i = left;
+ int j = right + 1;
+ T pivot = p[left];
+ do {
+ do
+ i++;
+ while ((p[i] < pivot) && (i < right));
+ do
+ j--;
+ while ((p[j] > pivot) && (j > left));
+ if (i < j) {
+ SWAP<T>(p[i], p[j]);
+ SWAP<int>(index[i], index[j]);
+ }
+ } while (i < j);
+ SWAP<T>(p[left], p[j]);
+ SWAP<int>(index[left], index[j]);
+ quicksort_index<T>(p, index, left, j - 1);
+ quicksort_index<T>(p, index, j + 1, right);
}
+}
- // instantiate an <int> version of the quicksort_index
- //template <int> void SWAP (int & a, int & b);
- template void
- quicksort_index<int>(std::vector<int> & p, std::vector<int> & index,
- int left, int right);
+// instantiate an <int> version of the quicksort_index
+// template <int> void SWAP (int & a, int & b);
+template void
+quicksort_index<int>(std::vector<int>& p, std::vector<int>& index, int left, int right);
- } /* namespace trellis */
+} /* namespace trellis */
} /* namespace gr */
diff --git a/gr-trellis/lib/sccc_decoder_blk_impl.cc b/gr-trellis/lib/sccc_decoder_blk_impl.cc
index 152079d94c..206dc3f5da 100644
--- a/gr-trellis/lib/sccc_decoder_blk_impl.cc
+++ b/gr-trellis/lib/sccc_decoder_blk_impl.cc
@@ -31,93 +31,115 @@
#include <gnuradio/trellis/core_algorithms.h>
namespace gr {
- namespace trellis {
+namespace trellis {
- template <class T>
- typename sccc_decoder_blk<T>::sptr
- sccc_decoder_blk<T>::make(const fsm &FSMo, int STo0, int SToK,
- const fsm &FSMi, int STi0, int STiK,
- const interleaver &INTERLEAVER,
- int blocklength,
- int repetitions,
- siso_type_t SISO_TYPE)
- {
- return gnuradio::get_initial_sptr
- (new sccc_decoder_blk_impl<T>(FSMo, STo0, SToK, FSMi, STi0, STiK,
- INTERLEAVER, blocklength, repetitions,
- SISO_TYPE));
- }
+template <class T>
+typename sccc_decoder_blk<T>::sptr
+sccc_decoder_blk<T>::make(const fsm& FSMo,
+ int STo0,
+ int SToK,
+ const fsm& FSMi,
+ int STi0,
+ int STiK,
+ const interleaver& INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ siso_type_t SISO_TYPE)
+{
+ return gnuradio::get_initial_sptr(new sccc_decoder_blk_impl<T>(FSMo,
+ STo0,
+ SToK,
+ FSMi,
+ STi0,
+ STiK,
+ INTERLEAVER,
+ blocklength,
+ repetitions,
+ SISO_TYPE));
+}
- template <class T>
- sccc_decoder_blk_impl<T>::sccc_decoder_blk_impl(const fsm &FSMo, int STo0, int SToK,
- const fsm &FSMi, int STi0, int STiK,
- const interleaver &INTERLEAVER,
- int blocklength,
- int repetitions,
- siso_type_t SISO_TYPE)
+template <class T>
+sccc_decoder_blk_impl<T>::sccc_decoder_blk_impl(const fsm& FSMo,
+ int STo0,
+ int SToK,
+ const fsm& FSMi,
+ int STi0,
+ int STiK,
+ const interleaver& INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ siso_type_t SISO_TYPE)
: block("sccc_decoder_blk",
- io_signature::make(1, 1, sizeof(float)),
- io_signature::make(1, 1, sizeof(T))),
- d_FSMo(FSMo), d_STo0(STo0), d_SToK(SToK),
- d_FSMi(FSMi), d_STi0(STi0), d_STiK(STiK),
+ io_signature::make(1, 1, sizeof(float)),
+ io_signature::make(1, 1, sizeof(T))),
+ d_FSMo(FSMo),
+ d_STo0(STo0),
+ d_SToK(SToK),
+ d_FSMi(FSMi),
+ d_STi0(STi0),
+ d_STiK(STiK),
d_INTERLEAVER(INTERLEAVER),
d_blocklength(blocklength),
d_repetitions(repetitions),
d_SISO_TYPE(SISO_TYPE)
- {
- this->set_relative_rate(1, (uint64_t) d_FSMi.O());
- this->set_output_multiple(d_blocklength);
- }
-
- template <class T>
- sccc_decoder_blk_impl<T>::~sccc_decoder_blk_impl()
- {
- }
+{
+ this->set_relative_rate(1, (uint64_t)d_FSMi.O());
+ this->set_output_multiple(d_blocklength);
+}
- template <class T>
- void
- sccc_decoder_blk_impl<T>::forecast(int noutput_items,
- gr_vector_int &ninput_items_required)
- {
- int input_required = d_FSMi.O() * noutput_items ;
- ninput_items_required[0] = input_required;
- }
+template <class T>
+sccc_decoder_blk_impl<T>::~sccc_decoder_blk_impl()
+{
+}
- //===========================================================
+template <class T>
+void sccc_decoder_blk_impl<T>::forecast(int noutput_items,
+ gr_vector_int& ninput_items_required)
+{
+ int input_required = d_FSMi.O() * noutput_items;
+ ninput_items_required[0] = input_required;
+}
- template <class T>
- int
- sccc_decoder_blk_impl<T>::general_work(int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
- {
- int nblocks = noutput_items / d_blocklength;
- float (*p2min)(float, float) = NULL;
+//===========================================================
- if(d_SISO_TYPE == TRELLIS_MIN_SUM)
- p2min = &min;
- else if(d_SISO_TYPE == TRELLIS_SUM_PRODUCT)
- p2min = &min_star;
+template <class T>
+int sccc_decoder_blk_impl<T>::general_work(int noutput_items,
+ gr_vector_int& ninput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items)
+{
+ int nblocks = noutput_items / d_blocklength;
+ float (*p2min)(float, float) = NULL;
- const float *in = (const float*)input_items[0];
- T *out = (T*)output_items[0];
+ if (d_SISO_TYPE == TRELLIS_MIN_SUM)
+ p2min = &min;
+ else if (d_SISO_TYPE == TRELLIS_SUM_PRODUCT)
+ p2min = &min_star;
- for(int n = 0; n < nblocks; n++) {
- sccc_decoder(d_FSMo, d_STo0, d_SToK,
- d_FSMi, d_STi0, d_STiK,
- d_INTERLEAVER, d_blocklength, d_repetitions,
- p2min,
- &(in[n*d_blocklength*d_FSMi.O()]),
- &(out[n*d_blocklength]));
- }
+ const float* in = (const float*)input_items[0];
+ T* out = (T*)output_items[0];
- this->consume_each(d_FSMi.O() * noutput_items );
- return noutput_items;
+ for (int n = 0; n < nblocks; n++) {
+ sccc_decoder(d_FSMo,
+ d_STo0,
+ d_SToK,
+ d_FSMi,
+ d_STi0,
+ d_STiK,
+ d_INTERLEAVER,
+ d_blocklength,
+ d_repetitions,
+ p2min,
+ &(in[n * d_blocklength * d_FSMi.O()]),
+ &(out[n * d_blocklength]));
}
+ this->consume_each(d_FSMi.O() * noutput_items);
+ return noutput_items;
+}
+
template class sccc_decoder_blk<std::uint8_t>;
template class sccc_decoder_blk<std::int16_t>;
template class sccc_decoder_blk<std::int32_t>;
- } /* namespace trellis */
+} /* namespace trellis */
} /* namespace gr */
diff --git a/gr-trellis/lib/sccc_decoder_blk_impl.h b/gr-trellis/lib/sccc_decoder_blk_impl.h
index 0c3e2d9310..683f65190f 100644
--- a/gr-trellis/lib/sccc_decoder_blk_impl.h
+++ b/gr-trellis/lib/sccc_decoder_blk_impl.h
@@ -27,54 +27,57 @@
#include <gnuradio/trellis/sccc_decoder_blk.h>
namespace gr {
- namespace trellis {
+namespace trellis {
-template<class T>
- class sccc_decoder_blk_impl : public sccc_decoder_blk<T>
- {
- private:
- fsm d_FSMo;
- int d_STo0;
- int d_SToK;
- fsm d_FSMi;
- int d_STi0;
- int d_STiK;
- interleaver d_INTERLEAVER;
- int d_blocklength;
- int d_repetitions;
- siso_type_t d_SISO_TYPE;
- std::vector<float> d_buffer;
+template <class T>
+class sccc_decoder_blk_impl : public sccc_decoder_blk<T>
+{
+private:
+ fsm d_FSMo;
+ int d_STo0;
+ int d_SToK;
+ fsm d_FSMi;
+ int d_STi0;
+ int d_STiK;
+ interleaver d_INTERLEAVER;
+ int d_blocklength;
+ int d_repetitions;
+ siso_type_t d_SISO_TYPE;
+ std::vector<float> d_buffer;
- public:
- sccc_decoder_blk_impl(const fsm &FSMo, int STo0, int SToK,
- const fsm &FSMi, int STi0, int STiK,
- const interleaver &INTERLEAVER,
- int blocklength,
- int repetitions,
- siso_type_t SISO_TYPE);
- ~sccc_decoder_blk_impl();
+public:
+ sccc_decoder_blk_impl(const fsm& FSMo,
+ int STo0,
+ int SToK,
+ const fsm& FSMi,
+ int STi0,
+ int STiK,
+ const interleaver& INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ siso_type_t SISO_TYPE);
+ ~sccc_decoder_blk_impl();
- fsm FSMo() const { return d_FSMo; }
- fsm FSMi() const { return d_FSMi; }
- int STo0() const { return d_STo0; }
- int SToK() const { return d_SToK; }
- int STi0() const { return d_STi0; }
- int STiK() const { return d_STiK; }
- interleaver INTERLEAVER() const { return d_INTERLEAVER; }
- int blocklength() const { return d_blocklength; }
- int repetitions() const { return d_repetitions; }
- siso_type_t SISO_TYPE() const { return d_SISO_TYPE; }
+ fsm FSMo() const { return d_FSMo; }
+ fsm FSMi() const { return d_FSMi; }
+ int STo0() const { return d_STo0; }
+ int SToK() const { return d_SToK; }
+ int STi0() const { return d_STi0; }
+ int STiK() const { return d_STiK; }
+ interleaver INTERLEAVER() const { return d_INTERLEAVER; }
+ int blocklength() const { return d_blocklength; }
+ int repetitions() const { return d_repetitions; }
+ siso_type_t SISO_TYPE() const { return d_SISO_TYPE; }
- void forecast(int noutput_items,
- gr_vector_int &ninput_items_required);
+ void forecast(int noutput_items, gr_vector_int& ninput_items_required);
- int general_work(int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
- };
+ int general_work(int noutput_items,
+ gr_vector_int& ninput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items);
+};
- } /* namespace trellis */
+} /* namespace trellis */
} /* namespace gr */
#endif /* SCCC_DECODER_BLK_IMPL_H */
diff --git a/gr-trellis/lib/sccc_decoder_combined_blk_impl.cc b/gr-trellis/lib/sccc_decoder_combined_blk_impl.cc
index 9ef1321996..6f25189246 100644
--- a/gr-trellis/lib/sccc_decoder_combined_blk_impl.cc
+++ b/gr-trellis/lib/sccc_decoder_combined_blk_impl.cc
@@ -30,43 +30,67 @@
#include <gnuradio/trellis/core_algorithms.h>
namespace gr {
- namespace trellis {
-
- template <class IN_T, class OUT_T>
- typename sccc_decoder_combined_blk<IN_T,OUT_T>::sptr
- sccc_decoder_combined_blk<IN_T,OUT_T>::make(const fsm &FSMo, int STo0, int SToK,
- const fsm &FSMi, int STi0, int STiK,
- const interleaver &INTERLEAVER,
- int blocklength,
- int repetitions,
- siso_type_t SISO_TYPE,
- int D,
- const std::vector<IN_T> &TABLE,
- digital::trellis_metric_type_t METRIC_TYPE,
- float scaling)
- {
- return gnuradio::get_initial_sptr
- (new sccc_decoder_combined_blk_impl<IN_T,OUT_T>(FSMo, STo0, SToK, FSMi, STi0, STiK,
- INTERLEAVER, blocklength, repetitions,
- SISO_TYPE, D, TABLE,METRIC_TYPE, scaling));
- }
-
- template <class IN_T, class OUT_T>
- sccc_decoder_combined_blk_impl<IN_T,OUT_T>::sccc_decoder_combined_blk_impl(const fsm &FSMo, int STo0, int SToK,
- const fsm &FSMi, int STi0, int STiK,
- const interleaver &INTERLEAVER,
- int blocklength,
- int repetitions,
- siso_type_t SISO_TYPE,
- int D,
- const std::vector<IN_T> &TABLE,
- digital::trellis_metric_type_t METRIC_TYPE,
- float scaling)
+namespace trellis {
+
+template <class IN_T, class OUT_T>
+typename sccc_decoder_combined_blk<IN_T, OUT_T>::sptr
+sccc_decoder_combined_blk<IN_T, OUT_T>::make(const fsm& FSMo,
+ int STo0,
+ int SToK,
+ const fsm& FSMi,
+ int STi0,
+ int STiK,
+ const interleaver& INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ siso_type_t SISO_TYPE,
+ int D,
+ const std::vector<IN_T>& TABLE,
+ digital::trellis_metric_type_t METRIC_TYPE,
+ float scaling)
+{
+ return gnuradio::get_initial_sptr(
+ new sccc_decoder_combined_blk_impl<IN_T, OUT_T>(FSMo,
+ STo0,
+ SToK,
+ FSMi,
+ STi0,
+ STiK,
+ INTERLEAVER,
+ blocklength,
+ repetitions,
+ SISO_TYPE,
+ D,
+ TABLE,
+ METRIC_TYPE,
+ scaling));
+}
+
+template <class IN_T, class OUT_T>
+sccc_decoder_combined_blk_impl<IN_T, OUT_T>::sccc_decoder_combined_blk_impl(
+ const fsm& FSMo,
+ int STo0,
+ int SToK,
+ const fsm& FSMi,
+ int STi0,
+ int STiK,
+ const interleaver& INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ siso_type_t SISO_TYPE,
+ int D,
+ const std::vector<IN_T>& TABLE,
+ digital::trellis_metric_type_t METRIC_TYPE,
+ float scaling)
: block("sccc_decoder_combined_blk<IN_T,OUT_T>",
- io_signature::make(1, 1, sizeof(IN_T)),
- io_signature::make(1, 1, sizeof(OUT_T))),
- d_FSMo(FSMo), d_STo0(STo0), d_SToK(SToK),
- d_FSMi(FSMi), d_STi0(STi0), d_STiK(STiK),
+ io_signature::make(1, 1, sizeof(IN_T)),
+ io_signature::make(1, 1, sizeof(OUT_T))),
+ d_FSMo(FSMo),
+ d_STo0(STo0),
+ d_SToK(SToK),
+ d_FSMi(FSMi),
+ d_STi0(STi0),
+ d_STiK(STiK),
d_INTERLEAVER(INTERLEAVER),
d_blocklength(blocklength),
d_repetitions(repetitions),
@@ -75,77 +99,82 @@ namespace gr {
d_TABLE(TABLE),
d_METRIC_TYPE(METRIC_TYPE),
d_scaling(scaling)
- {
- this->set_relative_rate(1, (uint64_t) d_D);
- this->set_output_multiple(d_blocklength);
+{
+ this->set_relative_rate(1, (uint64_t)d_D);
+ this->set_output_multiple(d_blocklength);
+}
+
+template <class IN_T, class OUT_T>
+sccc_decoder_combined_blk_impl<IN_T, OUT_T>::~sccc_decoder_combined_blk_impl()
+{
+}
+
+template <class IN_T, class OUT_T>
+void sccc_decoder_combined_blk_impl<IN_T, OUT_T>::set_scaling(float scaling)
+{
+ gr::thread::scoped_lock guard(this->d_setlock);
+ d_scaling = scaling;
+}
+
+template <class IN_T, class OUT_T>
+void sccc_decoder_combined_blk_impl<IN_T, OUT_T>::forecast(
+ int noutput_items, gr_vector_int& ninput_items_required)
+{
+ int input_required = d_D * noutput_items;
+ ninput_items_required[0] = input_required;
+}
+
+//===========================================================
+
+template <class IN_T, class OUT_T>
+int sccc_decoder_combined_blk_impl<IN_T, OUT_T>::general_work(
+ int noutput_items,
+ gr_vector_int& ninput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items)
+{
+ gr::thread::scoped_lock guard(this->d_setlock);
+ int nblocks = noutput_items / d_blocklength;
+ float (*p2min)(float, float) = NULL;
+
+ if (d_SISO_TYPE == TRELLIS_MIN_SUM)
+ p2min = &min;
+ else if (d_SISO_TYPE == TRELLIS_SUM_PRODUCT)
+ p2min = &min_star;
+
+ const IN_T* in = (const IN_T*)input_items[0];
+ OUT_T* out = (OUT_T*)output_items[0];
+
+ for (int n = 0; n < nblocks; n++) {
+ sccc_decoder_combined(d_FSMo,
+ d_STo0,
+ d_SToK,
+ d_FSMi,
+ d_STi0,
+ d_STiK,
+ d_INTERLEAVER,
+ d_blocklength,
+ d_repetitions,
+ p2min,
+ d_D,
+ d_TABLE,
+ d_METRIC_TYPE,
+ d_scaling,
+ &(in[n * d_blocklength * d_D]),
+ &(out[n * d_blocklength]));
}
- template <class IN_T, class OUT_T>
- sccc_decoder_combined_blk_impl<IN_T,OUT_T>::~sccc_decoder_combined_blk_impl()
- {
- }
-
- template <class IN_T, class OUT_T>
- void
- sccc_decoder_combined_blk_impl<IN_T,OUT_T>::set_scaling(float scaling)
- {
- gr::thread::scoped_lock guard(this->d_setlock);
- d_scaling = scaling;
- }
-
- template <class IN_T, class OUT_T>
- void
- sccc_decoder_combined_blk_impl<IN_T,OUT_T>::forecast(int noutput_items,
- gr_vector_int &ninput_items_required)
- {
- int input_required = d_D * noutput_items ;
- ninput_items_required[0] = input_required;
- }
-
- //===========================================================
-
- template <class IN_T, class OUT_T>
- int
- sccc_decoder_combined_blk_impl<IN_T,OUT_T>::general_work(int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
- {
- gr::thread::scoped_lock guard(this->d_setlock);
- int nblocks = noutput_items / d_blocklength;
- float (*p2min)(float, float) = NULL;
-
- if(d_SISO_TYPE == TRELLIS_MIN_SUM)
- p2min = &min;
- else if(d_SISO_TYPE == TRELLIS_SUM_PRODUCT)
- p2min = &min_star;
-
- const IN_T *in = (const IN_T*)input_items[0];
- OUT_T *out = (OUT_T*)output_items[0];
-
- for(int n = 0; n < nblocks; n++) {
- sccc_decoder_combined(d_FSMo, d_STo0, d_SToK,
- d_FSMi, d_STi0, d_STiK,
- d_INTERLEAVER, d_blocklength, d_repetitions,
- p2min,
- d_D,d_TABLE,
- d_METRIC_TYPE,
- d_scaling,
- &(in[n*d_blocklength*d_D]),
- &(out[n*d_blocklength]));
- }
-
- this->consume_each(d_D * noutput_items);
- return noutput_items;
- }
+ this->consume_each(d_D * noutput_items);
+ return noutput_items;
+}
- template class sccc_decoder_combined_blk<float, std::uint8_t>;
- template class sccc_decoder_combined_blk<float, std::int16_t>;
- template class sccc_decoder_combined_blk<float, std::int32_t>;
- template class sccc_decoder_combined_blk<gr_complex, std::uint8_t>;
- template class sccc_decoder_combined_blk<gr_complex, std::int16_t>;
- template class sccc_decoder_combined_blk<gr_complex, std::int32_t>;
+template class sccc_decoder_combined_blk<float, std::uint8_t>;
+template class sccc_decoder_combined_blk<float, std::int16_t>;
+template class sccc_decoder_combined_blk<float, std::int32_t>;
+template class sccc_decoder_combined_blk<gr_complex, std::uint8_t>;
+template class sccc_decoder_combined_blk<gr_complex, std::int16_t>;
+template class sccc_decoder_combined_blk<gr_complex, std::int32_t>;
- } /* namespace trellis */
+} /* namespace trellis */
} /* namespace gr */
diff --git a/gr-trellis/lib/sccc_decoder_combined_blk_impl.h b/gr-trellis/lib/sccc_decoder_combined_blk_impl.h
index 8236c79a49..91a5fbd3da 100644
--- a/gr-trellis/lib/sccc_decoder_combined_blk_impl.h
+++ b/gr-trellis/lib/sccc_decoder_combined_blk_impl.h
@@ -26,67 +26,70 @@
#include <gnuradio/trellis/sccc_decoder_combined_blk.h>
namespace gr {
- namespace trellis {
+namespace trellis {
- template <class IN_T, class OUT_T>
- class sccc_decoder_combined_blk_impl : public sccc_decoder_combined_blk<IN_T,OUT_T>
- {
- private:
- fsm d_FSMo;
- int d_STo0;
- int d_SToK;
- fsm d_FSMi;
- int d_STi0;
- int d_STiK;
- interleaver d_INTERLEAVER;
- int d_blocklength;
- int d_repetitions;
- siso_type_t d_SISO_TYPE;
- int d_D;
- std::vector<IN_T> d_TABLE;
- digital::trellis_metric_type_t d_METRIC_TYPE;
- float d_scaling;
- std::vector<float> d_buffer;
+template <class IN_T, class OUT_T>
+class sccc_decoder_combined_blk_impl : public sccc_decoder_combined_blk<IN_T, OUT_T>
+{
+private:
+ fsm d_FSMo;
+ int d_STo0;
+ int d_SToK;
+ fsm d_FSMi;
+ int d_STi0;
+ int d_STiK;
+ interleaver d_INTERLEAVER;
+ int d_blocklength;
+ int d_repetitions;
+ siso_type_t d_SISO_TYPE;
+ int d_D;
+ std::vector<IN_T> d_TABLE;
+ digital::trellis_metric_type_t d_METRIC_TYPE;
+ float d_scaling;
+ std::vector<float> d_buffer;
- public:
- sccc_decoder_combined_blk_impl(const fsm &FSMo, int STo0, int SToK,
- const fsm &FSMi, int STi0, int STiK,
- const interleaver &INTERLEAVER,
- int blocklength,
- int repetitions,
- siso_type_t SISO_TYPE,
- int D,
- const std::vector<IN_T> &TABLE,
- digital::trellis_metric_type_t METRIC_TYPE,
- float scaling);
- ~sccc_decoder_combined_blk_impl();
+public:
+ sccc_decoder_combined_blk_impl(const fsm& FSMo,
+ int STo0,
+ int SToK,
+ const fsm& FSMi,
+ int STi0,
+ int STiK,
+ const interleaver& INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ siso_type_t SISO_TYPE,
+ int D,
+ const std::vector<IN_T>& TABLE,
+ digital::trellis_metric_type_t METRIC_TYPE,
+ float scaling);
+ ~sccc_decoder_combined_blk_impl();
- fsm FSMo() const { return d_FSMo; }
- fsm FSMi() const { return d_FSMi; }
- int STo0() const { return d_STo0; }
- int SToK() const { return d_SToK; }
- int STi0() const { return d_STi0; }
- int STiK() const { return d_STiK; }
- interleaver INTERLEAVER() const { return d_INTERLEAVER; }
- int blocklength() const { return d_blocklength; }
- int repetitions() const { return d_repetitions; }
- int D() const { return d_D; }
- std::vector<IN_T> TABLE() const { return d_TABLE; }
- digital::trellis_metric_type_t METRIC_TYPE() const { return d_METRIC_TYPE; }
- siso_type_t SISO_TYPE() const { return d_SISO_TYPE; }
- float scaling() const { return d_scaling; }
- void set_scaling(float scaling);
+ fsm FSMo() const { return d_FSMo; }
+ fsm FSMi() const { return d_FSMi; }
+ int STo0() const { return d_STo0; }
+ int SToK() const { return d_SToK; }
+ int STi0() const { return d_STi0; }
+ int STiK() const { return d_STiK; }
+ interleaver INTERLEAVER() const { return d_INTERLEAVER; }
+ int blocklength() const { return d_blocklength; }
+ int repetitions() const { return d_repetitions; }
+ int D() const { return d_D; }
+ std::vector<IN_T> TABLE() const { return d_TABLE; }
+ digital::trellis_metric_type_t METRIC_TYPE() const { return d_METRIC_TYPE; }
+ siso_type_t SISO_TYPE() const { return d_SISO_TYPE; }
+ float scaling() const { return d_scaling; }
+ void set_scaling(float scaling);
- void forecast(int noutput_items,
- gr_vector_int &ninput_items_required);
+ void forecast(int noutput_items, gr_vector_int& ninput_items_required);
- int general_work(int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
- };
+ int general_work(int noutput_items,
+ gr_vector_int& ninput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items);
+};
- } /* namespace trellis */
+} /* namespace trellis */
} /* namespace gr */
#endif /* SCCC_DECODER_COMBINED_BLK_IMPL_H */
diff --git a/gr-trellis/lib/sccc_encoder_impl.cc b/gr-trellis/lib/sccc_encoder_impl.cc
index 9c3e1da2d5..8bff8dbe43 100644
--- a/gr-trellis/lib/sccc_encoder_impl.cc
+++ b/gr-trellis/lib/sccc_encoder_impl.cc
@@ -29,73 +29,78 @@
#include <iostream>
namespace gr {
- namespace trellis {
+namespace trellis {
- template <class IN_T, class OUT_T>
- typename sccc_encoder<IN_T,OUT_T>::sptr
- sccc_encoder<IN_T,OUT_T>::make(const fsm &FSMo, int STo,
- const fsm &FSMi, int STi,
- const interleaver &INTERLEAVER,
- int blocklength)
- {
- return gnuradio::get_initial_sptr
- (new sccc_encoder_impl<IN_T,OUT_T>(FSMo, STo, FSMi, STi, INTERLEAVER, blocklength));
- }
+template <class IN_T, class OUT_T>
+typename sccc_encoder<IN_T, OUT_T>::sptr
+sccc_encoder<IN_T, OUT_T>::make(const fsm& FSMo,
+ int STo,
+ const fsm& FSMi,
+ int STi,
+ const interleaver& INTERLEAVER,
+ int blocklength)
+{
+ return gnuradio::get_initial_sptr(new sccc_encoder_impl<IN_T, OUT_T>(
+ FSMo, STo, FSMi, STi, INTERLEAVER, blocklength));
+}
- template <class IN_T, class OUT_T>
- sccc_encoder_impl<IN_T,OUT_T>::sccc_encoder_impl(const fsm &FSMo, int STo,
- const fsm &FSMi, int STi,
- const interleaver &INTERLEAVER,
- int blocklength)
+template <class IN_T, class OUT_T>
+sccc_encoder_impl<IN_T, OUT_T>::sccc_encoder_impl(const fsm& FSMo,
+ int STo,
+ const fsm& FSMi,
+ int STi,
+ const interleaver& INTERLEAVER,
+ int blocklength)
: sync_block("sccc_encoder<IN_T,OUT_T>",
- io_signature::make(1, 1, sizeof(IN_T)),
- io_signature::make(1, 1, sizeof(OUT_T))),
- d_FSMo(FSMo), d_STo(STo),
- d_FSMi(FSMi), d_STi(STi),
+ io_signature::make(1, 1, sizeof(IN_T)),
+ io_signature::make(1, 1, sizeof(OUT_T))),
+ d_FSMo(FSMo),
+ d_STo(STo),
+ d_FSMi(FSMi),
+ d_STi(STi),
d_INTERLEAVER(INTERLEAVER),
d_blocklength(blocklength)
- {
- this->set_output_multiple(d_blocklength);
- d_buffer.resize(d_blocklength);
- }
+{
+ this->set_output_multiple(d_blocklength);
+ d_buffer.resize(d_blocklength);
+}
- template <class IN_T, class OUT_T>
- sccc_encoder_impl<IN_T,OUT_T>::~sccc_encoder_impl()
- {
- }
+template <class IN_T, class OUT_T>
+sccc_encoder_impl<IN_T, OUT_T>::~sccc_encoder_impl()
+{
+}
- template <class IN_T, class OUT_T>
- int
- sccc_encoder_impl<IN_T,OUT_T>::work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
- {
- for(int b = 0; b < noutput_items/d_blocklength; b++) {
- const IN_T *in = (const IN_T*)input_items[0]+b*d_blocklength;
- OUT_T *out = (OUT_T*)output_items[0]+b*d_blocklength;
+template <class IN_T, class OUT_T>
+int sccc_encoder_impl<IN_T, OUT_T>::work(int noutput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items)
+{
+ for (int b = 0; b < noutput_items / d_blocklength; b++) {
+ const IN_T* in = (const IN_T*)input_items[0] + b * d_blocklength;
+ OUT_T* out = (OUT_T*)output_items[0] + b * d_blocklength;
- int STo_tmp = d_STo;
- for(int i = 0; i < d_blocklength; i++) {
- d_buffer[i] = d_FSMo.OS()[STo_tmp*d_FSMo.I()+in[i]];
- STo_tmp = (int) d_FSMo.NS()[STo_tmp*d_FSMo.I()+in[i]];
- }
+ int STo_tmp = d_STo;
+ for (int i = 0; i < d_blocklength; i++) {
+ d_buffer[i] = d_FSMo.OS()[STo_tmp * d_FSMo.I() + in[i]];
+ STo_tmp = (int)d_FSMo.NS()[STo_tmp * d_FSMo.I() + in[i]];
+ }
- int STi_tmp = d_STi;
- for(int i = 0; i < d_blocklength; i++) {
- int k = d_INTERLEAVER.INTER()[i];
- out[i] = (OUT_T) d_FSMi.OS()[STi_tmp*d_FSMi.I()+d_buffer[k]];
- STi_tmp = (int) d_FSMi.NS()[STi_tmp*d_FSMi.I()+d_buffer[k]];
- }
- }
- return noutput_items;
+ int STi_tmp = d_STi;
+ for (int i = 0; i < d_blocklength; i++) {
+ int k = d_INTERLEAVER.INTER()[i];
+ out[i] = (OUT_T)d_FSMi.OS()[STi_tmp * d_FSMi.I() + d_buffer[k]];
+ STi_tmp = (int)d_FSMi.NS()[STi_tmp * d_FSMi.I() + d_buffer[k]];
+ }
}
- template class sccc_encoder<std::uint8_t, std::uint8_t>;
- template class sccc_encoder<std::uint8_t, std::int16_t>;
- template class sccc_encoder<std::uint8_t, std::int32_t>;
- template class sccc_encoder<std::int16_t, std::int16_t>;
- template class sccc_encoder<std::int16_t, std::int32_t>;
- template class sccc_encoder<std::int32_t, std::int32_t>;
+ return noutput_items;
+}
+template class sccc_encoder<std::uint8_t, std::uint8_t>;
+template class sccc_encoder<std::uint8_t, std::int16_t>;
+template class sccc_encoder<std::uint8_t, std::int32_t>;
+template class sccc_encoder<std::int16_t, std::int16_t>;
+template class sccc_encoder<std::int16_t, std::int32_t>;
+template class sccc_encoder<std::int32_t, std::int32_t>;
- } /* namespace trellis */
+} /* namespace trellis */
} /* namespace gr */
diff --git a/gr-trellis/lib/sccc_encoder_impl.h b/gr-trellis/lib/sccc_encoder_impl.h
index 40968906dc..f298b61c23 100644
--- a/gr-trellis/lib/sccc_encoder_impl.h
+++ b/gr-trellis/lib/sccc_encoder_impl.h
@@ -26,40 +26,42 @@
#include <gnuradio/trellis/sccc_encoder.h>
namespace gr {
- namespace trellis {
+namespace trellis {
- template <class IN_T, class OUT_T>
- class sccc_encoder_impl : public sccc_encoder<IN_T,OUT_T>
- {
- private:
- fsm d_FSMo;
- int d_STo;
- fsm d_FSMi;
- int d_STi;
- interleaver d_INTERLEAVER;
- int d_blocklength;
- std::vector<int> d_buffer;
+template <class IN_T, class OUT_T>
+class sccc_encoder_impl : public sccc_encoder<IN_T, OUT_T>
+{
+private:
+ fsm d_FSMo;
+ int d_STo;
+ fsm d_FSMi;
+ int d_STi;
+ interleaver d_INTERLEAVER;
+ int d_blocklength;
+ std::vector<int> d_buffer;
- public:
- sccc_encoder_impl(const fsm &FSMo, int STo,
- const fsm &FSMi, int STi,
- const interleaver &INTERLEAVER,
- int blocklength);
- ~sccc_encoder_impl();
+public:
+ sccc_encoder_impl(const fsm& FSMo,
+ int STo,
+ const fsm& FSMi,
+ int STi,
+ const interleaver& INTERLEAVER,
+ int blocklength);
+ ~sccc_encoder_impl();
- fsm FSMo() const { return d_FSMo; }
- int STo() const { return d_STo; }
- fsm FSMi() const { return d_FSMi; }
- int STi() const { return d_STi; }
- interleaver INTERLEAVER() const { return d_INTERLEAVER; }
- int blocklength() const { return d_blocklength; }
+ fsm FSMo() const { return d_FSMo; }
+ int STo() const { return d_STo; }
+ fsm FSMi() const { return d_FSMi; }
+ int STi() const { return d_STi; }
+ interleaver INTERLEAVER() const { return d_INTERLEAVER; }
+ int blocklength() const { return d_blocklength; }
- int work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
- };
+ int work(int noutput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items);
+};
- } /* namespace trellis */
+} /* namespace trellis */
} /* namespace gr */
#endif /* SCCC_ENCODER_IMPL_H */
diff --git a/gr-trellis/lib/siso_combined_f_impl.cc b/gr-trellis/lib/siso_combined_f_impl.cc
index ff413b8699..d6decbbafd 100644
--- a/gr-trellis/lib/siso_combined_f_impl.cc
+++ b/gr-trellis/lib/siso_combined_f_impl.cc
@@ -31,219 +31,239 @@
#include <iostream>
namespace gr {
- namespace trellis {
-
- siso_combined_f::sptr
- siso_combined_f::make(const fsm &FSM, int K,
- int S0, int SK,
- bool POSTI, bool POSTO,
- siso_type_t SISO_TYPE,
- int D, const std::vector<float> &TABLE,
- digital::trellis_metric_type_t TYPE)
- {
- return gnuradio::get_initial_sptr
- (new siso_combined_f_impl(FSM, K, S0, SK, POSTI, POSTO,
- SISO_TYPE, D, TABLE, TYPE));
- }
+namespace trellis {
+
+siso_combined_f::sptr siso_combined_f::make(const fsm& FSM,
+ int K,
+ int S0,
+ int SK,
+ bool POSTI,
+ bool POSTO,
+ siso_type_t SISO_TYPE,
+ int D,
+ const std::vector<float>& TABLE,
+ digital::trellis_metric_type_t TYPE)
+{
+ return gnuradio::get_initial_sptr(new siso_combined_f_impl(
+ FSM, K, S0, SK, POSTI, POSTO, SISO_TYPE, D, TABLE, TYPE));
+}
- void siso_combined_f_impl::recalculate()
- {
- int multiple;
- if(d_POSTI && d_POSTO)
- multiple = d_FSM.I()+d_FSM.O();
- else if(d_POSTI)
+void siso_combined_f_impl::recalculate()
+{
+ int multiple;
+ if (d_POSTI && d_POSTO)
+ multiple = d_FSM.I() + d_FSM.O();
+ else if (d_POSTI)
multiple = d_FSM.I();
- else if(d_POSTO)
+ else if (d_POSTO)
multiple = d_FSM.O();
- else
- throw std::runtime_error ("Not both POSTI and POSTO can be false.");
-
- set_output_multiple(d_K*multiple);
-
- //what is the meaning of relative rate for a block with 2 inputs?
- //set_relative_rate ((uint64_t) multiple, (uint64_t) d_FSM.I() );
- // it turns out that the above gives problems in the scheduler, so
- // let's try (assumption O>I)
- //set_relative_rate ((uint64_t) multiple, (uint64_t) d_FSM.O() );
- // I am tempted to automate like this
- if(d_FSM.I() <= d_D)
+ else
+ throw std::runtime_error("Not both POSTI and POSTO can be false.");
+
+ set_output_multiple(d_K * multiple);
+
+ // what is the meaning of relative rate for a block with 2 inputs?
+ // set_relative_rate ((uint64_t) multiple, (uint64_t) d_FSM.I() );
+ // it turns out that the above gives problems in the scheduler, so
+ // let's try (assumption O>I)
+ // set_relative_rate ((uint64_t) multiple, (uint64_t) d_FSM.O() );
+ // I am tempted to automate like this
+ if (d_FSM.I() <= d_D)
set_relative_rate((uint64_t)multiple, (uint64_t)d_D);
- else
+ else
set_relative_rate((uint64_t)multiple, (uint64_t)d_FSM.I());
- }
-
-
- siso_combined_f_impl::siso_combined_f_impl(const fsm &FSM, int K,
- int S0, int SK,
- bool POSTI, bool POSTO,
- siso_type_t SISO_TYPE,
- int D, const std::vector<float> &TABLE,
- digital::trellis_metric_type_t TYPE)
- : block("siso_combined_f",
- io_signature::make(1, -1, sizeof(float)),
- io_signature::make(1, -1, sizeof(float))),
- d_FSM(FSM), d_K(K), d_S0(S0), d_SK(SK),
- d_POSTI(POSTI), d_POSTO(POSTO),
- d_SISO_TYPE(SISO_TYPE),
- d_D(D), d_TABLE(TABLE), d_TYPE(TYPE)//,
- //d_alpha(FSM.S()*(K+1)),
- //d_beta(FSM.S()*(K+1))
- {
- recalculate();
- }
+}
- void siso_combined_f_impl::set_FSM(const fsm &FSM)
- {
- gr::thread::scoped_lock guard(d_setlock);
- d_FSM=FSM;
- recalculate();
- }
- void siso_combined_f_impl::set_K(int K)
- {
- gr::thread::scoped_lock guard(d_setlock);
- d_K=K;
- recalculate();
- }
+siso_combined_f_impl::siso_combined_f_impl(const fsm& FSM,
+ int K,
+ int S0,
+ int SK,
+ bool POSTI,
+ bool POSTO,
+ siso_type_t SISO_TYPE,
+ int D,
+ const std::vector<float>& TABLE,
+ digital::trellis_metric_type_t TYPE)
+ : block("siso_combined_f",
+ io_signature::make(1, -1, sizeof(float)),
+ io_signature::make(1, -1, sizeof(float))),
+ d_FSM(FSM),
+ d_K(K),
+ d_S0(S0),
+ d_SK(SK),
+ d_POSTI(POSTI),
+ d_POSTO(POSTO),
+ d_SISO_TYPE(SISO_TYPE),
+ d_D(D),
+ d_TABLE(TABLE),
+ d_TYPE(TYPE) //,
+ // d_alpha(FSM.S()*(K+1)),
+// d_beta(FSM.S()*(K+1))
+{
+ recalculate();
+}
- void siso_combined_f_impl::set_POSTI(bool POSTI)
- {
- gr::thread::scoped_lock guard(d_setlock);
- d_POSTI = POSTI;
- recalculate();
- }
+void siso_combined_f_impl::set_FSM(const fsm& FSM)
+{
+ gr::thread::scoped_lock guard(d_setlock);
+ d_FSM = FSM;
+ recalculate();
+}
- void siso_combined_f_impl::set_POSTO(bool POSTO)
- {
- gr::thread::scoped_lock guard(d_setlock);
- d_POSTO = POSTO;
- recalculate();
- }
+void siso_combined_f_impl::set_K(int K)
+{
+ gr::thread::scoped_lock guard(d_setlock);
+ d_K = K;
+ recalculate();
+}
- void siso_combined_f_impl::set_D(int D)
- {
- gr::thread::scoped_lock guard(d_setlock);
- d_D=D;
- recalculate();
- }
+void siso_combined_f_impl::set_POSTI(bool POSTI)
+{
+ gr::thread::scoped_lock guard(d_setlock);
+ d_POSTI = POSTI;
+ recalculate();
+}
- void siso_combined_f_impl::set_S0(int S0)
- {
- gr::thread::scoped_lock guard(d_setlock);
- d_S0 = S0;
- }
+void siso_combined_f_impl::set_POSTO(bool POSTO)
+{
+ gr::thread::scoped_lock guard(d_setlock);
+ d_POSTO = POSTO;
+ recalculate();
+}
- void siso_combined_f_impl::set_SK(int SK)
- {
- gr::thread::scoped_lock guard(d_setlock);
- d_SK = SK;
- }
+void siso_combined_f_impl::set_D(int D)
+{
+ gr::thread::scoped_lock guard(d_setlock);
+ d_D = D;
+ recalculate();
+}
- void siso_combined_f_impl::set_SISO_TYPE(trellis::siso_type_t type)
- {
- gr::thread::scoped_lock guard(d_setlock);
- d_SISO_TYPE = type;
- }
+void siso_combined_f_impl::set_S0(int S0)
+{
+ gr::thread::scoped_lock guard(d_setlock);
+ d_S0 = S0;
+}
- void siso_combined_f_impl::set_TABLE(const std::vector<float> &table)
- {
- gr::thread::scoped_lock guard(d_setlock);
- d_TABLE = table;
- }
+void siso_combined_f_impl::set_SK(int SK)
+{
+ gr::thread::scoped_lock guard(d_setlock);
+ d_SK = SK;
+}
- void siso_combined_f_impl::set_TYPE(digital::trellis_metric_type_t type)
- {
- gr::thread::scoped_lock guard(d_setlock);
- d_TYPE = type;
- }
+void siso_combined_f_impl::set_SISO_TYPE(trellis::siso_type_t type)
+{
+ gr::thread::scoped_lock guard(d_setlock);
+ d_SISO_TYPE = type;
+}
+
+void siso_combined_f_impl::set_TABLE(const std::vector<float>& table)
+{
+ gr::thread::scoped_lock guard(d_setlock);
+ d_TABLE = table;
+}
+
+void siso_combined_f_impl::set_TYPE(digital::trellis_metric_type_t type)
+{
+ gr::thread::scoped_lock guard(d_setlock);
+ d_TYPE = type;
+}
+
+siso_combined_f_impl::~siso_combined_f_impl() {}
+
+void siso_combined_f_impl::forecast(int noutput_items,
+ gr_vector_int& ninput_items_required)
+{
+ int multiple;
+ if (d_POSTI && d_POSTO)
+ multiple = d_FSM.I() + d_FSM.O();
+ else if (d_POSTI)
+ multiple = d_FSM.I();
+ else if (d_POSTO)
+ multiple = d_FSM.O();
+ else
+ throw std::runtime_error("Not both POSTI and POSTO can be false.");
+
+ // printf("forecast: Multiple = %d\n",multiple);
+ int input_required1 = d_FSM.I() * (noutput_items / multiple);
+ int input_required2 = d_D * (noutput_items / multiple);
+ // printf("forecast: Output requirements: %d\n",noutput_items);
+ // printf("forecast: Input requirements: %d %d\n",input_required1,input_required2);
+ unsigned ninputs = ninput_items_required.size();
- siso_combined_f_impl::~siso_combined_f_impl()
- {
+ for (unsigned int i = 0; i < ninputs / 2; i++) {
+ ninput_items_required[2 * i] = input_required1;
+ ninput_items_required[2 * i + 1] = input_required2;
}
+}
- void
- siso_combined_f_impl::forecast(int noutput_items,
- gr_vector_int &ninput_items_required)
- {
- int multiple;
- if(d_POSTI && d_POSTO)
- multiple = d_FSM.I()+d_FSM.O();
- else if(d_POSTI)
- multiple = d_FSM.I();
- else if(d_POSTO)
- multiple = d_FSM.O();
- else
- throw std::runtime_error ("Not both POSTI and POSTO can be false.");
-
- //printf("forecast: Multiple = %d\n",multiple);
- int input_required1 = d_FSM.I() * (noutput_items/multiple) ;
- int input_required2 = d_D * (noutput_items/multiple) ;
- //printf("forecast: Output requirements: %d\n",noutput_items);
- //printf("forecast: Input requirements: %d %d\n",input_required1,input_required2);
- unsigned ninputs = ninput_items_required.size();
-
- for(unsigned int i = 0; i < ninputs/2; i++) {
- ninput_items_required[2*i] = input_required1;
- ninput_items_required[2*i+1] = input_required2;
- }
+int siso_combined_f_impl::general_work(int noutput_items,
+ gr_vector_int& ninput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items)
+{
+ gr::thread::scoped_lock guard(d_setlock);
+ int nstreams = output_items.size();
+ // printf("general_work:Streams: %d\n",nstreams);
+
+ int multiple;
+ if (d_POSTI && d_POSTO)
+ multiple = d_FSM.I() + d_FSM.O();
+ else if (d_POSTI)
+ multiple = d_FSM.I();
+ else if (d_POSTO)
+ multiple = d_FSM.O();
+ else
+ throw std::runtime_error(
+ "siso_combined_f_impl:: Not both POSTI and POSTO can be false.");
+
+ int nblocks = noutput_items / (d_K * multiple);
+ // printf("general_work:Blocks: %d\n",nblocks);
+ // for(int i=0;i<ninput_items.size();i++)
+ // printf("general_work:Input items available: %d\n",ninput_items[i]);
+
+ float (*p2min)(float, float) = NULL;
+ if (d_SISO_TYPE == TRELLIS_MIN_SUM)
+ p2min = &min;
+ else if (d_SISO_TYPE == TRELLIS_SUM_PRODUCT)
+ p2min = &min_star;
+
+ for (int m = 0; m < nstreams; m++) {
+ const float* in1 = (const float*)input_items[2 * m];
+ const float* in2 = (const float*)input_items[2 * m + 1];
+ float* out = (float*)output_items[m];
+ for (int n = 0; n < nblocks; n++) {
+ siso_algorithm_combined(d_FSM.I(),
+ d_FSM.S(),
+ d_FSM.O(),
+ d_FSM.NS(),
+ d_FSM.OS(),
+ d_FSM.PS(),
+ d_FSM.PI(),
+ d_K,
+ d_S0,
+ d_SK,
+ d_POSTI,
+ d_POSTO,
+ p2min,
+ d_D,
+ d_TABLE,
+ d_TYPE,
+ &(in1[n * d_K * d_FSM.I()]),
+ &(in2[n * d_K * d_D]),
+ &(out[n * d_K * multiple]) //,
+ // d_alpha,d_beta
+ );
+ }
}
- int
- siso_combined_f_impl::general_work(int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
- {
- gr::thread::scoped_lock guard(d_setlock);
- int nstreams = output_items.size();
- //printf("general_work:Streams: %d\n",nstreams);
-
- int multiple;
- if(d_POSTI && d_POSTO)
- multiple = d_FSM.I()+d_FSM.O();
- else if(d_POSTI)
- multiple = d_FSM.I();
- else if(d_POSTO)
- multiple = d_FSM.O();
- else
- throw std::runtime_error("siso_combined_f_impl:: Not both POSTI and POSTO can be false.");
-
- int nblocks = noutput_items / (d_K*multiple);
- //printf("general_work:Blocks: %d\n",nblocks);
- //for(int i=0;i<ninput_items.size();i++)
- //printf("general_work:Input items available: %d\n",ninput_items[i]);
-
- float (*p2min)(float, float) = NULL;
- if(d_SISO_TYPE == TRELLIS_MIN_SUM)
- p2min = &min;
- else if(d_SISO_TYPE == TRELLIS_SUM_PRODUCT)
- p2min = &min_star;
-
- for(int m=0;m<nstreams;m++) {
- const float *in1 = (const float*)input_items[2*m];
- const float *in2 = (const float*)input_items[2*m+1];
- float *out = (float *) output_items[m];
- for(int n=0;n<nblocks;n++) {
- siso_algorithm_combined(d_FSM.I(),d_FSM.S(),d_FSM.O(),
- d_FSM.NS(),d_FSM.OS(),d_FSM.PS(),d_FSM.PI(),
- d_K,d_S0,d_SK,
- d_POSTI,d_POSTO,
- p2min,
- d_D,d_TABLE,d_TYPE,
- &(in1[n*d_K*d_FSM.I()]),&(in2[n*d_K*d_D]),
- &(out[n*d_K*multiple])//,
- //d_alpha,d_beta
- );
- }
- }
-
- for(unsigned int i = 0; i < input_items.size()/2; i++) {
- consume(2*i,d_FSM.I() * noutput_items / multiple );
- consume(2*i+1,d_D * noutput_items / multiple );
- }
-
- return noutput_items;
+ for (unsigned int i = 0; i < input_items.size() / 2; i++) {
+ consume(2 * i, d_FSM.I() * noutput_items / multiple);
+ consume(2 * i + 1, d_D * noutput_items / multiple);
}
- } /* namespace trellis */
+ return noutput_items;
+}
+
+} /* namespace trellis */
} /* namespace gr */
diff --git a/gr-trellis/lib/siso_combined_f_impl.h b/gr-trellis/lib/siso_combined_f_impl.h
index 93e9aa87d2..98b4420765 100644
--- a/gr-trellis/lib/siso_combined_f_impl.h
+++ b/gr-trellis/lib/siso_combined_f_impl.h
@@ -26,66 +26,69 @@
#include <gnuradio/trellis/siso_combined_f.h>
namespace gr {
- namespace trellis {
+namespace trellis {
- class siso_combined_f_impl : public siso_combined_f
- {
- private:
- fsm d_FSM;
- int d_K;
- int d_S0;
- int d_SK;
- bool d_POSTI;
- bool d_POSTO;
- siso_type_t d_SISO_TYPE;
- int d_D;
- std::vector<float> d_TABLE;
- digital::trellis_metric_type_t d_TYPE;
- void recalculate();
- //std::vector<float> d_alpha;
- //std::vector<float> d_beta;
+class siso_combined_f_impl : public siso_combined_f
+{
+private:
+ fsm d_FSM;
+ int d_K;
+ int d_S0;
+ int d_SK;
+ bool d_POSTI;
+ bool d_POSTO;
+ siso_type_t d_SISO_TYPE;
+ int d_D;
+ std::vector<float> d_TABLE;
+ digital::trellis_metric_type_t d_TYPE;
+ void recalculate();
+ // std::vector<float> d_alpha;
+ // std::vector<float> d_beta;
- public:
- siso_combined_f_impl(const fsm &FSM, int K,
- int S0, int SK,
- bool POSTI, bool POSTO,
- siso_type_t d_SISO_TYPE,
- int D, const std::vector<float> &TABLE,
- digital::trellis_metric_type_t TYPE);
- ~siso_combined_f_impl();
+public:
+ siso_combined_f_impl(const fsm& FSM,
+ int K,
+ int S0,
+ int SK,
+ bool POSTI,
+ bool POSTO,
+ siso_type_t d_SISO_TYPE,
+ int D,
+ const std::vector<float>& TABLE,
+ digital::trellis_metric_type_t TYPE);
+ ~siso_combined_f_impl();
- fsm FSM() const { return d_FSM; }
- int K() const { return d_K; }
- int S0() const { return d_S0; }
- int SK() const { return d_SK; }
- bool POSTI() const { return d_POSTI; }
- bool POSTO() const { return d_POSTO; }
- siso_type_t SISO_TYPE() const { return d_SISO_TYPE; }
- int D() const { return d_D; }
- std::vector<float> TABLE() const { return d_TABLE; }
- digital::trellis_metric_type_t TYPE() const { return d_TYPE; }
+ fsm FSM() const { return d_FSM; }
+ int K() const { return d_K; }
+ int S0() const { return d_S0; }
+ int SK() const { return d_SK; }
+ bool POSTI() const { return d_POSTI; }
+ bool POSTO() const { return d_POSTO; }
+ siso_type_t SISO_TYPE() const { return d_SISO_TYPE; }
+ int D() const { return d_D; }
+ std::vector<float> TABLE() const { return d_TABLE; }
+ digital::trellis_metric_type_t TYPE() const { return d_TYPE; }
- void set_FSM(const fsm &FSM);
- void set_K(int K);
- void set_S0(int S0);
- void set_SK(int SK);
- void set_POSTI(bool POSTI);
- void set_POSTO(bool POSTO);
- void set_SISO_TYPE(trellis::siso_type_t type);
- void set_D(int D);
- void set_TABLE(const std::vector<float> &table);
- void set_TYPE(digital::trellis_metric_type_t type);
+ void set_FSM(const fsm& FSM);
+ void set_K(int K);
+ void set_S0(int S0);
+ void set_SK(int SK);
+ void set_POSTI(bool POSTI);
+ void set_POSTO(bool POSTO);
+ void set_SISO_TYPE(trellis::siso_type_t type);
+ void set_D(int D);
+ void set_TABLE(const std::vector<float>& table);
+ void set_TYPE(digital::trellis_metric_type_t type);
- void forecast(int noutput_items,
- gr_vector_int &ninput_items_required);
+ void forecast(int noutput_items, gr_vector_int& ninput_items_required);
- int general_work(int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
- };
+ int general_work(int noutput_items,
+ gr_vector_int& ninput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items);
+};
- } /* namespace trellis */
+} /* namespace trellis */
} /* namespace gr */
#endif /* INCLUDED_TRELLIS_SISO_COMBINED_F_IMPL_H */
diff --git a/gr-trellis/lib/siso_f_impl.cc b/gr-trellis/lib/siso_f_impl.cc
index 14968a45a4..c4052fc28e 100644
--- a/gr-trellis/lib/siso_f_impl.cc
+++ b/gr-trellis/lib/siso_f_impl.cc
@@ -31,191 +31,194 @@
#include <iostream>
namespace gr {
- namespace trellis {
-
- siso_f::sptr
- siso_f::make(const fsm &FSM, int K,
- int S0, int SK,
- bool POSTI, bool POSTO,
- siso_type_t SISO_TYPE)
- {
- return gnuradio::get_initial_sptr
- (new siso_f_impl(FSM, K, S0, SK, POSTI, POSTO, SISO_TYPE));
- }
-
-
- void siso_f_impl::recalculate()
- {
- int multiple;
- if(d_POSTI && d_POSTO)
- multiple = d_FSM.I()+d_FSM.O();
- else if(d_POSTI)
+namespace trellis {
+
+siso_f::sptr siso_f::make(
+ const fsm& FSM, int K, int S0, int SK, bool POSTI, bool POSTO, siso_type_t SISO_TYPE)
+{
+ return gnuradio::get_initial_sptr(
+ new siso_f_impl(FSM, K, S0, SK, POSTI, POSTO, SISO_TYPE));
+}
+
+
+void siso_f_impl::recalculate()
+{
+ int multiple;
+ if (d_POSTI && d_POSTO)
+ multiple = d_FSM.I() + d_FSM.O();
+ else if (d_POSTI)
multiple = d_FSM.I();
- else if(d_POSTO)
+ else if (d_POSTO)
multiple = d_FSM.O();
- else
- throw std::runtime_error ("Not both POSTI and POSTO can be false.");
-
- set_output_multiple (d_K*multiple);
-
- //what is the meaning of relative rate for a block with 2 inputs?
- //set_relative_rate ( (uint64_t) multiple, (uint64_t) d_FSM.I() );
- // it turns out that the above gives problems in the scheduler, so
- // let's try (assumption O>I)
- //set_relative_rate ( (uint64_t) multiple, (uint64_t) d_FSM.O() );
- // I am tempted to automate like this
- if(d_FSM.I() <= d_FSM.O())
- set_relative_rate((uint64_t)multiple, (uint64_t)d_FSM.O());
- else
- set_relative_rate((uint64_t)multiple, (uint64_t)d_FSM.I());
- }
-
- siso_f_impl::siso_f_impl(const fsm &FSM, int K,
- int S0, int SK,
- bool POSTI, bool POSTO,
- siso_type_t SISO_TYPE)
- : block("siso_f",
- io_signature::make(1, -1, sizeof(float)),
- io_signature::make(1, -1, sizeof(float))),
- d_FSM(FSM), d_K(K),
- d_S0(S0),d_SK(SK),
- d_POSTI(POSTI), d_POSTO(POSTO),
- d_SISO_TYPE(SISO_TYPE)//,
- //d_alpha(FSM.S()*(K+1)),
- //d_beta(FSM.S()*(K+1))
- {
- recalculate();
- }
-
- void siso_f_impl::set_FSM(const fsm &FSM)
- {
- gr::thread::scoped_lock guard(d_setlock);
- d_FSM=FSM;
- recalculate();
- }
-
- void siso_f_impl::set_K(int K)
- {
- gr::thread::scoped_lock guard(d_setlock);
- d_K=K;
- recalculate();
- }
-
- void siso_f_impl::set_POSTI(bool POSTI)
- {
- gr::thread::scoped_lock guard(d_setlock);
- d_POSTI = POSTI;
- recalculate();
- }
-
- void siso_f_impl::set_POSTO(bool POSTO)
- {
- gr::thread::scoped_lock guard(d_setlock);
- d_POSTO = POSTO;
- recalculate();
- }
-
- void siso_f_impl::set_S0(int S0)
- {
- gr::thread::scoped_lock guard(d_setlock);
- d_S0 = S0;
- }
-
- void siso_f_impl::set_SK(int SK)
- {
- gr::thread::scoped_lock guard(d_setlock);
- d_SK = SK;
- }
-
- void siso_f_impl::set_SISO_TYPE(trellis::siso_type_t type)
- {
- gr::thread::scoped_lock guard(d_setlock);
- d_SISO_TYPE = type;
+ else
+ throw std::runtime_error("Not both POSTI and POSTO can be false.");
+
+ set_output_multiple(d_K * multiple);
+
+ // what is the meaning of relative rate for a block with 2 inputs?
+ // set_relative_rate ( (uint64_t) multiple, (uint64_t) d_FSM.I() );
+ // it turns out that the above gives problems in the scheduler, so
+ // let's try (assumption O>I)
+ // set_relative_rate ( (uint64_t) multiple, (uint64_t) d_FSM.O() );
+ // I am tempted to automate like this
+ if (d_FSM.I() <= d_FSM.O())
+ set_relative_rate((uint64_t)multiple, (uint64_t)d_FSM.O());
+ else
+ set_relative_rate((uint64_t)multiple, (uint64_t)d_FSM.I());
+}
+
+siso_f_impl::siso_f_impl(
+ const fsm& FSM, int K, int S0, int SK, bool POSTI, bool POSTO, siso_type_t SISO_TYPE)
+ : block("siso_f",
+ io_signature::make(1, -1, sizeof(float)),
+ io_signature::make(1, -1, sizeof(float))),
+ d_FSM(FSM),
+ d_K(K),
+ d_S0(S0),
+ d_SK(SK),
+ d_POSTI(POSTI),
+ d_POSTO(POSTO),
+ d_SISO_TYPE(SISO_TYPE) //,
+ // d_alpha(FSM.S()*(K+1)),
+// d_beta(FSM.S()*(K+1))
+{
+ recalculate();
+}
+
+void siso_f_impl::set_FSM(const fsm& FSM)
+{
+ gr::thread::scoped_lock guard(d_setlock);
+ d_FSM = FSM;
+ recalculate();
+}
+
+void siso_f_impl::set_K(int K)
+{
+ gr::thread::scoped_lock guard(d_setlock);
+ d_K = K;
+ recalculate();
+}
+
+void siso_f_impl::set_POSTI(bool POSTI)
+{
+ gr::thread::scoped_lock guard(d_setlock);
+ d_POSTI = POSTI;
+ recalculate();
+}
+
+void siso_f_impl::set_POSTO(bool POSTO)
+{
+ gr::thread::scoped_lock guard(d_setlock);
+ d_POSTO = POSTO;
+ recalculate();
+}
+
+void siso_f_impl::set_S0(int S0)
+{
+ gr::thread::scoped_lock guard(d_setlock);
+ d_S0 = S0;
+}
+
+void siso_f_impl::set_SK(int SK)
+{
+ gr::thread::scoped_lock guard(d_setlock);
+ d_SK = SK;
+}
+
+void siso_f_impl::set_SISO_TYPE(trellis::siso_type_t type)
+{
+ gr::thread::scoped_lock guard(d_setlock);
+ d_SISO_TYPE = type;
+}
+
+siso_f_impl::~siso_f_impl() {}
+
+void siso_f_impl::forecast(int noutput_items, gr_vector_int& ninput_items_required)
+{
+ int multiple;
+ if (d_POSTI && d_POSTO)
+ multiple = d_FSM.I() + d_FSM.O();
+ else if (d_POSTI)
+ multiple = d_FSM.I();
+ else if (d_POSTO)
+ multiple = d_FSM.O();
+ else
+ throw std::runtime_error("Not both POSTI and POSTO can be false.");
+
+ // printf("forecast: Multiple = %d\n",multiple);
+ int input_required1 = d_FSM.I() * (noutput_items / multiple);
+ int input_required2 = d_FSM.O() * (noutput_items / multiple);
+ // printf("forecast: Output requirements: %d\n",noutput_items);
+ // printf("forecast: Input requirements: %d %d\n",input_required1,input_required2);
+ unsigned ninputs = ninput_items_required.size();
+ for (unsigned int i = 0; i < ninputs / 2; i++) {
+ ninput_items_required[2 * i] = input_required1;
+ ninput_items_required[2 * i + 1] = input_required2;
}
-
- siso_f_impl::~siso_f_impl()
- {
+}
+
+int siso_f_impl::general_work(int noutput_items,
+ gr_vector_int& ninput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items)
+{
+ gr::thread::scoped_lock guard(d_setlock);
+ int nstreams = output_items.size();
+ // printf("general_work:Streams: %d\n",nstreams);
+ int multiple;
+ if (d_POSTI && d_POSTO)
+ multiple = d_FSM.I() + d_FSM.O();
+ else if (d_POSTI)
+ multiple = d_FSM.I();
+ else if (d_POSTO)
+ multiple = d_FSM.O();
+ else
+ throw std::runtime_error("siso_f_impl: Not both POSTI and POSTO can be false.\n");
+
+ int nblocks = noutput_items / (d_K * multiple);
+ // printf("general_work:Blocks: %d\n",nblocks);
+ // for(int i=0;i<ninput_items.size();i++)
+ // printf("general_work:Input items available: %d\n",ninput_items[i]);
+
+ float (*p2min)(float, float) = NULL;
+ if (d_SISO_TYPE == TRELLIS_MIN_SUM)
+ p2min = &min;
+ else if (d_SISO_TYPE == TRELLIS_SUM_PRODUCT)
+ p2min = &min_star;
+
+ for (int m = 0; m < nstreams; m++) {
+ const float* in1 = (const float*)input_items[2 * m];
+ const float* in2 = (const float*)input_items[2 * m + 1];
+ float* out = (float*)output_items[m];
+ for (int n = 0; n < nblocks; n++) {
+ siso_algorithm(d_FSM.I(),
+ d_FSM.S(),
+ d_FSM.O(),
+ d_FSM.NS(),
+ d_FSM.OS(),
+ d_FSM.PS(),
+ d_FSM.PI(),
+ d_K,
+ d_S0,
+ d_SK,
+ d_POSTI,
+ d_POSTO,
+ p2min,
+ &(in1[n * d_K * d_FSM.I()]),
+ &(in2[n * d_K * d_FSM.O()]),
+ &(out[n * d_K * multiple]) //,
+ // d_alpha,d_beta
+ );
+ }
}
- void
- siso_f_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required)
- {
- int multiple;
- if(d_POSTI && d_POSTO)
- multiple = d_FSM.I()+d_FSM.O();
- else if(d_POSTI)
- multiple = d_FSM.I();
- else if(d_POSTO)
- multiple = d_FSM.O();
- else
- throw std::runtime_error ("Not both POSTI and POSTO can be false.");
-
- //printf("forecast: Multiple = %d\n",multiple);
- int input_required1 = d_FSM.I() * (noutput_items/multiple) ;
- int input_required2 = d_FSM.O() * (noutput_items/multiple) ;
- //printf("forecast: Output requirements: %d\n",noutput_items);
- //printf("forecast: Input requirements: %d %d\n",input_required1,input_required2);
- unsigned ninputs = ninput_items_required.size();
- for(unsigned int i = 0; i < ninputs/2; i++) {
- ninput_items_required[2*i] = input_required1;
- ninput_items_required[2*i+1] = input_required2;
- }
+ for (unsigned int i = 0; i < input_items.size() / 2; i++) {
+ consume(2 * i, d_FSM.I() * noutput_items / multiple);
+ consume(2 * i + 1, d_FSM.O() * noutput_items / multiple);
}
- int
- siso_f_impl::general_work(int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
- {
- gr::thread::scoped_lock guard(d_setlock);
- int nstreams = output_items.size();
- //printf("general_work:Streams: %d\n",nstreams);
- int multiple;
- if(d_POSTI && d_POSTO)
- multiple = d_FSM.I()+d_FSM.O();
- else if(d_POSTI)
- multiple = d_FSM.I();
- else if(d_POSTO)
- multiple = d_FSM.O();
- else
- throw std::runtime_error("siso_f_impl: Not both POSTI and POSTO can be false.\n");
-
- int nblocks = noutput_items / (d_K*multiple);
- //printf("general_work:Blocks: %d\n",nblocks);
- //for(int i=0;i<ninput_items.size();i++)
- //printf("general_work:Input items available: %d\n",ninput_items[i]);
-
- float (*p2min)(float, float) = NULL;
- if(d_SISO_TYPE == TRELLIS_MIN_SUM)
- p2min = &min;
- else if(d_SISO_TYPE == TRELLIS_SUM_PRODUCT)
- p2min = &min_star;
-
- for(int m = 0; m < nstreams; m++) {
- const float *in1 = (const float*)input_items[2*m];
- const float *in2 = (const float*)input_items[2*m+1];
- float *out = (float*)output_items[m];
- for(int n = 0;n < nblocks; n++) {
- siso_algorithm(d_FSM.I(),d_FSM.S(),d_FSM.O(),
- d_FSM.NS(),d_FSM.OS(),d_FSM.PS(),d_FSM.PI(),
- d_K,d_S0,d_SK,
- d_POSTI,d_POSTO,
- p2min,
- &(in1[n*d_K*d_FSM.I()]),&(in2[n*d_K*d_FSM.O()]),
- &(out[n*d_K*multiple])//,
- //d_alpha,d_beta
- );
- }
- }
-
- for(unsigned int i = 0; i < input_items.size()/2; i++) {
- consume(2*i,d_FSM.I() * noutput_items / multiple );
- consume(2*i+1,d_FSM.O() * noutput_items / multiple );
- }
-
- return noutput_items;
- }
+ return noutput_items;
+}
- } /* namespace trellis */
+} /* namespace trellis */
} /* namespace gr */
diff --git a/gr-trellis/lib/siso_f_impl.h b/gr-trellis/lib/siso_f_impl.h
index f92616bf0a..92ac211bcf 100644
--- a/gr-trellis/lib/siso_f_impl.h
+++ b/gr-trellis/lib/siso_f_impl.h
@@ -30,55 +30,57 @@
#include <gnuradio/trellis/siso_f.h>
namespace gr {
- namespace trellis {
+namespace trellis {
- class siso_f_impl : public siso_f
- {
- private:
- fsm d_FSM;
- int d_K;
- int d_S0;
- int d_SK;
- bool d_POSTI;
- bool d_POSTO;
- siso_type_t d_SISO_TYPE;
- void recalculate();
- //std::vector<float> d_alpha;
- //std::vector<float> d_beta;
+class siso_f_impl : public siso_f
+{
+private:
+ fsm d_FSM;
+ int d_K;
+ int d_S0;
+ int d_SK;
+ bool d_POSTI;
+ bool d_POSTO;
+ siso_type_t d_SISO_TYPE;
+ void recalculate();
+ // std::vector<float> d_alpha;
+ // std::vector<float> d_beta;
- public:
- siso_f_impl(const fsm &FSM, int K,
- int S0, int SK,
- bool POSTI, bool POSTO,
- siso_type_t d_SISO_TYPE);
- ~siso_f_impl();
+public:
+ siso_f_impl(const fsm& FSM,
+ int K,
+ int S0,
+ int SK,
+ bool POSTI,
+ bool POSTO,
+ siso_type_t d_SISO_TYPE);
+ ~siso_f_impl();
- fsm FSM() const { return d_FSM; }
- int K() const { return d_K; }
- int S0() const { return d_S0; }
- int SK() const { return d_SK; }
- bool POSTI() const { return d_POSTI; }
- bool POSTO() const { return d_POSTO; }
- siso_type_t SISO_TYPE() const { return d_SISO_TYPE; }
+ fsm FSM() const { return d_FSM; }
+ int K() const { return d_K; }
+ int S0() const { return d_S0; }
+ int SK() const { return d_SK; }
+ bool POSTI() const { return d_POSTI; }
+ bool POSTO() const { return d_POSTO; }
+ siso_type_t SISO_TYPE() const { return d_SISO_TYPE; }
- void set_FSM(const fsm &FSM);
- void set_K(int K);
- void set_S0(int S0);
- void set_SK(int SK);
- void set_POSTI(bool POSTI);
- void set_POSTO(bool POSTO);
- void set_SISO_TYPE(trellis::siso_type_t type);
+ void set_FSM(const fsm& FSM);
+ void set_K(int K);
+ void set_S0(int S0);
+ void set_SK(int SK);
+ void set_POSTI(bool POSTI);
+ void set_POSTO(bool POSTO);
+ void set_SISO_TYPE(trellis::siso_type_t type);
- void forecast(int noutput_items,
- gr_vector_int &ninput_items_required);
+ void forecast(int noutput_items, gr_vector_int& ninput_items_required);
- int general_work (int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
- };
+ int general_work(int noutput_items,
+ gr_vector_int& ninput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items);
+};
- } /* namespace trellis */
+} /* namespace trellis */
} /* namespace gr */
#endif /* INCLUDED_TRELLIS_SISO_F_IMPL_H */
diff --git a/gr-trellis/lib/viterbi_combined_impl.cc b/gr-trellis/lib/viterbi_combined_impl.cc
index 675af6aea5..a956adfd28 100644
--- a/gr-trellis/lib/viterbi_combined_impl.cc
+++ b/gr-trellis/lib/viterbi_combined_impl.cc
@@ -29,148 +29,165 @@
#include <iostream>
namespace gr {
- namespace trellis {
-
- template <class IN_T,class OUT_T>
- typename viterbi_combined<IN_T,OUT_T>::sptr
- viterbi_combined<IN_T,OUT_T>::make(const fsm &FSM, int K,
- int S0, int SK, int D,
- const std::vector<IN_T> &TABLE,
- digital::trellis_metric_type_t TYPE)
- {
- return gnuradio::get_initial_sptr
- (new viterbi_combined_impl<IN_T,OUT_T>(FSM, K, S0, SK, D, TABLE,TYPE));
- }
-
- template <class IN_T,class OUT_T>
- viterbi_combined_impl<IN_T,OUT_T>::viterbi_combined_impl(const fsm &FSM, int K,
- int S0, int SK, int D,
- const std::vector<IN_T> &TABLE,
- digital::trellis_metric_type_t TYPE)
+namespace trellis {
+
+template <class IN_T, class OUT_T>
+typename viterbi_combined<IN_T, OUT_T>::sptr
+viterbi_combined<IN_T, OUT_T>::make(const fsm& FSM,
+ int K,
+ int S0,
+ int SK,
+ int D,
+ const std::vector<IN_T>& TABLE,
+ digital::trellis_metric_type_t TYPE)
+{
+ return gnuradio::get_initial_sptr(
+ new viterbi_combined_impl<IN_T, OUT_T>(FSM, K, S0, SK, D, TABLE, TYPE));
+}
+
+template <class IN_T, class OUT_T>
+viterbi_combined_impl<IN_T, OUT_T>::viterbi_combined_impl(
+ const fsm& FSM,
+ int K,
+ int S0,
+ int SK,
+ int D,
+ const std::vector<IN_T>& TABLE,
+ digital::trellis_metric_type_t TYPE)
: block("viterbi_combined<IN_T,OUT_T>",
- io_signature::make(1, -1, sizeof(IN_T)),
- io_signature::make(1, -1, sizeof(OUT_T))),
- d_FSM(FSM), d_K(K), d_S0(S0), d_SK(SK), d_D(D),
- d_TABLE(TABLE), d_TYPE(TYPE)//,
- //d_trace(FSM.S()*K)
- {
- this->set_relative_rate(1, (uint64_t)d_D);
- this->set_output_multiple(d_K);
- }
-
- template <class IN_T,class OUT_T>
- void
- viterbi_combined_impl<IN_T,OUT_T>::set_K(int K)
- {
- gr::thread::scoped_lock guard(this->d_setlock);
- d_K = K;
- this->set_output_multiple(d_K);
- }
-
- template <class IN_T,class OUT_T>
- void
- viterbi_combined_impl<IN_T,OUT_T>::set_D(int D)
- {
- gr::thread::scoped_lock guard(this->d_setlock);
- d_D = D;
- this->set_relative_rate(1, (uint64_t)d_D);
+ io_signature::make(1, -1, sizeof(IN_T)),
+ io_signature::make(1, -1, sizeof(OUT_T))),
+ d_FSM(FSM),
+ d_K(K),
+ d_S0(S0),
+ d_SK(SK),
+ d_D(D),
+ d_TABLE(TABLE),
+ d_TYPE(TYPE) //,
+ // d_trace(FSM.S()*K)
+{
+ this->set_relative_rate(1, (uint64_t)d_D);
+ this->set_output_multiple(d_K);
+}
+
+template <class IN_T, class OUT_T>
+void viterbi_combined_impl<IN_T, OUT_T>::set_K(int K)
+{
+ gr::thread::scoped_lock guard(this->d_setlock);
+ d_K = K;
+ this->set_output_multiple(d_K);
+}
+
+template <class IN_T, class OUT_T>
+void viterbi_combined_impl<IN_T, OUT_T>::set_D(int D)
+{
+ gr::thread::scoped_lock guard(this->d_setlock);
+ d_D = D;
+ this->set_relative_rate(1, (uint64_t)d_D);
+}
+
+template <class IN_T, class OUT_T>
+void viterbi_combined_impl<IN_T, OUT_T>::set_FSM(const fsm& FSM)
+{
+ gr::thread::scoped_lock guard(this->d_setlock);
+ d_FSM = FSM;
+}
+
+template <class IN_T, class OUT_T>
+void viterbi_combined_impl<IN_T, OUT_T>::set_S0(int S0)
+{
+ gr::thread::scoped_lock guard(this->d_setlock);
+ d_S0 = S0;
+}
+
+template <class IN_T, class OUT_T>
+void viterbi_combined_impl<IN_T, OUT_T>::set_SK(int SK)
+{
+ gr::thread::scoped_lock guard(this->d_setlock);
+ d_SK = SK;
+}
+
+template <class IN_T, class OUT_T>
+void viterbi_combined_impl<IN_T, OUT_T>::set_TYPE(digital::trellis_metric_type_t type)
+{
+ gr::thread::scoped_lock guard(this->d_setlock);
+ d_TYPE = type;
+}
+
+template <class IN_T, class OUT_T>
+void viterbi_combined_impl<IN_T, OUT_T>::set_TABLE(const std::vector<IN_T>& table)
+{
+ gr::thread::scoped_lock guard(this->d_setlock);
+ d_TABLE = table;
+}
+
+template <class IN_T, class OUT_T>
+viterbi_combined_impl<IN_T, OUT_T>::~viterbi_combined_impl()
+{
+}
+
+template <class IN_T, class OUT_T>
+void viterbi_combined_impl<IN_T, OUT_T>::forecast(int noutput_items,
+ gr_vector_int& ninput_items_required)
+{
+ int input_required = d_D * noutput_items;
+ unsigned ninputs = ninput_items_required.size();
+ for (unsigned int i = 0; i < ninputs; i++) {
+ ninput_items_required[i] = input_required;
}
-
- template <class IN_T,class OUT_T>
- void viterbi_combined_impl<IN_T,OUT_T>::set_FSM(const fsm &FSM)
- {
- gr::thread::scoped_lock guard(this->d_setlock);
- d_FSM = FSM;
- }
-
- template <class IN_T,class OUT_T>
- void viterbi_combined_impl<IN_T,OUT_T>::set_S0(int S0)
- {
- gr::thread::scoped_lock guard(this->d_setlock);
- d_S0 = S0;
- }
-
- template <class IN_T,class OUT_T>
- void viterbi_combined_impl<IN_T,OUT_T>::set_SK(int SK)
- {
- gr::thread::scoped_lock guard(this->d_setlock);
- d_SK = SK;
- }
-
- template <class IN_T,class OUT_T>
- void
- viterbi_combined_impl<IN_T,OUT_T>::set_TYPE(digital::trellis_metric_type_t type)
- {
- gr::thread::scoped_lock guard(this->d_setlock);
- d_TYPE = type;
- }
-
- template <class IN_T,class OUT_T>
- void
- viterbi_combined_impl<IN_T,OUT_T>::set_TABLE(const std::vector<IN_T> &table)
- {
- gr::thread::scoped_lock guard(this->d_setlock);
- d_TABLE = table;
- }
-
- template <class IN_T,class OUT_T>
- viterbi_combined_impl<IN_T,OUT_T>::~viterbi_combined_impl()
- {
- }
-
- template <class IN_T,class OUT_T>
- void
- viterbi_combined_impl<IN_T,OUT_T>::forecast(int noutput_items,
- gr_vector_int &ninput_items_required)
- {
- int input_required = d_D * noutput_items;
- unsigned ninputs = ninput_items_required.size();
- for(unsigned int i = 0; i < ninputs; i++) {
- ninput_items_required[i] = input_required;
- }
- }
-
- template <class IN_T,class OUT_T>
- int
- viterbi_combined_impl<IN_T,OUT_T>::general_work(int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
- {
- gr::thread::scoped_lock guard(this->d_setlock);
- int nstreams = input_items.size();
- int nblocks = noutput_items / d_K;
-
- for(int m=0;m<nstreams;m++) {
- const IN_T *in = (const IN_T*)input_items[m];
- OUT_T *out = (OUT_T*)output_items[m];
-
- for(int n=0;n<nblocks;n++) {
- viterbi_algorithm_combined(d_FSM.I(), d_FSM.S(), d_FSM.O(),
- d_FSM.NS(), d_FSM.OS(), d_FSM.PS(),
- d_FSM.PI(), d_K,d_S0, d_SK, d_D,
- d_TABLE, d_TYPE,
- &(in[n*d_K*d_D]), &(out[n*d_K]));
- }
- }
-
- this->consume_each(d_D * noutput_items);
- return noutput_items;
+}
+
+template <class IN_T, class OUT_T>
+int viterbi_combined_impl<IN_T, OUT_T>::general_work(
+ int noutput_items,
+ gr_vector_int& ninput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items)
+{
+ gr::thread::scoped_lock guard(this->d_setlock);
+ int nstreams = input_items.size();
+ int nblocks = noutput_items / d_K;
+
+ for (int m = 0; m < nstreams; m++) {
+ const IN_T* in = (const IN_T*)input_items[m];
+ OUT_T* out = (OUT_T*)output_items[m];
+
+ for (int n = 0; n < nblocks; n++) {
+ viterbi_algorithm_combined(d_FSM.I(),
+ d_FSM.S(),
+ d_FSM.O(),
+ d_FSM.NS(),
+ d_FSM.OS(),
+ d_FSM.PS(),
+ d_FSM.PI(),
+ d_K,
+ d_S0,
+ d_SK,
+ d_D,
+ d_TABLE,
+ d_TYPE,
+ &(in[n * d_K * d_D]),
+ &(out[n * d_K]));
+ }
}
- template class viterbi_combined<std::int16_t, std::uint8_t>;
- template class viterbi_combined<std::int16_t, std::int16_t>;
- template class viterbi_combined<std::int16_t, std::int32_t>;
- template class viterbi_combined<std::int32_t, std::uint8_t>;
- template class viterbi_combined<std::int32_t, std::int16_t>;
- template class viterbi_combined<std::int32_t, std::int32_t>;
- template class viterbi_combined<float, std::uint8_t>;
- template class viterbi_combined<float, std::int16_t>;
- template class viterbi_combined<float, std::int32_t>;
- template class viterbi_combined<gr_complex, std::uint8_t>;
- template class viterbi_combined<gr_complex, std::int16_t>;
- template class viterbi_combined<gr_complex, std::int32_t>;
-
-
- } /* namespace trellis */
+ this->consume_each(d_D * noutput_items);
+ return noutput_items;
+}
+
+template class viterbi_combined<std::int16_t, std::uint8_t>;
+template class viterbi_combined<std::int16_t, std::int16_t>;
+template class viterbi_combined<std::int16_t, std::int32_t>;
+template class viterbi_combined<std::int32_t, std::uint8_t>;
+template class viterbi_combined<std::int32_t, std::int16_t>;
+template class viterbi_combined<std::int32_t, std::int32_t>;
+template class viterbi_combined<float, std::uint8_t>;
+template class viterbi_combined<float, std::int16_t>;
+template class viterbi_combined<float, std::int32_t>;
+template class viterbi_combined<gr_complex, std::uint8_t>;
+template class viterbi_combined<gr_complex, std::int16_t>;
+template class viterbi_combined<gr_complex, std::int32_t>;
+
+
+} /* namespace trellis */
} /* namespace gr */
diff --git a/gr-trellis/lib/viterbi_combined_impl.h b/gr-trellis/lib/viterbi_combined_impl.h
index e83114673f..ea3aaeed8a 100644
--- a/gr-trellis/lib/viterbi_combined_impl.h
+++ b/gr-trellis/lib/viterbi_combined_impl.h
@@ -26,55 +26,57 @@
#include <gnuradio/trellis/viterbi_combined.h>
namespace gr {
- namespace trellis {
+namespace trellis {
- template <class IN_T,class OUT_T>
- class viterbi_combined_impl : public viterbi_combined<IN_T,OUT_T>
- {
- private:
- fsm d_FSM;
- int d_K;
- int d_S0;
- int d_SK;
- int d_D;
- std::vector<IN_T> d_TABLE;
- digital::trellis_metric_type_t d_TYPE;
- //std::vector<int> d_trace;
+template <class IN_T, class OUT_T>
+class viterbi_combined_impl : public viterbi_combined<IN_T, OUT_T>
+{
+private:
+ fsm d_FSM;
+ int d_K;
+ int d_S0;
+ int d_SK;
+ int d_D;
+ std::vector<IN_T> d_TABLE;
+ digital::trellis_metric_type_t d_TYPE;
+ // std::vector<int> d_trace;
- public:
- viterbi_combined_impl(const fsm &FSM, int K,
- int S0, int SK, int D,
- const std::vector<IN_T> &TABLE,
- digital::trellis_metric_type_t TYPE);
- ~viterbi_combined_impl();
+public:
+ viterbi_combined_impl(const fsm& FSM,
+ int K,
+ int S0,
+ int SK,
+ int D,
+ const std::vector<IN_T>& TABLE,
+ digital::trellis_metric_type_t TYPE);
+ ~viterbi_combined_impl();
- fsm FSM() const { return d_FSM; }
- int K() const { return d_K; }
- int S0() const { return d_S0; }
- int SK() const { return d_SK; }
- int D() const { return d_D; }
- std::vector<IN_T> TABLE() const { return d_TABLE; }
- digital::trellis_metric_type_t TYPE() const { return d_TYPE; }
- //std::vector<int> trace() const { return d_trace; }
+ fsm FSM() const { return d_FSM; }
+ int K() const { return d_K; }
+ int S0() const { return d_S0; }
+ int SK() const { return d_SK; }
+ int D() const { return d_D; }
+ std::vector<IN_T> TABLE() const { return d_TABLE; }
+ digital::trellis_metric_type_t TYPE() const { return d_TYPE; }
+ // std::vector<int> trace() const { return d_trace; }
- void set_FSM(const fsm &FSM);
- void set_K(int K);
- void set_S0(int S0);
- void set_SK(int SK);
- void set_D(int D);
- void set_TABLE(const std::vector<IN_T> &table);
- void set_TYPE(digital::trellis_metric_type_t type);
+ void set_FSM(const fsm& FSM);
+ void set_K(int K);
+ void set_S0(int S0);
+ void set_SK(int SK);
+ void set_D(int D);
+ void set_TABLE(const std::vector<IN_T>& table);
+ void set_TYPE(digital::trellis_metric_type_t type);
- void forecast(int noutput_items,
- gr_vector_int &ninput_items_required);
+ void forecast(int noutput_items, gr_vector_int& ninput_items_required);
- int general_work(int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
- };
+ int general_work(int noutput_items,
+ gr_vector_int& ninput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items);
+};
- } /* namespace trellis */
+} /* namespace trellis */
} /* namespace gr */
#endif /* VITERBI_COMBINED_IMPL_H */
diff --git a/gr-trellis/lib/viterbi_impl.cc b/gr-trellis/lib/viterbi_impl.cc
index 745109997f..69ac65c872 100644
--- a/gr-trellis/lib/viterbi_impl.cc
+++ b/gr-trellis/lib/viterbi_impl.cc
@@ -30,106 +30,110 @@
#include <iostream>
namespace gr {
- namespace trellis {
-
- template <class T>
- typename viterbi<T>::sptr
- viterbi<T>::make(const fsm &FSM, int K,
- int S0, int SK)
- {
- return gnuradio::get_initial_sptr
- (new viterbi_impl<T>(FSM, K, S0, SK));
- }
-
- template <class T>
- viterbi_impl<T>::viterbi_impl(const fsm &FSM, int K,
- int S0, int SK)
- : block("viterbi",
- io_signature::make(1, -1, sizeof(float)),
- io_signature::make(1, -1, sizeof(T))),
- d_FSM(FSM), d_K(K), d_S0(S0), d_SK(SK)//,
- //d_trace(FSM.S()*K)
- {
- this->set_relative_rate(1, (uint64_t)d_FSM.O());
- this->set_output_multiple(d_K);
- }
-
- template <class T>
- void viterbi_impl<T>::set_FSM(const fsm &FSM)
- {
- gr::thread::scoped_lock guard(this->d_setlock);
- d_FSM = FSM;
- this->set_relative_rate(1, (uint64_t)d_FSM.O());
- }
-
- template <class T>
- void viterbi_impl<T>::set_K(int K)
- {
- gr::thread::scoped_lock guard(this->d_setlock);
- d_K = K;
- this->set_output_multiple(d_K);
- }
-
- template <class T>
- void viterbi_impl<T>::set_S0(int S0)
- {
- gr::thread::scoped_lock guard(this->d_setlock);
- d_S0 = S0;
- }
+namespace trellis {
- template <class T>
- void viterbi_impl<T>::set_SK(int SK)
- {
- gr::thread::scoped_lock guard(this->d_setlock);
- d_SK = SK;
- }
+template <class T>
+typename viterbi<T>::sptr viterbi<T>::make(const fsm& FSM, int K, int S0, int SK)
+{
+ return gnuradio::get_initial_sptr(new viterbi_impl<T>(FSM, K, S0, SK));
+}
- template <class T>
- viterbi_impl<T>::~viterbi_impl()
- {
+template <class T>
+viterbi_impl<T>::viterbi_impl(const fsm& FSM, int K, int S0, int SK)
+ : block("viterbi",
+ io_signature::make(1, -1, sizeof(float)),
+ io_signature::make(1, -1, sizeof(T))),
+ d_FSM(FSM),
+ d_K(K),
+ d_S0(S0),
+ d_SK(SK) //,
+ // d_trace(FSM.S()*K)
+{
+ this->set_relative_rate(1, (uint64_t)d_FSM.O());
+ this->set_output_multiple(d_K);
+}
+
+template <class T>
+void viterbi_impl<T>::set_FSM(const fsm& FSM)
+{
+ gr::thread::scoped_lock guard(this->d_setlock);
+ d_FSM = FSM;
+ this->set_relative_rate(1, (uint64_t)d_FSM.O());
+}
+
+template <class T>
+void viterbi_impl<T>::set_K(int K)
+{
+ gr::thread::scoped_lock guard(this->d_setlock);
+ d_K = K;
+ this->set_output_multiple(d_K);
+}
+
+template <class T>
+void viterbi_impl<T>::set_S0(int S0)
+{
+ gr::thread::scoped_lock guard(this->d_setlock);
+ d_S0 = S0;
+}
+
+template <class T>
+void viterbi_impl<T>::set_SK(int SK)
+{
+ gr::thread::scoped_lock guard(this->d_setlock);
+ d_SK = SK;
+}
+
+template <class T>
+viterbi_impl<T>::~viterbi_impl()
+{
+}
+
+template <class T>
+void viterbi_impl<T>::forecast(int noutput_items, gr_vector_int& ninput_items_required)
+{
+ int input_required = d_FSM.O() * noutput_items;
+ unsigned ninputs = ninput_items_required.size();
+ for (unsigned int i = 0; i < ninputs; i++) {
+ ninput_items_required[i] = input_required;
}
-
- template <class T>
- void
- viterbi_impl<T>::forecast(int noutput_items,
- gr_vector_int &ninput_items_required)
- {
- int input_required = d_FSM.O() * noutput_items;
- unsigned ninputs = ninput_items_required.size();
- for(unsigned int i = 0; i < ninputs; i++) {
- ninput_items_required[i] = input_required;
- }
+}
+
+template <class T>
+int viterbi_impl<T>::general_work(int noutput_items,
+ gr_vector_int& ninput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items)
+{
+ gr::thread::scoped_lock guard(this->d_setlock);
+ int nstreams = input_items.size();
+ int nblocks = noutput_items / d_K;
+
+ for (int m = 0; m < nstreams; m++) {
+ const float* in = (const float*)input_items[m];
+ T* out = (T*)output_items[m];
+
+ for (int n = 0; n < nblocks; n++) {
+ viterbi_algorithm(d_FSM.I(),
+ d_FSM.S(),
+ d_FSM.O(),
+ d_FSM.NS(),
+ d_FSM.OS(),
+ d_FSM.PS(),
+ d_FSM.PI(),
+ d_K,
+ d_S0,
+ d_SK,
+ &(in[n * d_K * d_FSM.O()]),
+ &(out[n * d_K]));
+ }
}
- template <class T>
- int
- viterbi_impl<T>::general_work(int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
- {
- gr::thread::scoped_lock guard(this->d_setlock);
- int nstreams = input_items.size();
- int nblocks = noutput_items / d_K;
-
- for(int m = 0; m < nstreams; m++) {
- const float *in = (const float*)input_items[m];
- T *out = (T*)output_items[m];
-
- for(int n = 0; n < nblocks; n++) {
- viterbi_algorithm(d_FSM.I(), d_FSM.S(), d_FSM.O(),
- d_FSM.NS(), d_FSM.OS(), d_FSM.PS(),
- d_FSM.PI(), d_K,d_S0, d_SK,
- &(in[n*d_K*d_FSM.O()]), &(out[n*d_K]));
- }
- }
-
- this->consume_each(d_FSM.O() * noutput_items);
- return noutput_items;
- }
+ this->consume_each(d_FSM.O() * noutput_items);
+ return noutput_items;
+}
template class viterbi<std::uint8_t>;
template class viterbi<std::int16_t>;
template class viterbi<std::int32_t>;
- } /* namespace trellis */
+} /* namespace trellis */
} /* namespace gr */
diff --git a/gr-trellis/lib/viterbi_impl.h b/gr-trellis/lib/viterbi_impl.h
index c9f40a0b79..a8e2c23685 100644
--- a/gr-trellis/lib/viterbi_impl.h
+++ b/gr-trellis/lib/viterbi_impl.h
@@ -27,43 +27,41 @@
#include <gnuradio/trellis/viterbi.h>
namespace gr {
- namespace trellis {
+namespace trellis {
-template<class T>
- class viterbi_impl : public viterbi<T>
- {
- private:
- fsm d_FSM;
- int d_K;
- int d_S0;
- int d_SK;
- //std::vector<int> d_trace;
+template <class T>
+class viterbi_impl : public viterbi<T>
+{
+private:
+ fsm d_FSM;
+ int d_K;
+ int d_S0;
+ int d_SK;
+ // std::vector<int> d_trace;
- public:
- viterbi_impl(const fsm &FSM, int K,
- int S0, int SK);
- ~viterbi_impl();
+public:
+ viterbi_impl(const fsm& FSM, int K, int S0, int SK);
+ ~viterbi_impl();
- fsm FSM() const { return d_FSM; }
- int K() const { return d_K; }
- int S0() const { return d_S0; }
- int SK() const { return d_SK; }
+ fsm FSM() const { return d_FSM; }
+ int K() const { return d_K; }
+ int S0() const { return d_S0; }
+ int SK() const { return d_SK; }
- void set_FSM(const fsm &FSM);
- void set_K(int K);
- void set_S0(int S0);
- void set_SK(int SK);
- //std::vector<int> trace () const { return d_trace; }
+ void set_FSM(const fsm& FSM);
+ void set_K(int K);
+ void set_S0(int S0);
+ void set_SK(int SK);
+ // std::vector<int> trace () const { return d_trace; }
- void forecast(int noutput_items,
- gr_vector_int &ninput_items_required);
- int general_work(int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
- };
+ void forecast(int noutput_items, gr_vector_int& ninput_items_required);
+ int general_work(int noutput_items,
+ gr_vector_int& ninput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items);
+};
- } /* namespace trellis */
+} /* namespace trellis */
} /* namespace gr */
#endif /* VITERBI_IMPL_H */