<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: LMS FIR filter in Intel® Integrated Performance Primitives</title>
    <link>https://community.intel.com/t5/Intel-Integrated-Performance/LMS-FIR-filter/m-p/993612#M22630</link>
    <description>&lt;DIV&gt;Hi,&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color="#000080" size="2"&gt;&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color="#000080" size="2"&gt;On IA architecture division is replaced with multiplication by 1/nrm in floating point format. If you dont have opportunity to use floating point, you should calculate tmp/nrm in Q (Q15 or Q31) format outside the loop and then use shift inside the loop.&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color="#000080" size="2"&gt;&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;Regards,&lt;/DIV&gt;
&lt;DIV&gt; Vladimir&lt;/DIV&gt;</description>
    <pubDate>Mon, 30 May 2005 21:27:44 GMT</pubDate>
    <dc:creator>Vladimir_Dudnik</dc:creator>
    <dc:date>2005-05-30T21:27:44Z</dc:date>
    <item>
      <title>LMS FIR filter</title>
      <link>https://community.intel.com/t5/Intel-Integrated-Performance/LMS-FIR-filter/m-p/993606#M22624</link>
      <description>&lt;DIV&gt;Hello,&lt;/DIV&gt;
&lt;DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;The IPP documentation says that the function ippsFIRLMSOne_Direct adapts the taps with the classic LMS formula:&lt;/DIV&gt;
&lt;DIV&gt;w_i(n+1) = w_i(n) + 2 * mu * err * x(n - i)&lt;/DIV&gt;
&lt;DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;However, I've noticed that the adaptation process uses another parameter which decreases over time. I've done something like this:&lt;/DIV&gt;
&lt;DIV&gt;while(there is data to filter) {&lt;/DIV&gt;
&lt;DIV&gt; tap = pTaps[tapsLen - 1];&lt;/DIV&gt;
&lt;DIV&gt; ippsFIRLMSOne_DirectQ15_16s(src, refVal, &amp;amp;pDstVal,&lt;/DIV&gt;
&lt;DIV&gt; pTaps, tapsLen, muQ15, pDlyLine, &amp;amp;pDlyLineIndex);&lt;/DIV&gt;
&lt;DIV&gt; adapt = (pTaps[tapsLen - 1] - tap) / (src * (refVal - pDstVal));&lt;/DIV&gt;
&lt;DIV&gt;}&lt;/DIV&gt;
&lt;DIV&gt;&lt;/DIV&gt;(pTaps[tapsLen - 1] - tap) is 2 * mu * err * x(n)
&lt;DIV&gt;(refVal - pDstVal) is err&lt;/DIV&gt;
&lt;DIV&gt;src is x(n)&lt;/DIV&gt;
&lt;DIV&gt;so adapt should be constant and equal to 2 * mu, right?&lt;/DIV&gt;
&lt;DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;Wrong! with mu = 1, adapt starts at about 3.21 and decreases over time until it's close to zero.&lt;/DIV&gt;
&lt;DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;That doesn't sound like the "classic" LMS algorithm to me! Can someone explain what's going on? Any help would be greatly appreciated!&lt;/DIV&gt;
&lt;DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;Thanks,&lt;/DIV&gt;
&lt;DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;Oliver&lt;/DIV&gt;</description>
      <pubDate>Wed, 23 Mar 2005 21:04:14 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Integrated-Performance/LMS-FIR-filter/m-p/993606#M22624</guid>
      <dc:creator>thales_oliver</dc:creator>
      <dc:date>2005-03-23T21:04:14Z</dc:date>
    </item>
    <item>
      <title>Re: LMS FIR filter</title>
      <link>https://community.intel.com/t5/Intel-Integrated-Performance/LMS-FIR-filter/m-p/993607#M22625</link>
      <description>&lt;DIV&gt;Dear Customer,&lt;BR /&gt;Could you please submit this issue into Intel Premier Support at &lt;A href="https://premier.intel.com" target="_blank"&gt;https://premier.intel.com&lt;/A&gt; where our product support team will provide assistance?&lt;/DIV&gt;
