# References using in ofdm\_equalizer\_simpledfe

**URL:** <https://www.ruby-forum.com/t/references-using-in-ofdm-equalizer-simpledfe/231887>\
**Category:** GNU Radio\
**Created:** [September 4, 2014, 3:06pm UTC](https://www.ruby-forum.com/t/references-using-in-ofdm-equalizer-simpledfe/231887 "2014-09-04T15:06:47Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![addis\_a](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/c4cdca/32.png) [@addis\_a](https://www.ruby-forum.com/u/addis_a)\
**Post date:** [September 4, 2014, 3:06pm UTC](https://www.ruby-forum.com/t/references-using-in-ofdm-equalizer-simpledfe/231887/1 "2014-09-04T15:06:47Z")

</div>

## Hi Martin, Could you tell me the reference paper that you used in ofdm\_equalizer\_simpledfe?

Thanks  
Tiankun

---

<div class="post-metadata">

**Author:** ![Tiankun\_Hu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/46a35a/32.png) [@Tiankun\_Hu](https://www.ruby-forum.com/u/Tiankun_Hu)\
**Post date:** [September 4, 2014, 3:33pm UTC](https://www.ruby-forum.com/t/references-using-in-ofdm-equalizer-simpledfe/231887/2 "2014-09-04T15:33:34Z")

</div>

On Thu, Sep 4, 2014 at 9:04 AM, Tiankun Hu [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> Hi Martin,  
> Could you tell me the reference paper that you used in  
> ofdm\_equalizer\_simpledfe?

​Hello Tiankun,

A decision feedback equalizer (DFE) works like this:

The equalizer keeps track of the channel estimate on every subcarrier​  
i.  
Call this estimate H\_i. The initial values of H\_i are provided by the  
Schmidl-Cox block, and these values are calculated from the SYNC symbols  
present in every packet.

Now, when a symbol r\_i is received on subcarrier i, it is equalized  
using  
the estimate H\_i. The equalized symbol is matched to the nearest  
constellation point. Let this symbol be R\_i. Now, the new estimate of  
H\_i  
is calculated from r\_i and R\_i. This new value of H\_i is then used for  
the  
next symbol on subcarrier i.

DFE works well when the channel changes slowly across time. However, if  
there is substantial residual CFO (carrier frequency offset) or Doppler,  
then errors are possible. Substantial channel variations across  
subcarrier  
indices is irrelevant, because DFE maintains an independent channel  
estimate H\_i for each subcarrier i.

Good luck with GNU Radio. 🙂

Best,  
Aditya

---

<div class="post-metadata">

**Author:** ![Tiankun\_Hu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/46a35a/32.png) [@Tiankun\_Hu](https://www.ruby-forum.com/u/Tiankun_Hu)\
**Post date:** [September 4, 2014, 5:00pm UTC](https://www.ruby-forum.com/t/references-using-in-ofdm-equalizer-simpledfe/231887/3 "2014-09-04T17:00:48Z")

</div>

Aditya, thanks your clarify !

在 2014年09月04日 21:31, Aditya D. 写道:

> using the estimate H\_i. The equalized symbol is matched to the nearest  
> Good luck with GNU Radio. 🙂

–  
Thanks  
Tiankun

---

<div class="post-metadata">

**Author:** ![Tiankun\_Hu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/46a35a/32.png) [@Tiankun\_Hu](https://www.ruby-forum.com/u/Tiankun_Hu)\
**Post date:** [September 4, 2014, 5:47pm UTC](https://www.ruby-forum.com/t/references-using-in-ofdm-equalizer-simpledfe/231887/4 "2014-09-04T17:47:43Z")

</div>

On Thu, Sep 4, 2014 at 11:29 AM, Tiankun Hu [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> ```
> if (!d_occupied_carriers[k]) {
> / d_pilot_symbols[d_pilot_carr_
> d_channel_state[k] = d_alpha *
> }
> 
> ```

​Hello Tiankun,

That’s a good question. The answer depends on how you want to implement  
DFE  
– and there are a couple of options.

a) Ignore pilots altogether. This is what I had described in my earlier  
email.

b) Since pilots are known symbols, if a pilot is encountered, the new  
channel estimate will always be correct. We know the received symbol r\_i  
and the expected symbol E\_i, so it is trivial to calculate the channel  
estimate H\_i. However if you ignore the pilots, then Doppler or residual  
CFO can make the decoding on a non-pilot symbol incorrect, leading to an  
incorrect estimate of H\_i propagating to all subsequent symbol indices  
on  
that subcarrier ‘i’.

Hope that helps.

Best,  
Aditya

---

<div class="post-metadata">

**Author:** ![Tiankun\_Hu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/46a35a/32.png) [@Tiankun\_Hu](https://www.ruby-forum.com/u/Tiankun_Hu)\
**Post date:** [September 4, 2014, 5:30pm UTC](https://www.ruby-forum.com/t/references-using-in-ofdm-equalizer-simpledfe/231887/5 "2014-09-04T17:30:39Z")

</div>

Hi Aditya,  
What’s use of pilot symbols in “ofdm\_equalizer\_simpledfe” ?  
I just found pilot symbols update their carrier’s channel state, but  
didn’t find what’s the use of these pilot channel state, seems them has  
no relate with data symbol, data symbol also only use themselves to  
update channel state.

```
             for (int i = 0; i < n_sym; i++) {
                 for (int k = 0; k < d_fft_len; k++) {
                     if (!d_occupied_carriers[k]) {
                         continue;
                     }
                     if (!d_pilot_carriers.empty() &&

```

d\_pilot\_carriers[d\_pilot\_carr\_set][k]) {  
======\> //didn’t find any use of these channel state in pilot  
carriers \<=========  
//seems has not relate with data symbol  
d\_channel\_state[k] = d\_alpha \* d\_channel\_state[k]  
+ (1-d\_alpha) \* frame[i_d\_fft\_len +  
k]  
/  
d\_pilot\_symbols[d\_pilot\_carr\_set][k];  
frame[i_d\_fft\_len+k] =  
d\_pilot\_symbols[d\_pilot\_carr\_set][k];  
} else {  
sym\_eq = frame[i_d\_fft\_len+k] /  
d\_channel\_state[k];  
d\_constellation-\>  
map\_to\_points(d\_constellation-\>  
decision\_maker(&sym\_eq), &sym\_est);  
d\_channel\_state[k] = d\_alpha \*  
d\_channel\_state[k]  
+ (1-d\_alpha) \* frame[i_d\_fft\_len + k]  
/ sym\_est;  
frame[i\*d\_fft\_len+k] = sym\_est;  
}  
}  
if (!d\_pilot\_carriers.empty()) {  
d\_pilot\_carr\_set = (d\_pilot\_carr\_set + 1) %  
d\_pilot\_carriers.size();  
}  
}

在 2014年09月04日 22:59, Tiankun Hu 写道:

> > ```
> > Could you tell me the reference paper that you used in
> > 
> > ```
> > 
> > present in every packet.  
> > subcarrier indices is irrelevant, because DFE maintains an independent  
> > Discuss-gnuradio mailing list  
> > [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> > [Discuss-gnuradio Info Page](https://lists.gnu.org/mailman/listinfo/discuss-gnuradio)

–  
Thanks  
Tiankun

---

<div class="post-metadata">

**Author:** ![Tiankun\_Hu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/46a35a/32.png) [@Tiankun\_Hu](https://www.ruby-forum.com/u/Tiankun_Hu)\
**Post date:** [September 5, 2014, 11:02am UTC](https://www.ruby-forum.com/t/references-using-in-ofdm-equalizer-simpledfe/231887/6 "2014-09-05T11:02:32Z")

</div>

Hi Aditya,  
Thanks your time!  
But how to use pilotes symbol’s channel state to update data symbol’s?  
“ofdm\_equalizer\_simpledfe” is so simple, so it didn’t realize that,  
right?  
Is there any example or paper can be for reference?

Thanks  
Tiankun

------------------ 原始邮件 ------------------  
发件人: “Aditya D.”;[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid);  
发送时间: 2014年9月4日(星期四) 晚上11:45  
收件人: "Tiankun Hu"[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid);  
抄送: "removed\_email\_address@domain.invalid"[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid);  
主题: Re: [Discuss-gnuradio] references using in ofdm\_equalizer\_simpledfe

On Thu, Sep 4, 2014 at 11:29 AM, Tiankun Hu [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:  
Hi Aditya,  
What’s use of pilot symbols in “ofdm\_equalizer\_simpledfe” ?  
I just found pilot symbols update their carrier’s channel state, but  
didn’t find what’s the use of these pilot channel state, seems them has  
no relate with data symbol, data symbol also only use themselves to  
update channel state.

```
            for (int i = 0; i < n_sym; i++) {
                for (int k = 0; k < d_fft_len; k++) {
                    if (!d_occupied_carriers[k]) {
                        continue;
                    }
                    if (!d_pilot_carriers.empty() && 

```

d\_pilot\_carriers[d\_pilot\_carr\_set][k]) {  
======\> //didn’t find any use of these channel state in pilot  
carriers \<=========  
//seems has not relate with data symbol  
d\_channel\_state[k] = d\_alpha \*  
d\_channel\_state[k]  
+ (1-d\_alpha) \* frame[i\*d\_fft\_len + k]  
/  
d\_pilot\_symbols[d\_pilot\_carr\_set][k];  
frame[i\*d\_fft\_len+k] =  
d\_pilot\_symbols[d\_pilot\_carr\_set][k];  
} else {  
sym\_eq = frame[i\*d\_fft\_len+k] /  
d\_channel\_state[k];  
d\_constellation-\>  
map\_to\_points(d\_constellation-\>  
decision\_maker(&sym\_eq),  
&sym\_est);  
d\_channel\_state[k] = d\_alpha \*  
d\_channel\_state[k]  
+ (1-d\_alpha) \* frame[i\*d\_fft\_len + k] /  
sym\_est;  
frame[i\*d\_fft\_len+k] = sym\_est;  
}  
}  
if (!d\_pilot\_carriers.empty()) {  
d\_pilot\_carr\_set = (d\_pilot\_carr\_set + 1) %  
d\_pilot\_carriers.size();  
}  
}

​Hello Tiankun,

That’s a good question. The answer depends on how you want to implement  
DFE – and there are a couple of options.

a) Ignore pilots altogether. This is what I had described in my earlier  
email.

b) Since pilots are known symbols, if a pilot is encountered, the new  
channel estimate will always be correct. We know the received symbol r\_i  
and the expected symbol E\_i, so it is trivial to calculate the channel  
estimate H\_i. However if you ignore the pilots, then Doppler or residual  
CFO can make the decoding on a non-pilot symbol incorrect, leading to an  
incorrect estimate of H\_i propagating to all subsequent symbol indices  
on that subcarrier ‘i’.

Hope that helps.

Best,  
Aditya

---

<div class="post-metadata">

**Author:** ![Tiankun\_Hu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/46a35a/32.png) [@Tiankun\_Hu](https://www.ruby-forum.com/u/Tiankun_Hu)\
**Post date:** [September 5, 2014, 6:26pm UTC](https://www.ruby-forum.com/t/references-using-in-ofdm-equalizer-simpledfe/231887/7 "2014-09-05T18:26:14Z")

</div>

It uses them. It will reset the channel state estimate every time it  
encounters a pilot symbol. See eg the qa codes for examples. If you want  
to  
make use of them in your modem, you need to put pilots on the same  
carriers  
as the data.

M

---

<div class="post-metadata">

**Author:** ![Tiankun\_Hu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/46a35a/32.png) [@Tiankun\_Hu](https://www.ruby-forum.com/u/Tiankun_Hu)\
**Post date:** [September 8, 2014, 8:13am UTC](https://www.ruby-forum.com/t/references-using-in-ofdm-equalizer-simpledfe/231887/8 "2014-09-08T08:13:02Z")

</div>

Aditya/Martin, thanks your help, I will read these references that you  
mentioned.

在 2014年09月06日 00:31, Aditya D. 写道:

> important to note. If I remember correctly, the reference implementation
> 
> ```
> encounters a pilot symbol. See eg the qa codes for examples. If you
> But how to use pilotes symbol's channel state to update data
> *发送时间:* 2014年9月4日(星期四) 晚上11:45
> 
> symbol
> d_channel_state[k];
> }
> 
> ignore the pilots, then Doppler or residual CFO can make the
> 
> ```
> 
> Discuss-gnuradio mailing list  
> [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> [Discuss-gnuradio Info Page](https://lists.gnu.org/mailman/listinfo/discuss-gnuradio)

–  
Thanks  
Tiankun

---

<div class="post-metadata">

**Author:** ![Tiankun\_Hu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/46a35a/32.png) [@Tiankun\_Hu](https://www.ruby-forum.com/u/Tiankun_Hu)\
**Post date:** [September 5, 2014, 6:34pm UTC](https://www.ruby-forum.com/t/references-using-in-ofdm-equalizer-simpledfe/231887/9 "2014-09-05T18:34:19Z")

</div>

Hi Tiankun,

To add on to what Martin said: In DFE, the channel state H\_I on  
subcarrier  
i is updated everytime it receives a new symbol on that subcarrier. It  
doesn’t really care of that symbol is a pilot or a data symbol. If it is  
a  
pilot, the channel estimate H\_i is trivially calculated and updated. If  
it  
is a data symbol, then the nearest constellation point is found, and is  
then used to update H\_i.

And as Martin mentioned, the pilot placement pattern in the packet is  
important to note. If I remember correctly, the reference implementation  
uses the “comb” type pilot patter. Look at Figure 1(b) in the link  
below.  
In the “comb” pilot pattern, the pilots are useless, as the subcarriers  
that contain the pilot symbols do not carry data symbols. You will need  
to  
use the “block” pilot pattern (look at Figure 1(a) below, and you will  
immediately see how DFE is applicable in this case.

> **[Review on Selected Channel Estimation Algorithms for Orthogonal Frequency...](https://scialert.net/fulltext/?doi=itj.2011.914.926&org=11)**
>
> Review on Selected Channel Estimation Algorithms for Orthogonal Frequency Division Multiplexing System

Of course, there are other types of pilot patterns, but you can ignore  
them  
for now. Good luck!

best,  
aditya

On Fri, Sep 5, 2014 at 12:15 PM, Martin B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![Tiankun\_Hu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/46a35a/32.png) [@Tiankun\_Hu](https://www.ruby-forum.com/u/Tiankun_Hu)\
**Post date:** [September 16, 2014, 5:30pm UTC](https://www.ruby-forum.com/t/references-using-in-ofdm-equalizer-simpledfe/231887/10 "2014-09-16T17:30:23Z")

</div>

On 15 Sep 2014 17:34, “Tiankun Hu” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Hi Aditya/Martin,  
> I still looked at rx/tx\_ofdm.grc.  
> Seems there an issue in “ofdm\_equalizer\_simpledfe.cc line90”.  
> If we use “ofdm\_carrier\_allocator\_cvc\_impl.cc” to allocator data and  
> pilot, the d\_occupied\_carriers[k] and  
> d\_pilot\_carriers[d\_pilot\_carr\_set][k]  
> shouldn’t equal to 1 at the same time, otherwise we will lose some data,  
> right? if so, when code arrive at line93 it will always false, so no  
> matter  
> we use block type or comb type pilot, the pilot will always useless.

Yep. Your configuration must be sensible.

> In “qa\_ofdm\_frame\_equalizer\_vcvc.test\_002\_simpledfe”, since we construct  
> tx\_data by hand, so this issue not occur, might we should remove  
> line90~92  
> or let “ofdm\_carrier\_allocator\_cvc\_impl.cc” do not allocate data to  
> carriers where both d\_occupied\_carriers[k]/d\_pilot\_carriers[k] equal to

1. 

> And second question is why “d\_occupied\_carriers” degrade to 1-d arrays  
> when init this object?

It’s flattened for easier lookup.

M

> 89 for (int k = 0; k \< d\_fft\_len; k++) {  
> 90 if (!d\_occupied\_carriers[k]) {  
> 91 continue;  
> 92 }  
> 93 if (!d\_pilot\_carriers.empty() &&  
> d\_pilot\_carriers[d\_pilot\_carr\_set][k]) {  
> 94 d\_channel\_state[k] = d\_alpha \* d\_channel\_state[k]  
> 95 + (1-d\_alpha) \* frame[i_d\_fft\_len + k] /  
> d\_pilot\_symbols[d\_pilot\_carr\_set][k];  
> 96 frame[i_d\_fft\_len+k] = d\_pilot\_symbols[d\_pilot\_carr\_set][k];  
> 97 } else {  
> 98 sym\_eq = frame[i_d\_fft\_len+k] / d\_channel\_state[k];  
> 99  
> d\_constellation-\>map\_to\_points(d\_constellation-\>decision\_maker(&sym\_eq),  
> &sym\_est);  
> 100 d\_channel\_state[k] = d\_alpha \* d\_channel\_state[k]  
> 101 + (1-d\_alpha) \* frame[i_d\_fft\_len + k]  
> / sym\_est;

---

<div class="post-metadata">

**Author:** ![Tiankun\_Hu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/46a35a/32.png) [@Tiankun\_Hu](https://www.ruby-forum.com/u/Tiankun_Hu)\
**Post date:** [September 15, 2014, 5:35pm UTC](https://www.ruby-forum.com/t/references-using-in-ofdm-equalizer-simpledfe/231887/11 "2014-09-15T17:35:55Z")

</div>

Hi Aditya/Martin,  
I still looked at rx/tx\_ofdm.grc.  
Seems there an issue in “ofdm\_equalizer\_simpledfe.cc line90”.  
If we use “ofdm\_carrier\_allocator\_cvc\_impl.cc” to allocator data and  
pilot, the d\_occupied\_carriers[k] and  
d\_pilot\_carriers[d\_pilot\_carr\_set][k] shouldn’t equal to 1 at the same  
time, otherwise we will lose some data, right? if so, when code arrive  
at line93 it will always false, so no matter we use block type or comb  
type pilot, the pilot will always useless.

In “qa\_ofdm\_frame\_equalizer\_vcvc.test\_002\_simpledfe”, since we construct  
tx\_data by hand, so this issue not occur, might we should remove  
line90~92 or let “ofdm\_carrier\_allocator\_cvc\_impl.cc” do not allocate  
data to carriers where both d\_occupied\_carriers[k]/d\_pilot\_carriers[k]  
equal to 1.

And second question is why “d\_occupied\_carriers” degrade to 1-d arrays  
when init this object?

89 for (int k = 0; k \< d\_fft\_len; k++) {  
90 if (!d\_occupied\_carriers[k]) {  
91 continue;  
92 }  
93 if (!d\_pilot\_carriers.empty() &&  
d\_pilot\_carriers[d\_pilot\_carr\_set][k]) {  
94 d\_channel\_state[k] = d\_alpha \* d\_channel\_state[k]  
95 + (1-d\_alpha) \* frame[i_d\_fft\_len + k] /  
d\_pilot\_symbols[d\_pilot\_carr\_set][k];  
96 frame[i_d\_fft\_len+k] =  
d\_pilot\_symbols[d\_pilot\_carr\_set][k];  
97 } else {  
98 sym\_eq = frame[i_d\_fft\_len+k] / d\_channel\_state[k];  
99  
d\_constellation-\>map\_to\_points(d\_constellation-\>decision\_maker(&sym\_eq),  
&sym\_est);  
100 d\_channel\_state[k] = d\_alpha \* d\_channel\_state[k]  
101 + (1-d\_alpha) \* frame[i_d\_fft\_len +  
k] / sym\_est;  
102 frame[i\*d\_fft\_len+k] = sym\_est;  
103 }  
104 }

在 2014年09月06日 00:31, Aditya D. 写道:

> important to note. If I remember correctly, the reference implementation
> 
> ```
> encounters a pilot symbol. See eg the qa codes for examples. If you
> But how to use pilotes symbol's channel state to update data
> *发送时间:* 2014年9月4日(星期四) 晚上11:45
> 
> symbol
> d_channel_state[k];
> }
> 
> ignore the pilots, then Doppler or residual CFO can make the
> 
> ```
> 
> Discuss-gnuradio mailing list  
> [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> [Discuss-gnuradio Info Page](https://lists.gnu.org/mailman/listinfo/discuss-gnuradio)

–  
Thanks  
Tiankun
