From bug-octave-request at bevo dot che dot wisc dot edu Tue Jan 22 14:59:56 2002 Subject: Re: IMPORTANT: Bug in "arg" function From: Roberto Hernandez To: Paul Kienzle CC: bug-octave at bevo dot che dot wisc dot edu Date: Tue, 22 Jan 2002 17:30:08 -0300 Paul Kienzle wrote: > After playing around in the debugger for a while, it seems that the problem > is that (-0 < 0) is not true. ***** Awesome, you figured it out! *************** > Looking at the value X(3), the debugger says that this is -0+0i. When > evaluated as a vector, the function complex::arg in the standard > C++ library returns atan2 (imag (x), real (x)), which apparently recognizes > -0 as a negative number. However, when evaluated as a scalar, Octave > automatically converts the type to real(X(3)) since the complex portion > is 0. This is then evaluated in liboctave/lo-mappers.cc using the > following: > > double > arg (double x) > { > if (x < 0.0) > return M_PI; > else > #if defined (HAVE_ISNAN) > return xisnan (x) ? octave_NaN : 0.0; > #else > return 0.0; > #endif > } > > Since x < 0.0 is false for x=-0.0, this evaluates to 0.0 rather than > M_PI. You get consistent behaviour if you replace > if (x < 0.0) > with > double y = copysign(1.0,x); > if (y < 0.0) OK, I'm a bit confused. In the example originally posted, the correct answer was the one displayed by evaluating each zero element in the vector as a scalar. In other words, in this case it's good that the function "arg" evaluates (-0.0 < 0.0) as false. Shouldn't the behavior be made consistent the other way around? I guess my confusion lies in not understanding what -0.0 is supposed to mean. The way I originally noticed the "arg" bug was while doing some FFT processing. The transform of a simple sinewave, which is supposed to have just two peaks in the phase plot looked like a sawtooth. After some digging I figured out that the FFT was returning some residual values where it was supposed to return a 0. In this case it was OK that the "arg" function returned weird phase values, because the input vector was messed up. So my next action was to write a function to round all the "small" values to zero, that is to _ABSOLUTE_ zero. Then I passed the "clean" vector to "arg" and that's when I noticed the weird behavior. In this case it shouldn't be OK that "arg" returns PI for some zero values, because they are absolute zero and not some infinitesimal value. In summary, when does the -0.0 come into play? Is it supposed to represent an infinitesimal negative value? Does (-0.0 == 0.0) evaluate as true? IMHO we should adopt some criteria as to what is the "CORRECT" thing for "arg" to do when passed a -0.0 value, whether real or imaginary. It occurs to me that if the function complex::arg is passed 0-0i it would return -PI/2, which is incorrect. Opinions? Thanks again, Roberto ------------------------------------------------------------- Octave is freely available under the terms of the GNU GPL. Octave's home on the web: http://www.octave.org How to fund new projects: http://www.octave.org/funding.html Subscription information: http://www.octave.org/archive.html -------------------------------------------------------------