&lt;DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;Thanks,&lt;BR /&gt;Ying S&lt;BR /&gt;Intel Corp.&lt;/DIV&gt;</description>
      <pubDate>Sat, 26 Mar 2005 04:19:43 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Integrated-Performance/LMS-FIR-filter/m-p/993607#M22625</guid>
      <dc:creator>Ying_S_Intel</dc:creator>
      <dc:date>2005-03-26T04:19:43Z</dc:date>
    </item>
    <item>
      <title>Re: LMS FIR filter</title>
      <link>https://community.intel.com/t5/Intel-Integrated-Performance/LMS-FIR-filter/m-p/993608#M22626</link>
      <description>&lt;DIV&gt;Hi, there is answer from our expert:&lt;/DIV&gt;
&lt;DIV&gt;
&lt;DIV style="BORDER-RIGHT: black 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: black 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: black 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: black 1px solid"&gt;&lt;SPAN class="text_smallest"&gt;Code:&lt;/SPAN&gt;&lt;PRE&gt;Reference is below. Probably you forgot about Q15 suffix meaning? All calculations are done in fixed point.

#define FXP (15)
#define HLF (1&amp;lt;&amp;lt;(FXP-1))

IppStatus ippsFIRLMSOne_DirectQ15_16s( Ipp16s src, Ipp16s ref,
                        Ipp16s* pDstVal, Ipp32s* pTaps, int tapsLen, int muQ15,
                                            Ipp16s* pDlyLine, int* pDlyIndex )
{
  {
    int n;
    Ipp64s tmp, nrm;

    pDlyLine[*pDlyIndex] = pDlyLine[*pDlyIndex+tapsLen] = src;

    (*pDlyIndex)++;
    if( *pDlyIndex &amp;gt;= tapsLen ) *pDlyIndex = 0;
    pDlyLine += *pDlyIndex;

    tmp = nrm = 0;
    for( n=0; n&lt;TAPSLEN&gt; * pDlyLine&lt;N&gt; );
        nrm += ( pDlyLine&lt;N&gt; * pDlyLine&lt;N&gt; );
    }

    tmp = (tmp + (HLF-1) + ((tmp&amp;gt;&amp;gt;FXP)&amp;amp;1)) &amp;gt;&amp;gt; FXP;
 
    *pDstVal = (Ipp16s)CLIP( tmp, IPP_MIN_16S, IPP_MAX_16S );

    if( 0 != nrm ) {
        tmp = muQ15 * ( ref - tmp );
        for( n=0; n&lt;TAPSLEN&gt; + tmp * pDlyLine&lt;N&gt; / nrm;
            pTaps&lt;N&gt; = (int)CLIP( tap, IPP_MIN_32S, IPP_MAX_32S );
        }
    }
    return ippStsNoErr;
  }
}
&lt;/N&gt;&lt;/N&gt;&lt;/TAPSLEN&gt;&lt;/N&gt;&lt;/N&gt;&lt;/N&gt;&lt;/TAPSLEN&gt;&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;Regards,&lt;/DIV&gt;
&lt;DIV&gt; Vladimir&lt;/DIV&gt;</description>
      <pubDate>Fri, 01 Apr 2005 05:07:28 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Integrated-Performance/LMS-FIR-filter/m-p/993608#M22626</guid>
      <dc:creator>Vladimir_Dudnik</dc:creator>
      <dc:date>2005-04-01T05:07:28Z</dc:date>
    </item>
    <item>
      <title>Re: LMS FIR filter</title>
      <link>https://community.intel.com/t5/Intel-Integrated-Performance/LMS-FIR-filter/m-p/993609#M22627</link>
      <description>&lt;DIV&gt;Thank you very much for your reply. I still have a few questions, though. I hope you or someone else can help me some more.&lt;/DIV&gt;
