ArcTan(x,y)?
04-06-2017, 03:30 PM
Post: #21
 StephenG1CMZ Senior Member Posts: 943 Joined: May 2015
RE: ArcTan(x,y)?
(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.

Stephen Lewkowicz (G1CMZ)
04-06-2017, 03:53 PM (This post was last modified: 04-06-2017 04:01 PM by Han.)
Post: #22
 Han Senior Member Posts: 1,882 Joined: Dec 2013
RE: ArcTan(x,y)?
(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:

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.

Graph 3D | QPI | SolveSys
04-09-2017, 09:50 AM
Post: #23
 JMB Member Posts: 97 Joined: Jan 2016
RE: ArcTan(x,y)?
(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]
04-09-2017, 03:47 PM (This post was last modified: 04-09-2017 05:26 PM by StephenG1CMZ.)
Post: #24
 StephenG1CMZ Senior Member Posts: 943 Joined: May 2015
RE: ArcTan(x,y)?
(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]

Stephen Lewkowicz (G1CMZ)
04-09-2017, 08:00 PM
Post: #25
 JMB Member Posts: 97 Joined: Jan 2016
RE: ArcTan(x,y)?
(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.
04-09-2017, 09:54 PM (This post was last modified: 04-09-2017 09:58 PM by StephenG1CMZ.)
Post: #26
 StephenG1CMZ Senior Member Posts: 943 Joined: May 2015
RE: ArcTan(x,y)?
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");

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;

Stephen Lewkowicz (G1CMZ)
 « Next Oldest | Next Newest »

User(s) browsing this thread: 1 Guest(s)