This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

IQMath Log operation issue

I am using IQMath in c6472 

I am seeing an issue for numbers less than 1.0 (+ve number between 0 and 1.0). It seems to work fine for values greater than 1.0.

I am using _iq19 format.

This is what I get for 2.0 (_iq19 HEX value  0x00100000) --> computed (by IQmath library) log value is 0.69314...(_iq19 HEX value 0x00058B8F)

for 1.75 (_iq19 value 0x000E0000 ) --> 0.55961... (_iq19 value 0x0047A17)

for 3.5 (_iq19 value 0x001C0000) --> 1.25275..  (_iq19 value 0x000A05A7)

Values for < 1.0 are as follows

for 0.0003 (_iq19 HEX vale 0x0000009D) -->  computed (by IQmath library) log value is   1.6787.. (_iq19 Hex 0x000D6E11)

Expected value is -8.1117

for 0.0006 (_iq19 0x0000013A) --> computed vale is 1.71877..   ( _iq19 HEX 0x00DC00E)

expected value is -7.4186

Can someone please help if I am missing something or is it a bug?

Somnath

  • Can you tell which version of IMGLib you are using?  Can you please share your example project?

    Thanks,

    Travis

  • Travis,

    The library involved is IQMath and not IMGLib.

    I can't share the full project since that contains huge number of files and for part of our product code base.

    Here is the essence of how I tested it.

    #include <IQmath_inline_all.h>

    _iq19 gPrevVal[64];
    _iq19 gInpVal[64] ;

    for (i=0; i < 16; i++)
         {
             gPrevVal[i] = _FtoIQ19(0.0006 );
            gInpVal[i] = _FtoIQ19(0.0003 * (i+1));
          
         }
         for (i= 16; i < 32; i++)
         {
             gPrevVal[i] = _FtoIQ19(0.003);
            gInpVal[i] = _FtoIQ19(0.0015 * (i- 15));
           
         }
         for (i= 32; i < 48; i++)
         {
             gPrevVal[i] = _FtoIQ19(0.04);
            gInpVal[i] = _FtoIQ19(0.02 * (i- 31));
           
         }
         for (i= 48; i < 56; i++)
         {
             gPrevVal[i] = _FtoIQ19(0.2);
            gInpVal[i] = _FtoIQ19(0.075 * (i- 47));
         
         }
         for (i= 56; i < 64; i++)
         {
            gPrevVal[i] = _FtoIQ19(4.0);
            gInpVal[i] = _FtoIQ19(2.0 * (i- 55));
         
         }

    for(i=0; i < 64; i++)
         {
          _iq19 prevVal, inpVal;
          
                prevVal  = gPrevVal[i];
                inpVal   = gInpVal[i];

                {
                     _iq19 logR0, logR0Prev;
                                
                   logR0 = _IQ19log((_iq19)(inpVal));
                   logR0Prev = _IQ19log((_iq19)(prevVal) ) ;
                   glogR0[i] = logR0;
                   glogR0Prev[i] = logR0Prev;

                 }

    }

  • Somnath,

    I observed that 1/10 of the decimal for the log values is within the precision and results are correct for <1.0 log value. The precision degrades with the 1/100, 1/1000 place of the decimal for <1.0 values. It is attributed to the fact that the look table is being used for the taylor series approximation of upto 10 values in fixed point implementation and the tables values are stored in IQ29 bit format.

     Y' = 2y (1 + y^2(1/3 + y^2(1/7 + y^2(1/9 + ........)))

    const I32_IQ IQlogTableCoeff[]={
              0x01861861    ,    // 1/21 in Q29
              0x01AF286B    ,    // 1/19 in Q29
              0x01E1E1E1    ,    // 1/17  in Q29
              0x02222222    ,    // 1/15  in Q29
              0x02762762    ,    // 1/13  in Q29
              0x02E8BA2E    ,    // 1/11  in Q29
              0x038E38E3    ,    // 1/9  in Q29
              0x04924924    ,    // 1/7  in Q29
              0x06666666    ,    // 1/5  in Q29
              0x0AAAAAAA    ,    // 1/3  in Q29
    };

    If you are looking for a better range the lookup table values for taylor series has to be increased. But then the performance will also change because the for loop will be called more number of times with the increase in table size.

    Regards,

    Asheesh