&lt;DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;Is this code the actual IPP implementation? Or "just" some code you wrote to emulate the IPP function?&lt;/DIV&gt;
&lt;DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;In this code, the taps are not in reversed order, right?&lt;/DIV&gt;
&lt;DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;Finally, could you explain the following line of code to me:&lt;/DIV&gt;
&lt;DIV&gt; tmp = (tmp + (HLF-1) + ((tmp&amp;gt;&amp;gt;FXP)&amp;amp;1)) &amp;gt;&amp;gt; FXP;&lt;BR /&gt;&lt;/DIV&gt;
&lt;DIV&gt;Is this a Q15 conversion? Couldn't you do something simpler, like tmp = tmp * 1&amp;lt;&amp;lt;15, followed by clipping?&lt;/DIV&gt;
&lt;DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;Thanks again for your help!&lt;/DIV&gt;
&lt;DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;Sincerely,&lt;/DIV&gt;
&lt;DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;Oliver&lt;/DIV&gt;</description>
      <pubDate>Wed, 20 Apr 2005 17:07:24 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Integrated-Performance/LMS-FIR-filter/m-p/993609#M22627</guid>
      <dc:creator>thales_oliver</dc:creator>
      <dc:date>2005-04-20T17:07:24Z</dc:date>
    </item>
    <item>
      <title>Re: LMS FIR filter</title>
      <link>https://community.intel.com/t5/Intel-Integrated-Performance/LMS-FIR-filter/m-p/993610#M22628</link>
      <description>&lt;DIV&gt;&lt;FONT color="#000080" size="2"&gt;
&lt;P&gt;It is actual general (PX) code implementation. Of course optimized version is different (with the same result). Taps should be in inverse order  this fact is mentioned in the manual and in ipps.h header file:&lt;/P&gt;
&lt;DIV style="BORDER-RIGHT: black 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: black 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: black 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: black 1px solid"&gt;&lt;SPAN class="text_smallest"&gt;Code:&lt;/SPAN&gt;&lt;PRE&gt;/* ///////////////////////////////////////////////////////////////////////////
//   Names:     ippsFIRLMSOne_Direct
//   Purpose:   direct form of a FIR LMS filter. One point operation.
//   Parameters:
//      src          source signal sample
//      refval       desired signal sample
//      pTapsInv     FIR taps coefficient values to be fitted
//      tapsLen      number of the taps
//      pDlyLine     pointer to the delay line values
//      pDlyIndex    pointer to the current index of delay line
//      mu           adaptation step
//      muQ15        adaptation step, integer version
//                   muQ15 = (int)(mu * (1&amp;lt;&amp;lt;15) + 0.5f)
//      pDstVal      where write output sample to
//   Return:
//      ippStsNullPtrErr  pointer the the data is null
//      ippStsSizeErr     the taps length is equal or less zero
//      ippStsNoErr       otherwise
//   Note: adaptation error value has been deleted from the parameter
//         list because it can be computed as (refval - dst).
//         taps array is inverted, delay line is of double size = tapsLen * 2
*/&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;The line of code youve asked about is rounding to the nearest even with applying Q15 shift. We provide rounding to the nearest even number (as it is realized in hardware for example for cvtps2dq instruction by default) for all related functions.&lt;/P&gt;
&lt;P&gt;Regards,&lt;BR /&gt; Vladimir&lt;/P&gt;&lt;/FONT&gt;&lt;/DIV&gt;</description>
      <pubDate>Wed, 20 Apr 2005 23:10:14 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Integrated-Performance/LMS-FIR-filter/m-p/993610#M22628</guid>
      <dc:creator>Vladimir_Dudnik</dc:creator>
      <dc:date>2005-04-20T23:10:14Z</dc:date>
    </item>
    <item>
      <title>Re: LMS FIR filter</title>
      <link>https://community.intel.com/t5/Intel-Integrated-Performance/LMS-FIR-filter/m-p/993611#M22629</link>
      <description>&lt;DIV&gt;&lt;/DIV&gt;&lt;PRE&gt;&lt;/PRE&gt;
