summaryrefslogtreecommitdiff
path: root/gr-digital
diff options
context:
space:
mode:
authorTom Rondeau <trondeau@vt.edu>2011-06-03 17:14:28 -0400
committerTom Rondeau <trondeau@vt.edu>2011-06-03 17:14:28 -0400
commit7d1d1902c54dc8feeb5742592e28403011602708 (patch)
tree1d1adf9d4e03d03546dd3855505e3f8f0ee08aab /gr-digital
parent1db1cabf26f9f543e35ae7082917fc1cdd5d6853 (diff)
digital: adding an LMS decision-directed equalizer block.
Diffstat (limited to 'gr-digital')
-rw-r--r--gr-digital/lib/Makefile.am2
-rw-r--r--gr-digital/lib/digital_lms_dd_equalizer_cc.cc99
-rw-r--r--gr-digital/lib/digital_lms_dd_equalizer_cc.h88
-rw-r--r--gr-digital/swig/Makefile.am1
-rw-r--r--gr-digital/swig/digital_lms_dd_equalizer_cc.i38
-rw-r--r--gr-digital/swig/digital_swig.i2
6 files changed, 230 insertions, 0 deletions
diff --git a/gr-digital/lib/Makefile.am b/gr-digital/lib/Makefile.am
index 6f641b7458..25a2b6f7fa 100644
--- a/gr-digital/lib/Makefile.am
+++ b/gr-digital/lib/Makefile.am
@@ -28,6 +28,7 @@ grinclude_HEADERS = \
digital_constellation.h \
digital_costas_loop_cc.h \
digital_cma_equalizer_cc.h \
+ digital_lms_dd_equalizer_cc.h \
digital_kurtotic_equalizer_cc.h
lib_LTLIBRARIES = libgnuradio-digital.la
@@ -36,6 +37,7 @@ libgnuradio_digital_la_SOURCES = \
digital_constellation.cc \
digital_costas_loop_cc.cc \
digital_cma_equalizer_cc.cc \
+ digital_lms_dd_equalizer_cc.cc \
digital_kurtotic_equalizer_cc.cc
libgnuradio_digital_la_LIBADD = \
diff --git a/gr-digital/lib/digital_lms_dd_equalizer_cc.cc b/gr-digital/lib/digital_lms_dd_equalizer_cc.cc
new file mode 100644
index 0000000000..05a51fa2c8
--- /dev/null
+++ b/gr-digital/lib/digital_lms_dd_equalizer_cc.cc
@@ -0,0 +1,99 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <digital_lms_dd_equalizer_cc.h>
+#include <gr_io_signature.h>
+#include <gr_misc.h>
+#include <iostream>
+
+digital_lms_dd_equalizer_cc_sptr
+digital_make_lms_dd_equalizer_cc (float mu, int ntaps,
+ digital_constellation_sptr cnst)
+{
+ return gnuradio::get_initial_sptr(new digital_lms_dd_equalizer_cc (mu, ntaps, cnst));
+}
+
+digital_lms_dd_equalizer_cc::digital_lms_dd_equalizer_cc (float mu, int ntaps,
+ digital_constellation_sptr cnst)
+ : gr_sync_block ("lms_dd_equalizer_cc",
+ gr_make_io_signature (1, 1, sizeof (gr_complex)),
+ gr_make_io_signature (1, 1, sizeof (gr_complex))),
+ d_taps(ntaps), d_cnst(cnst)
+{
+ set_mu(mu);
+
+ gr_zero_vector(d_taps);
+ d_taps [d_taps.size()/2] = 1;
+
+ set_history(ntaps+1);
+}
+
+float
+digital_lms_dd_equalizer_cc::get_mu()
+{
+ return d_mu;
+}
+
+void
+digital_lms_dd_equalizer_cc::set_mu(float mu)
+{
+ if(mu < 0.0f || mu > 1.0f) {
+ throw std::out_of_range("digital_lms_dd_equalizer::set_mu: Gain value must in [0, 1]");
+ }
+ else {
+ d_mu = mu;
+ }
+}
+
+int
+digital_lms_dd_equalizer_cc::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const gr_complex *in = (const gr_complex *) input_items[0];
+ gr_complex *out = (gr_complex *) output_items[0];
+
+ gr_complex acc, decision, error;
+
+ for(int i = 0; i < noutput_items; i++) {
+ acc = 0;
+
+ // Compute output
+ for (size_t j=0; j < d_taps.size(); j++)
+ acc += in[i+j] * conj(d_taps[j]);
+
+ d_cnst->map_to_points(d_cnst->decision_maker(&acc), &decision);
+ error = decision - acc;
+
+ // Update taps
+ for (size_t j=0; j < d_taps.size(); j++)
+ d_taps[j] += d_mu * conj(error) * in[i+j];
+
+ out[i] = acc; // Output decision
+ }
+
+ return noutput_items;
+}
diff --git a/gr-digital/lib/digital_lms_dd_equalizer_cc.h b/gr-digital/lib/digital_lms_dd_equalizer_cc.h
new file mode 100644
index 0000000000..f33b5fc5c3
--- /dev/null
+++ b/gr-digital/lib/digital_lms_dd_equalizer_cc.h
@@ -0,0 +1,88 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DIGITAL_LMS_DD_EQUALIZER_CC_H
+#define INCLUDED_DIGITAL_LMS_DD_EQUALIZER_CC_H
+
+#include <gr_sync_block.h>
+#include <digital_constellation.h>
+
+class digital_lms_dd_equalizer_cc;
+typedef boost::shared_ptr<digital_lms_dd_equalizer_cc> digital_lms_dd_equalizer_cc_sptr;
+
+digital_lms_dd_equalizer_cc_sptr digital_make_lms_dd_equalizer_cc (float mu, int ntaps,
+ digital_constellation_sptr cnst);
+
+/*!
+ * \brief Least-Mean-Square Decision Directed Equalizer (complex in/out)
+ * \ingroup eq_blk
+ *
+ * This block implements an LMS-based decision-directed equalizer.
+ * It uses a set of weights, w, to correlate against the inputs, u,
+ * and a decisions is then made from this output. The error
+ * in the decision is used to update teh weight vector.
+ *
+ * y[n] = conj(w[n]) u[n]
+ * d[n] = decision(y[n])
+ * e[n] = d[n] - y[n]
+ * w[n+1] = w[n] + mu u[n] conj(e[n])
+ *
+ * Where mu is a gain value (between 0 and 1 and usualy small,
+ * around 0.01 - 0.1.
+ *
+ * This block uses the digital_constellation object for making
+ * the decision from y[n]. Create the constellation object for
+ * whatever constellation is to be used and pass in the object.
+ * In Python, you can use something like:
+ * self.constellation = digital.constellation_qpsk()
+ * To create a QPSK constellation (see the digital_constellation
+ * block for more details as to what constellations are available
+ * or how to create your own). You then pass the object to this
+ * block as an sptr, or using "self.constellation.base()".
+ *
+ * The theory for this algorithm can be found in Chapter 9 of:
+ * S. Haykin, Adaptive Filter Theory, Upper Saddle River, NJ:
+ * Prentice Hall, 1996.
+ *
+ */
+class digital_lms_dd_equalizer_cc : public gr_sync_block
+{
+private:
+ friend digital_lms_dd_equalizer_cc_sptr digital_make_lms_dd_equalizer_cc (float mu, int ntaps,
+ digital_constellation_sptr cnst);
+
+ float d_mu;
+ std::vector<gr_complex> d_taps;
+ digital_constellation_sptr d_cnst;
+
+ digital_lms_dd_equalizer_cc (float mu, int ntaps,
+ digital_constellation_sptr cnst);
+
+public:
+ float get_mu();
+ void set_mu(float mu);
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gr-digital/swig/Makefile.am b/gr-digital/swig/Makefile.am
index edbda6bdaa..1e5c1de6d6 100644
--- a/gr-digital/swig/Makefile.am
+++ b/gr-digital/swig/Makefile.am
@@ -60,6 +60,7 @@ digital_swig_swiginclude_headers = \
digital_constellation.i \
digital_costas_loop_cc.i \
digital_cma_equalizer_cc.i \
+ digital_lms_dd_equalizer_cc.i \
digital_kurtotic_equalizer_cc.i
if GUILE
diff --git a/gr-digital/swig/digital_lms_dd_equalizer_cc.i b/gr-digital/swig/digital_lms_dd_equalizer_cc.i
new file mode 100644
index 0000000000..ac6accc6b7
--- /dev/null
+++ b/gr-digital/swig/digital_lms_dd_equalizer_cc.i
@@ -0,0 +1,38 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+GR_SWIG_BLOCK_MAGIC(digital,lms_dd_equalizer_cc)
+
+digital_lms_dd_equalizer_cc_sptr digital_make_lms_dd_equalizer_cc (float mu, int ntaps,
+ digital_constellation_sptr cnst);
+
+class digital_lms_dd_equalizer_cc : public gr_sync_block
+{
+public:
+ float get_mu();
+ void set_mu(float mu);
+
+private:
+ digital_lms_dd_equalizer_cc (float mu, int ntaps,
+ digital_constellation_sptr cnst);
+};
diff --git a/gr-digital/swig/digital_swig.i b/gr-digital/swig/digital_swig.i
index 73d8edd8d0..d87bdd852e 100644
--- a/gr-digital/swig/digital_swig.i
+++ b/gr-digital/swig/digital_swig.i
@@ -25,12 +25,14 @@
#include "digital_constellation.h"
#include "digital_costas_loop_cc.h"
#include "digital_cma_equalizer_cc.h"
+#include "digital_lms_dd_equalizer_cc.h"
#include "digital_kurtotic_equalizer_cc.h"
%}
%include "digital_constellation.i"
%include "digital_costas_loop_cc.i"
%include "digital_cma_equalizer_cc.i"
+%include "digital_lms_dd_equalizer_cc.i"
%include "digital_kurtotic_equalizer_cc.i"
#if SWIGGUILE