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.

Arcustangens2 with fastmath atan2sp

Other Parts Discussed in Thread: MATHLIB

Hi!

I'm using the atan2sp function from fastmath 2.01 atan2sp.asm.

Unfortunately this implementation has a bug. Consider the following inputs:

atan2sp(0,1)   result: 0, correct

atan2sp(0,-1) result: 0, wrong, should be -PI

A workaround is for that bug is pretty easy, but wrapping each use of a optimized asm function in some more c code should be avoided.

Since i have no knowledge in the TexasInstruments Assembly Language, i'd appreciate a fix for atan2sp.

Kind Regards

  • If you search the forum for atan2sp, you will find the thread here which addresses this issue.

    Regards,
    RandyP

  • Thank you for the link, but it doesn't work for me. i get "Group Not Found". Besides searching the forum for atan2sp yields only this thread here where we are (and one other unrelated) .

    Kind Regards

  • My sincere apologies. Here is the information I intended you to find:

    This is a special case that's documented in the user guide for the library.  From page 4-3:

    If y = 0, then the return value is 0 independent of the value of x (including 0).

    This may be arguably incorrect, but that is how the library was written.  Unfortunately, this means that you will need to add a check for cases when y = 0.

    I have no explanation why this is the case for the function or what the history is.

    Regards,
    RandyP

  • RandyP said:

    This is a special case that's documented in the user guide for the library.  From page 4-3:

    If y = 0, then the return value is 0 independent of the value of x (including 0).

    As i wrote in my initial post, this is what i already found out. What i was asking for is a fix for that wrong behaviour and not the workaround i already knew ;)

    Thank you anyways for you help!

  • Hi 1768011

    I am a little confused by the original question, what is the x and what is the y

    As the documentation says, the atan2 calculates the arc tangent of the first argument divided by the second argument, thus for atan2(0,-1) should be 0 and not -pi - Am I wrong here?

    Now, if you switch the order and look at atan2(1,0) and atan2(-1,0) this is a different story and the documentation says that it returns the right result (that is, for 1 it is +pi, for -1 it is -pi)

    Do you agree? If so, close the thread

    Best Regards

    Ran
  • I am guessing that atan2sp does what the documentation says it will do.  However what it is doing may not be what many developers want it do.  They probably want it to behave more like the common definition of atan2.  And unless they read the details in the documentation, they probably expect it behave in that manner.

    As it happens in embedded development, we often have to make trade-offs in our solutions.  That is a big reason why fastmathlib is available along side the C RTS: it gives us more options to choose solutions in the face of necessary trade-offs.  The original poster (years ago) was requesting that the atan2sp function behave more like what they expect from an atan2 function.  There is probably a reason that atan2sp deviates from the expected behavior; the reason for that deviation might have been useful for the OP to know.  As Randy P. indicates, sometimes motivations for such decisions get lost over time, or at least they get to a point where they require more energy to re-discover than anyone cares to put into the task.

  • But even if you look at the common definition of atan2, the original question was about atan2(0/-1) which is zero

    Is not it so?

    Ran
  • The standard trigonometric function arctangent takes one argument (usually y/x), and produces a value in the range (-pi/2, pi/2).  It is true that arctangent(0/-1) = arctangent(0) = 0.

    However the variant called atan2 has more information to work it.  It takes two arguments, usually y, x.  It can use the sign of the individual arguments (rather than the sign of their resulting division) to provide a richer result: value in the range (-pi, pi].

    If one looks at the result provided from a C RTS's <math.h>, you'll probably see atan2(0,-1) = pi.  Similarly if you plug them into

    We are in case two, so we have arctangent(0/-1) + pi = arctangent(0) + pi = 0 + pi = pi.

    The OP mentioned expecting a result of -pi.  -pi and pi can be interpreted as representing the same angle.  Which angle is produced is an implementation decision, perhaps guided by the desired range: [-pi, pi) or (-pi, pi] or [-pi, pi].

  • Can we close this one?

  • (Note that this thread started in 2011, so it may be that the original poster (OP) is no longer monitoring it.)

    The OP pointed out behavior in the C67x FastMath (aka C67x MATHLIB, aka C67x FastRTS) atan2sp function that was undesirable for their application.  The mentioned use-case (atan2sp(0,-1)) may fall under a documented special condition which deviates from normal atan2 behaviorBecause it is so documented, I would call the OP's request for different behavior an enhancement request rather than a bug report.  If such requests can be filed in a TI database somewhere, they may have appreciated it.

    That being said, it doesn't seem like this library is actively being developed.  An alternative might be if someone savvy could give him an efficient way to implement his desired behavior, e.g. a modification to the existing atan2sp with minimal added cycles that doesn't break the software pipeline.

    Finally, the answer may simply be "No, we won't/can't do that."  Probably not the answer that the OP was hoping for, but it would be an answer.

  • Dear All!

    Thank you for your replies!

    user347219 did a good job describing the details of the problem.

    The original intention of the post was either to get the library fixed or get a fast (assembly?) wrapper for atan2 to handle that special case.

    I don't know about the qualities of the cl6x compiler in terms of optimizations and c6000 assembly to decide if it makes sense to do some hand-written asm wrapper.

    Since this old thread came to life again, i guess there are other users that hit the non-standard behaviour of the library.

    Here's what i'm working with:

    extern "C" float  atan2sp ( float  y, float  x ) ;
    
    float atan2wrapper(float y, float x)
    {
        if((y == 0.0f) && (x < 0.0f))
        {
            return (3.1415926535f); // Work around TI's atan2 non-standard case
        }
        else
        {
            return atan2sp(y, x);
        }
    }

  • 1768011 presents a nice general purpose solution that should work fine for many cases.

    However in some situations, this solution may have a serious performance downside.

    That situation is when we want to perform the atan2 calculation in a loop.  There is a chance that the implementation as posted will not permit effective use of the software pipeline.  Consider the case when the compiler does not inline atan2sp: then looped calls to atan2wrapper will not be pipelined because they have a function call.  Consider the case when the compiler does inline atans2sp: then the if/else conditional statement becomes too complicated for branch-removal, and again atan2wrapper cannot be pipelined.

    If we always calculate the atan2, then we are more likely to be able to software pipeline because the conditional becomes simple enough for the compiler to optimize the branch away.  e.g.

    static inline
    float atan2wrapper2(float y, float x)
    {
        float val = atan2sp(y, x);  // assumes this call is inlined
        
        if(y==0 && x<0)
        {
            return 3.1415926535f;
        }
        
        return val;
    }

    By enabling the software pipeline, even at the cost of calculating atan2sp when it isn't needed, we have a chance at a decent performance gain.

    Such optimizations can be tricky, and can be use-case dependent.  For instance here, the qualities of the loop that call atan2wrapper, and the rate of occurrence of the "y==0 && x<0" condition have an impact on how this change will effect performance.

    See the Tuning Loops section 5.2 for more information on dealing with conditional logic in loops.

  • I close the thread
    Ran