&lt;DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;
&lt;DIV&gt;Hello,&lt;/DIV&gt;
&lt;DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;Thank you for your reply, it has been most helpful. However, I've noticed that in the code you provide, you do the normalization inside the loop:&lt;/DIV&gt;
&lt;DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;
&lt;DIV style="BORDER-RIGHT: black 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: black 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: black 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: black 1px solid"&gt;&lt;SPAN class="text_smallest"&gt;Code:&lt;/SPAN&gt;&lt;PRE&gt;        tmp = muQ15 * ( ref - tmp );
        for( n=0; n&lt;TAPSLEN&gt; + tmp * pDlyLine&lt;N&gt; / nrm;
            pTaps&lt;N&gt; = (int)CLIP( tap, IPP_MIN_32S, IPP_MAX_32S );
        }
&lt;/N&gt;&lt;/N&gt;&lt;/TAPSLEN&gt;&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;As I'm sure you're aware, division is the most CPU-expensive operation in this function. It would be more efficient to do something like:&lt;/DIV&gt;
&lt;DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;
&lt;DIV style="BORDER-RIGHT: black 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: black 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: black 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: black 1px solid"&gt;&lt;SPAN class="text_smallest"&gt;Code:&lt;/SPAN&gt;&lt;PRE&gt;        tmp = muQ15 * ( ref - tmp ) / nrm;
        for( n=0; n&lt;TAPSLEN&gt; + tmp * pDlyLine&lt;N&gt;;
            pTaps&lt;N&gt; = (int)CLIP( tap, IPP_MIN_32S, IPP_MAX_32S );
        }
&lt;/N&gt;&lt;/N&gt;&lt;/TAPSLEN&gt;&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;So there is only one division instead of tapsLen. But the problem with this method is that tmp gets too small (often 0) and as you can imagine, the performances aren't quite as good...&lt;/DIV&gt;
&lt;DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;So my question is: can you (or anyone) think of a way to do the division only once, without too much impact on performances? I know my question isn't directly related to the IPP, but I'm working on both Intel and non-Intel architecture, and I want my code to be as efficient as possible in both cases (specifically, with the normalization inside the loop, the code is too slow for the realtime application I'm working on).&lt;/DIV&gt;
&lt;DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;Regards,&lt;/DIV&gt;
&lt;DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;Oliver&lt;/DIV&gt;&lt;P&gt;Message Edited by thales_oliver on &lt;SPAN class="date_text"&gt;05-24-2005&lt;/SPAN&gt; &lt;SPAN class="time_text"&gt;06:39 AM&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Tue, 24 May 2005 20:36:48 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Integrated-Performance/LMS-FIR-filter/m-p/993611#M22629</guid>
      <dc:creator>thales_oliver</dc:creator>
      <dc:date>2005-05-24T20:36:48Z</dc:date>
    </item>
    <item>
      <title>Re: LMS FIR filter</title>
      <link>https://community.intel.com/t5/Intel-Integrated-Performance/LMS-FIR-filter/m-p/993612#M22630</link>
      <description>&lt;DIV&gt;Hi,&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color="#000080" size="2"&gt;&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color="#000080" size="2"&gt;On IA architecture division is replaced with multiplication by 1/nrm in floating point format. If you dont have opportunity to use floating point, you should calculate tmp/nrm in Q (Q15 or Q31) format outside the loop and then use shift inside the loop.&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color="#000080" size="2"&gt;&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;Regards,&lt;/DIV&gt;
&lt;DIV&gt; Vladimir&lt;/DIV&gt;</description>
      <pubDate>Mon, 30 May 2005 21:27:44 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Integrated-Performance/LMS-FIR-filter/m-p/993612#M22630</guid>
      <dc:creator>Vladimir_Dudnik</dc:creator>
      <dc:date>2005-05-30T21:27:44Z</dc:date>
    </item>
  </channel>
</rss>

