GNU Radio 3.6.2 C++ API
digital_lms_dd_equalizer_cc.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2011 Free Software Foundation, Inc.
4  *
5  * This file is part of GNU Radio
6  *
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  *
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING. If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #ifndef INCLUDED_DIGITAL_LMS_DD_EQUALIZER_CC_H
24 #define INCLUDED_DIGITAL_LMS_DD_EQUALIZER_CC_H
25 
26 #include <digital_api.h>
27 #include <gr_adaptive_fir_ccc.h>
28 #include <digital_constellation.h>
29 
32 
34  float mu, int sps,
36 
37 /*!
38  * \brief Least-Mean-Square Decision Directed Equalizer (complex in/out)
39  * \ingroup eq_blk
40  * \ingroup digital
41  *
42  * This block implements an LMS-based decision-directed equalizer.
43  * It uses a set of weights, w, to correlate against the inputs, u,
44  * and a decisions is then made from this output. The error
45  * in the decision is used to update teh weight vector.
46  *
47  * y[n] = conj(w[n]) u[n]
48  * d[n] = decision(y[n])
49  * e[n] = d[n] - y[n]
50  * w[n+1] = w[n] + mu u[n] conj(e[n])
51  *
52  * Where mu is a gain value (between 0 and 1 and usualy small,
53  * around 0.001 - 0.01.
54  *
55  * This block uses the digital_constellation object for making
56  * the decision from y[n]. Create the constellation object for
57  * whatever constellation is to be used and pass in the object.
58  * In Python, you can use something like:
59  * self.constellation = digital.constellation_qpsk()
60  * To create a QPSK constellation (see the digital_constellation
61  * block for more details as to what constellations are available
62  * or how to create your own). You then pass the object to this
63  * block as an sptr, or using "self.constellation.base()".
64  *
65  * The theory for this algorithm can be found in Chapter 9 of:
66  * S. Haykin, Adaptive Filter Theory, Upper Saddle River, NJ:
67  * Prentice Hall, 1996.
68  *
69  */
71 {
72 private:
74  float mu, int sps,
76 
77  float d_mu;
78  std::vector<gr_complex> d_taps;
80 
81  digital_lms_dd_equalizer_cc (int num_taps,
82  float mu, int sps,
84 
85 protected:
86 
87  virtual gr_complex error(const gr_complex &out)
88  {
89  gr_complex decision, error;
90  d_cnst->map_to_points(d_cnst->decision_maker(&out), &decision);
91  error = decision - out;
92  return error;
93  }
94 
95  virtual void update_tap(gr_complex &tap, const gr_complex &in)
96  {
97  tap += d_mu*conj(in)*d_error;
98  }
99 
100 public:
101  float get_gain()
102  {
103  return d_mu;
104  }
105 
106  void set_gain(float mu)
107  {
108  if(mu < 0.0f || mu > 1.0f) {
109  throw std::out_of_range("digital_lms_dd_equalizer::set_mu: Gain value must in [0, 1]");
110  }
111  else {
112  d_mu = mu;
113  }
114  }
115 
116 };
117 
118 #endif