ArcTan(x,y)? - Printable Version +- HP Forums (https://www.hpmuseum.org/forum) +-- Forum: HP Calculators (and very old HP Computers) (/forum-3.html) +--- Forum: HP Prime (/forum-5.html) +--- Thread: ArcTan(x,y)? (/thread-8117.html) Pages: 1 2 RE: ArcTan(x,y)? - StephenG1CMZ - 04-06-2017 03:30 PM (04-05-2017 10:41 PM)KeithB Wrote:  So if the limit of atan2(x,x) as x approaches 0 is 45, maybe that is what atan2() should return? Clearly, discontinuities near 0 cannot be avoided - I have even seen it suggested online that one could scale values and use integer arithmetic to work around. I am beginning to wonder whether returning an error might be useful. But many Atan2 implementations do return 0, so changing to return 45 instead would introduce compatibility issues. RE: ArcTan(x,y)? - Han - 04-06-2017 03:53 PM (04-06-2017 03:30 PM)StephenG1CMZ Wrote:   (04-05-2017 10:41 PM)KeithB Wrote:  So if the limit of atan2(x,x) as x approaches 0 is 45, maybe that is what atan2() should return? Clearly, discontinuities near 0 cannot be avoided - I have even seen it suggested online that one could scale values and use integer arithmetic to work around. I am beginning to wonder whether returning an error might be useful. But many Atan2 implementations do return 0, so changing to return 45 instead would introduce compatibility issues. Care should be taken when evaluating limits of 2-variable functions. See second-to-last post in: http://www.hpmuseum.org/forum/thread-7346.html atan(x/x) is 45, but atan(0/x) is 0 and atan(y/0) is 90*sign(y) (EDIT: I erroneously wrote "infinite" earlier). The limit does not exist so mathematically atan(0/0) is undefined. RE: ArcTan(x,y)? - JMB - 04-09-2017 09:50 AM (04-06-2017 03:30 PM)StephenG1CMZ Wrote:   (04-05-2017 10:41 PM)KeithB Wrote:  So if the limit of atan2(x,x) as x approaches 0 is 45, maybe that is what atan2() should return? Clearly, discontinuities near 0 cannot be avoided - I have even seen it suggested online that one could scale values and use integer arithmetic to work around. I am beginning to wonder whether returning an error might be useful. But many Atan2 implementations do return 0, so changing to return 45 instead would introduce compatibility issues. The PRIME function polar_coordinates, also works in a similar way: polar_coordinates(1,1) returns: [1.41421356237 45] polar_coordinates(0.001,0.001) returns: [1.41421356237ᴇ−3 45] polar_coordinates(0,0) returns: [0 0] RE: ArcTan(x,y)? - StephenG1CMZ - 04-09-2017 03:47 PM (04-09-2017 09:50 AM)JMB Wrote:   (04-06-2017 03:30 PM)StephenG1CMZ Wrote:  Clearly, discontinuities near 0 cannot be avoided - I have even seen it suggested online that one could scale values and use integer arithmetic to work around. I am beginning to wonder whether returning an error might be useful. But many Atan2 implementations do return 0, so changing to return 45 instead would introduce compatibility issues. The PRIME function polar_coordinates, also works in a similar way: polar_coordinates(1,1) returns: [1.41421356237 45] polar_coordinates(0.001,0.001) returns: [1.41421356237ᴇ−3 45] polar_coordinates(0,0) returns: [0 0] Interesting. Arctan returns an angle. It was only after Debugging why polar_coordinates sometimes doesnt return at all that I realised polar_coordinates returns a pair of values instead (I know, the plural "coordinates" should have been a clue) - which explains why something goes wrong if you assign it to a global rather than local variable... Code: ```  LOCAL XY:=0.0001;  LOCAL II;  LOCAL KK:=3;  PC(XX,YY)  BEGIN   PRINT("PC");   FOR II FROM 1 TO KK DO    PRINT(II);    XY:=polar_coordinates(1+2*);    A:=polar_coordinates(1+2*);//STALLS    PRINT(II);   END;   RETURN 1;  END;  EXPORT TNBUG()   BEGIN   PRINT();   PRINT(TEVAL(N:=PC(XY,XY)));   PRINT("STALLS");   END;``` I was trying to time which of the three alternatives was slower, and I'm still waiting for polar_coordinates to finish the race [Android version] RE: ArcTan(x,y)? - JMB - 04-09-2017 08:00 PM (04-09-2017 03:47 PM)StephenG1CMZ Wrote:  I was trying to time which of the three alternatives was slower, and I'm still waiting for polar_coordinates to finish the race [Android version] The function polar_coordinates returns a vector, so instead of A you have to use one of the global variables M0, M1, ..., M9 as storage. RE: ArcTan(x,y)? - StephenG1CMZ - 04-09-2017 09:54 PM I have put together a little program to illustrate the relative timings of the various methods. Some of the timings can be improved, but it gives an idea. The printouts seem to be in duration order, quickest first, although sometimes that can change on the Android (presumably because the phone is taking cycles). Code: ```  LOCAL XY:=0.0001;  LOCAL II;  LOCAL KK:=1000;    ATANS(XY)  BEGIN   RETURN ATAN(XY/XY);  END;  ATANSIMPLECALL(XY)  BEGIN   FOR II FROM 1 TO KK DO    U:=ATANS(XY);   END;   RETURN U;  END;  ATANYX(YY,XX)   BEGIN   IF YY==0 AND XX==0 THEN    RETURN 0;   END;   RETURN ARG(XX+*YY);   END;    ATANYXCALL(YY,XX)  BEGIN   FOR II FROM 1 TO KK DO    U:=ATANYX(YY,XX);   END;   RETURN U;  END; arctanxy(x, y) begin   local a;   if x == 0 then     if y == 0 then       a := 0;     else       a := sign(y) * pi / 2     end;   else     a := atan(y / x);     if x < 0 then       if y < 0 then         a := a - pi;       else         a := a + pi;       end;     end;   end;   return a; end;    ATANPCALL(XX,YY)  BEGIN   FOR II FROM 1 TO KK DO    U:=arctanxy(XX,YY);   END;   RETURN U;  END;  ARGZ(XX,YY)   BEGIN   RETURN ARG(XX+*YY);  END;    ARGZCALL(XX,YY)   BEGIN   FOR II FROM 1 TO KK DO    U:=ARGZ(XX,YY);   END;   RETURN U;  END;  PC(XX,YY)  BEGIN   RETURN polar_coordinates(XX+YY*);  END;  PCCALL(XX,YY)  BEGIN   LOCAL TMP;   FOR II FROM 1 TO KK DO    TMP:=PC(XX,YY);   END;   RETURN TMP[2];  END;  EXPORT TN()   BEGIN   LOCAL RR;   LOCAL SP:="      ";   PRINT();   PRINT(KK +" LOOPS");   //SIMPLE ATAN:QUADRANT IGNORANT   PRINT("ATAN1: "+TEVAL(RR:=ATANSIMPLECALL(XY))+SP+RR);      //CALL ARG:MAY FAIL IF YOUR COMPILERS ARG DOESNT DO 0   PRINT("ARG: "+TEVAL(RR:=ARGZCALL(XY,XY))+SP+RR);     //CALL USER ATAN (USING ARG) HANDLING 0   PRINT("ATAN(ARG):"+TEVAL(RR:=ATANYXCALL(XY,XY))+SP+RR);      //CALL USER ATAN (PORTABLE) HANDLING 0   //WORKS ON PLATFORMS WITHOUT ARG   PRINT("ATAN(Portable):"+TEVAL(RR:=ATANPCALL(XY,XY))+SP+RR);   //CALL coordinates:FAIL IF GLOBAL   PRINT("polar : "+TEVAL(RR:=PCCALL(XY,XY))+SP+RR);    END;```