[scilab-Users] Atan function

Michaël Baudin michael.baudin at scilab.org
Wed May 18 12:04:32 CEST 2011


Hi,

I also looked in the Language Independent Arithmetic 2 "Elementary 
functions". The section 5.3.9.15 "Radian angle from Cartesian 
Co-ordinates" focuses on the atan2 function. We notice that the LIA 
standard switches the x and y arguments. Moreover, we see the line :

arcF (x, y)= downF (pi) if x = −0 and y = 0

which is exactly what is executed in the session:

-->y=+0;
-->x=-0;
-->atan(y,x)
ans =
3.1415927

Therefore, Scilab's atan is compatible with LIA 2 for this input.

Regards,

Michaël Baudin


Le 18/05/2011 10:52, Michaël Baudin a écrit :
> Hi,
>
> I do not see any bug in Scilab in this thread except, perhaps, in Matlab.
>
> At first, we can inspect the plot of the atan(y,x) function:
>
> scf();
> N=20;
> y=linspace(-4,4,N);
> x=linspace(-4,4,N);
> Z=(feval(y,x,myatan))';
> surf (y ,x ,Z);
> h = gcf ();
> cmap = graycolormap (10);
> h. color_map = cmap ;
> xtitle("atan(y,x)","y","x");
>
> There is a discontinuity on the line y=0 for x<0.
>
> The following session:
>
> -->atan(0,+0)
> ans =
> 0.
> -->atan(0,-0)
> ans =
> 3.1415927
>
> is caused by the signed zeros of the IEEE floating point arithmetic. 
> The values returned by atan are consistent with the mathematical limit 
> of the atan(0,x) function.
>
> The signed zero exists because there are two ways of representing zero 
> in a floating point format:
>
> * (-1)^0 * 0 * 2^-1022
> * (-1)^1 * 0 * 2^-1022
>
> In both case, the significant is zero and the exponent is set to the 
> minimum. But in the first case, the sign bit is set to 0, while in the 
> second it is set to 1. This topic is covered in "Floating point 
> numbers in Scilab", section 3.8 "Signed zeros":
>
> http://forge.scilab.org/index.php/p/docscifloat/downloads/
>
> These signed zeros can be consistently used to make branch cuts of 
> inverse trigonometric function consistent, as emphasized by Kahan in 
> "Branch cuts for complex elementary functions, or much ado about 
> nothing's sign bit".
>
> Exactly the same session can be reproduced in Octave, although Scilab 
> atan(y,x) is called atan2(y,x) in Octave:
>
> octave-3.2.4.exe:5> atan2([+0 -0 +0 -0],[+0 +0 -0 -0])
> ans =
>
> 0.00000 -0.00000 3.14159 -3.14159
>
> This is the same result as in Scilab:
>
> -->atan([+0 -0 +0 -0],[+0 +0 -0 -0])
> ans =
> 0. 0. 3.1415927 - 3.1415927
>
> These values are consistent with the values given in the ISO C99 
> standard (see the section F.9.1.4 "The atan2 functions"). These values 
> are also consistent with the wikipedia page:
>
> http://en.wikipedia.org/wiki/Atan2
>
> See the "Variations" section and the note on the FPATAN function.
>
> On the other hand, it seems to me that Matlab has a chosen to set zero 
> on output whenever one of the inputs x or y is zero:
>
> >> atan2([+0 -0 +0 -0],[+0 +0 -0 -0])
> ans =
> 0 0 0 0
>
> My point of view is that this is a bug, but it seems that this is on 
> purpose:
>
> http://www.mathworks.com/support/solutions/en/data/1-1CBTV/index.html?product=ML 
>
>
> Most functions consistently take into account for signed zeros in 
> Scilab. The fact that
>
> -->-0==+0
> ans =
> T
>
> is not really surprising: it is consistent with the mathematical 
> definition of the zero.
>
> The "sign" function in Scilab does not allow to distinguish these two 
> zeros:
>
> -->sign(+0)
> ans =
> 0.
> -->sign(-0)
> ans =
> 0.
>
> This is consistent with the mathematical definition of the "sign" 
> function, which is zero when x is zero.
>
> The missing function in Scilab is "signbit", which returns the sign 
> bit of the given number. A implementation is available in the floating 
> point module :
>
> http://forge.scilab.org/index.php/p/floatingpoint/source/tree/HEAD/macros/flps_signbit.sci 
>
>
> This implementation is based on the fact that the most simple way to 
> know the sign bit of a real number is to invert it, as shown in the 
> following session:
>
> -->ieee(2)
> -->1/-0
> ans =
> - Inf
> -->1/+0
> ans =
> Inf
>
> Using this function is simple with ATOMS:
>
> -->atomsInstall("floatingpoint");
> -->atomsLoad("floatingpoint");
> -->b = flps_signbit ( +0 )
> b =
> F
> -->b = flps_signbit ( -0 )
> b =
> T
>
> There are a couple of functions also missing in this category, 
> including: copysign, hypot, isfinite, pow2.
>
> Best regards,
>
> Michaël Baudin
>
> PS
> Here are a couple of plots.
>
> // 2D plots
> scf();
> subplot(2,2,1);
> z2=atan(y,-4*ones(y));
> plot(y,z2)
> xtitle("atan(y,-4)","y");
> //
> subplot(2,2,2);
> z2=atan(y,-2*ones(y));
> plot(y,z2)
> xtitle("atan(y,-2)","y");
> //
> subplot(2,2,3);
> z2=atan(y,+2*ones(y));
> plot(y,z2)
> xtitle("atan(y,2)","y");
> //
> subplot(2,2,4);
> z2=atan(y,+4*ones(y));
> plot(y,z2)
> xtitle("atan(y,4)","y");
>
>
>
> Le 11/05/2011 15:49, Samuel GOUGEON a écrit :
>> ----- Message d'origine -----
>> De : Serge Steer
>> Date : 10/05/2011 22:57:
>>> Le 10/05/2011 21:18, Samuel GOUGEON a écrit :
>>>> Look at that:
>>>>
>>>> -->atan(0, 0)
>>>> ans =
>>>> 0.00000000D+00
>>>>
>>>> -->atan(0, -0)
>>>> ans =
>>>> 3.14159265D+00
>>>>
>>>> --> -0 == 0
>>>> ans =
>>>> T
>>>>
>>>> :-(( Funny, isn't it ?!
>>> This later result is really quite funny, but the atan result is just 
>>> due to the branch cut definition for that function
>> The "special" branching cut is used only when atan() is used with a 
>> single argument.
>> It is not the case here. The help page states: The range of atan(y,x) 
>> is (-pi, pi].
>> while : atan(-0,-0)== -%pi => %T
>>
>> By the way, how is it possible to explain that the sign of -0 looks 
>> to be recorded
>> in floating point mode?? This "feature" makes Scilab somewhat 
>> unconsistent:
>> -->floor(-0)
>> ans =
>> 0.
>> // -1 would instead be expected!
>> -->sign(-0)
>> ans =
>> 0.
>> -->sign(-number_properties("tiniest"))
>> ans =
>> - 1.
>> This is why atan(y,x) should return always the same result if x and y 
>> are reals and null.
>> -->help minus // does not document this special feature, no more than
>> -->help sign
>>
>> Finally, to answer to Laurent:
>>
>> How can I guess that variable x is -0 and not 0?
>>
>> is_0minus = (x==0 & atan(0,x)==%pi);
>>
>> but we should hope that this puzzling feature will be fixed.
>>
>> Samuel
>>
>
>


-- 
Michaël Baudin
Ingénieur de développement
michael.baudin at scilab.org
-------------------------
Consortium Scilab - Digiteo
Domaine de Voluceau - Rocquencourt
B.P. 105 - 78153 Le Chesnay Cedex
Tel. : 01 39 63 56 87 - Fax : 01 39 63 55 94





More information about the users mailing list